From 91347ae5295aba9fcd723546bf139bece6e13085 Mon Sep 17 00:00:00 2001 From: Simon Evans Date: Thu, 30 May 2024 14:05:47 +0100 Subject: [PATCH] [PLA-1778] Add singleUseCodes filter to GetClaims query. (#71) --- composer.json | 1 + lang/en/mutation.php | 1 + src/GraphQL/Queries/GetClaimsQuery.php | 11 ++++- src/Models/Laravel/BeamClaim.php | 11 ++--- .../Laravel/Traits/HasSingleUseCodeScope.php | 29 ++++++++++++ .../Feature/GraphQL/Queries/GetClaimsTest.php | 45 ++++++++++++++++++- .../GraphQL/Resources/GetClaims.graphql | 2 + 7 files changed, 91 insertions(+), 9 deletions(-) create mode 100644 src/Models/Laravel/Traits/HasSingleUseCodeScope.php diff --git a/composer.json b/composer.json index 362eac0..4aa596c 100644 --- a/composer.json +++ b/composer.json @@ -46,6 +46,7 @@ "scripts": { "build-sr25519": "cd vendor/gmajor/sr25519-bindings/go && go build -buildmode=c-shared -o sr25519.so . && mv sr25519.so ../src/Crypto/sr25519.so", "analyse": "vendor/bin/phpstan analyse", + "fix": "vendor/bin/php-cs-fixer fix", "test": "vendor/bin/phpunit", "test-coverage": "vendor/bin/phpunit --coverage-html ../../temp/coverage", "post-autoload-dump": [ diff --git a/lang/en/mutation.php b/lang/en/mutation.php index 6bea004..47fa971 100644 --- a/lang/en/mutation.php +++ b/lang/en/mutation.php @@ -3,6 +3,7 @@ return [ 'claim_beam.args.account' => 'The wallet account.', 'claim_beam.args.code' => 'The beam code.', + 'claim_beam.args.single_use_code' => 'The beam single use code.', 'claim_beam.args.cryptoSignatureType' => 'The signature crypto type. This field is optional and it will use sr25519 by default.', 'claim_beam.args.signature' => 'The signed message.', 'claim_beam.description' => 'Mutation for claiming a beam.', diff --git a/src/GraphQL/Queries/GetClaimsQuery.php b/src/GraphQL/Queries/GetClaimsQuery.php index 9260d3d..330b65a 100644 --- a/src/GraphQL/Queries/GetClaimsQuery.php +++ b/src/GraphQL/Queries/GetClaimsQuery.php @@ -54,7 +54,12 @@ public function args(): array 'codes' => [ 'type' => GraphQL::type('[String]'), 'description' => __('enjin-platform-beam::mutation.claim_beam.args.code'), - 'rules' => ['prohibits:ids'], + 'rules' => ['prohibits:ids', 'array', 'max:100'], + ], + 'singleUseCodes' => [ + 'type' => GraphQL::type('[String]'), + 'description' => __('enjin-platform-beam::mutation.claim_beam.args.single_use_code'), + 'rules' => ['prohibits:ids', 'array', 'max:100'], ], 'accounts' => [ 'type' => GraphQL::type('[String]'), @@ -80,6 +85,7 @@ public function resolve( return BeamClaim::loadSelectFields($resolveInfo, $this->name) ->when(Arr::get($args, 'ids'), fn ($query) => $query->whereIn('id', $args['ids'])) ->when(Arr::get($args, 'codes'), fn ($query) => $query->hasCode($args['codes'])) + ->when(Arr::get($args, 'singleUseCodes'), fn ($query) => $query->hasSingleUseCode($args['singleUseCodes'])) ->when(Arr::get($args, 'accounts'), fn ($query) => $query->whereIn( 'wallet_public_key', collect($args['accounts'])->map(fn ($account) => SS58Address::getPublicKey($account)) @@ -95,7 +101,8 @@ protected function rules(array $args = []): array { return [ 'ids.*' => [new MinBigInt(1), new MaxBigInt()], - 'codes.*' => ['max:1024'], + 'codes.*' => ['max:32'], + 'singleUseCodes.*' => ['max:512'], 'accounts.*' => [new ValidSubstrateAccount()], ]; } diff --git a/src/Models/Laravel/BeamClaim.php b/src/Models/Laravel/BeamClaim.php index 2751080..9edc896 100644 --- a/src/Models/Laravel/BeamClaim.php +++ b/src/Models/Laravel/BeamClaim.php @@ -5,6 +5,7 @@ use Enjin\Platform\Beam\Database\Factories\BeamClaimFactory; use Enjin\Platform\Beam\Enums\BeamFlag; use Enjin\Platform\Beam\Enums\BeamRoute; +use Enjin\Platform\Beam\Models\Laravel\Traits\HasSingleUseCodeScope; use Enjin\Platform\Beam\Services\BeamService; use Enjin\Platform\Models\BaseModel; use Enjin\Platform\Models\Laravel\Collection; @@ -25,15 +26,15 @@ class BeamClaim extends BaseModel { + use HasEagerLimit; use HasFactory; + use HasSingleUseCodeScope; + use MassPrunable; use SoftDeletes; + use Traits\EagerLoadSelectFields; use Traits\HasBeamQr; - use Traits\HasCodeScope; - use MassPrunable; use Traits\HasClaimable; - use Traits\EagerLoadSelectFields; - use HasEagerLimit; - + use Traits\HasCodeScope; /** * The attributes that aren't mass assignable. diff --git a/src/Models/Laravel/Traits/HasSingleUseCodeScope.php b/src/Models/Laravel/Traits/HasSingleUseCodeScope.php new file mode 100644 index 0000000..c1c3f8a --- /dev/null +++ b/src/Models/Laravel/Traits/HasSingleUseCodeScope.php @@ -0,0 +1,29 @@ +whereIn('code', Arr::wrap($singleUseCode)); + } catch (\Throwable $exception) { + return $query; + } + } +} diff --git a/tests/Feature/GraphQL/Queries/GetClaimsTest.php b/tests/Feature/GraphQL/Queries/GetClaimsTest.php index 9547d10..6d365da 100644 --- a/tests/Feature/GraphQL/Queries/GetClaimsTest.php +++ b/tests/Feature/GraphQL/Queries/GetClaimsTest.php @@ -51,6 +51,24 @@ public function test_it_can_get_claims_with_codes(): void $this->assertNotEmpty($response['totalCount']); } + /** + * Test get beam with codes. + */ + public function test_it_can_get_claims_with_single_use_codes(): void + { + $response = $this->graphql($this->method, ['singleUseCodes' => [$this->beam->claims[0]->singleUseCode]]); + $this->assertNotEmpty($response['totalCount']); + } + + /** + * Test get beam with codes. + */ + public function test_it_can_get_claims_with_multiple_single_use_codes(): void + { + $response = $this->graphql($this->method, ['singleUseCodes' => [$this->beam->claims[0]->singleUseCode, $this->beam->claims[1]->singleUseCode]]); + $this->assertNotEmpty($response['totalCount']); + } + /** * Test get beam with accounts. */ @@ -74,15 +92,38 @@ public function test_it_can_get_claims_with_statuses(): void */ public function test_will_fail_with_invalid_parameters(): void { + $codes = array_fill(0, 10, fake()->text(32)); + $codes[0] = fake()->text(2000); $response = $this->graphql($this->method, [ 'ids' => [1], - 'codes' => [fake()->text(2000)], + 'codes' => $codes, + 'singleUseCodes' => [fake()->text(2000)], ], true); $this->assertArraySubset([ 'ids' => ['The ids field prohibits codes from being present.'], 'codes' => ['The codes field prohibits ids from being present.'], - 'codes.0' => ['The codes.0 field must not be greater than 1024 characters.'], + 'codes.0' => ['The codes.0 field must not be greater than 32 characters.'], + 'singleUseCodes' => ['The single use codes field prohibits ids from being present.'], + 'singleUseCodes.0' => ['The singleUseCodes.0 field must not be greater than 512 characters.'], + ], $response['error']); + } + + /** + * Test get claims too many codes. + */ + public function test_will_fail_with_too_many_codes(): void + { + $codes = array_fill(0, 101, fake()->text(32)); + $singleUseCodes = array_fill(0, 101, fake()->text(384)); + $response = $this->graphql($this->method, [ + 'codes' => $codes, + 'singleUseCodes' => $singleUseCodes, + ], true); + + $this->assertArraySubset([ + 'codes' => ['The codes field must not have more than 100 items.'], + 'singleUseCodes' => ['The single use codes field must not have more than 100 items.'], ], $response['error']); } } diff --git a/tests/Feature/GraphQL/Resources/GetClaims.graphql b/tests/Feature/GraphQL/Resources/GetClaims.graphql index e2a6b45..6e55aab 100644 --- a/tests/Feature/GraphQL/Resources/GetClaims.graphql +++ b/tests/Feature/GraphQL/Resources/GetClaims.graphql @@ -1,6 +1,7 @@ query GetClaims( $ids: [BigInt] $codes: [String] + $singleUseCodes: [String] $accounts: [String] $states: [ClaimStatus] $after: String @@ -9,6 +10,7 @@ query GetClaims( GetClaims( ids: $ids codes: $codes + singleUseCodes: $singleUseCodes accounts: $accounts states: $states after: $after