From 865837eb325f6d0cea5579eb756b1e2df6a3ec0c Mon Sep 17 00:00:00 2001 From: Leonardo Custodio Date: Mon, 9 Dec 2024 19:11:24 -0300 Subject: [PATCH] Revert packs for release --- database/factories/BeamPackFactory.php | 30 -- .../2024_08_01_041409_beam_packs.php | 48 --- lang/en/input_type.php | 3 - lang/en/type.php | 3 - lang/en/union.php | 5 - lang/en/validation.php | 2 - src/BeamServiceProvider.php | 1 - src/GraphQL/Mutations/AddTokensMutation.php | 88 ++++-- src/GraphQL/Mutations/CreateBeamMutation.php | 80 ++++- .../Mutations/RemoveTokensMutation.php | 66 +--- src/GraphQL/Mutations/UpdateBeamMutation.php | 78 ++++- .../Queries/GetSingleUseCodesQuery.php | 10 +- src/GraphQL/Traits/HasTokenInputRules.php | 171 ----------- src/GraphQL/Types/BeamPackType.php | 74 ----- src/GraphQL/Types/BeamType.php | 6 - src/GraphQL/Types/Input/BeamPackInputType.php | 41 --- .../Types/Input/ClaimTokenInputType.php | 1 + .../Types/Input/RemoveBeamPackType.php | 36 --- src/GraphQL/Unions/ClaimUnion.php | 41 --- src/Jobs/ClaimBeam.php | 49 +-- src/Jobs/DispatchCreateBeamClaimsJobs.php | 15 +- src/Models/BeamPack.php | 7 - src/Models/Laravel/Beam.php | 9 - src/Models/Laravel/BeamClaim.php | 28 +- src/Models/Laravel/BeamPack.php | 136 --------- .../Laravel/Traits/HasSingleUseCodeScope.php | 29 -- src/Rules/BeamPackExistInBeam.php | 33 -- src/Rules/BeamPackMaxTokenCount.php | 13 - src/Rules/BeamPackMaxTokenSupply.php | 13 - src/Rules/MaxTokenCount.php | 13 +- src/Rules/MaxTokenSupply.php | 11 +- src/Rules/SingleUseCodeExist.php | 16 +- src/Rules/TokensExistInBeamPack.php | 62 ---- src/Services/BeamService.php | 283 ++++-------------- src/Support/ClaimProbabilities.php | 6 +- .../GraphQL/Mutations/AddTokensTest.php | 141 ++------- .../GraphQL/Mutations/ClaimBeamTest.php | 55 +--- .../GraphQL/Mutations/CreateBeamTest.php | 215 ++----------- .../Mutations/ExpireSingleUseCodesTest.php | 49 --- .../GraphQL/Mutations/RemoveTokensTest.php | 69 +---- .../GraphQL/Mutations/UpdateBeamTest.php | 162 +++------- .../GraphQL/Queries/GetSingleUseCodesTest.php | 10 - .../GraphQL/Resources/AddTokens.graphql | 8 +- .../GraphQL/Resources/CreateBeam.graphql | 4 +- .../Resources/GetSingleUseCodes.graphql | 18 +- .../GraphQL/Resources/RemoveTokens.graphql | 8 +- .../GraphQL/Resources/UpdateBeam.graphql | 2 - tests/Feature/Traits/CreateBeamData.php | 48 +-- tests/Feature/Traits/SeedBeamData.php | 32 -- 49 files changed, 426 insertions(+), 1902 deletions(-) delete mode 100644 database/factories/BeamPackFactory.php delete mode 100644 database/migrations/2024_08_01_041409_beam_packs.php delete mode 100644 lang/en/union.php delete mode 100644 src/GraphQL/Traits/HasTokenInputRules.php delete mode 100644 src/GraphQL/Types/BeamPackType.php delete mode 100644 src/GraphQL/Types/Input/BeamPackInputType.php delete mode 100644 src/GraphQL/Types/Input/RemoveBeamPackType.php delete mode 100644 src/GraphQL/Unions/ClaimUnion.php delete mode 100644 src/Models/BeamPack.php delete mode 100644 src/Models/Laravel/BeamPack.php delete mode 100644 src/Rules/BeamPackExistInBeam.php delete mode 100644 src/Rules/BeamPackMaxTokenCount.php delete mode 100644 src/Rules/BeamPackMaxTokenSupply.php delete mode 100644 src/Rules/TokensExistInBeamPack.php diff --git a/database/factories/BeamPackFactory.php b/database/factories/BeamPackFactory.php deleted file mode 100644 index 022db4b..0000000 --- a/database/factories/BeamPackFactory.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ - public function definition() - { - return [ - 'is_claimed' => fake()->boolean(), - 'code' => fake()->text(), - 'nonce' => 1, - ]; - } -} diff --git a/database/migrations/2024_08_01_041409_beam_packs.php b/database/migrations/2024_08_01_041409_beam_packs.php deleted file mode 100644 index 01b1131..0000000 --- a/database/migrations/2024_08_01_041409_beam_packs.php +++ /dev/null @@ -1,48 +0,0 @@ -boolean('is_pack')->default(false)->index(); - }); - - Schema::create('beam_packs', function (Blueprint $table) { - $table->id(); - $table->foreignId('beam_id')->constrained()->cascadeOnDelete(); - $table->string('code')->index()->nullable(); - $table->unsignedInteger('nonce')->nullable(); - $table->boolean('is_claimed')->default(false)->index(); - $table->softDeletes(); - $table->timestamps(); - }); - - Schema::table('beam_claims', function (Blueprint $table) { - $table->foreignId('beam_pack_id')->index()->nullable()->constrained()->cascadeOnDelete(); - $table->dropUnique(['idempotency_key']); - $table->index(['idempotency_key']); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('beams', function (Blueprint $table) { - $table->dropColumn('is_pack'); - }); - Schema::dropIfExists('beam_packs'); - Schema::table('beam_claims', function (Blueprint $table) { - $table->dropColumn('beam_pack_id'); - $table->unique(['idempotency_key']); - }); - } -}; diff --git a/lang/en/input_type.php b/lang/en/input_type.php index 6d059fd..9bb7602 100644 --- a/lang/en/input_type.php +++ b/lang/en/input_type.php @@ -9,7 +9,4 @@ 'claim_token.field.tokenIdDataUpload' => 'You can use this to upload a txt file that contains a list of token ID ranges, one per line.', 'claim_token.field.claimQuantity' => 'The total amount of times each token ID can be claimed. This is mainly relevant for fungible tokens, where you can specify that there are a certain amount of claims for a token ID, e.g. 10 individual claims to receive 1 token with ID 123 per claim.', 'claim_token.field.tokenQuantityPerClaim' => 'The quantity of token that can be received per claim.', - 'beam_pack.description' => 'The beam pack.', - 'beam_pack.field.id' => 'The beam pack database ID, which can be null when creating a new beam pack.', - 'beam_pack.field.beam_pack' => 'The number of times this pack can be claimed.', ]; diff --git a/lang/en/type.php b/lang/en/type.php index 7e878d0..ba90731 100644 --- a/lang/en/type.php +++ b/lang/en/type.php @@ -29,7 +29,4 @@ 'beam_scan.field.walletPublicKey' => 'The wallet public key.', 'integer_range.description' => "A string value that can be used to represent a range of integer numbers. Use a double full stop to supply a range between 2 integers. \n\nExample \[\"1\",\"2\",\"3..8\"\]", 'attribute.description' => 'An initial attribute to set for the token when minting on demand.', - 'beam_pack.description' => 'The beam pack.', - 'beam_pack.field.id' => 'The beam pack internal ID.', - 'beam_pack.field.isClaimed' => 'The flag that determines if the beam pack is claimed.', ]; diff --git a/lang/en/union.php b/lang/en/union.php deleted file mode 100644 index 099163e..0000000 --- a/lang/en/union.php +++ /dev/null @@ -1,5 +0,0 @@ - 'The beam claim can be of either type: BeamPack or BeamClaim', -]; diff --git a/lang/en/validation.php b/lang/en/validation.php index 79f010a..aafac27 100644 --- a/lang/en/validation.php +++ b/lang/en/validation.php @@ -24,6 +24,4 @@ 'tokens_doesnt_exist_in_beam' => 'The :attribute already exist in beam.', 'tokens_exist_in_beam' => 'The :attribute doesn\'t exist in beam.', 'not_owner' => 'The :attribute should not be the owner of the collection.', - 'beam_pack_exist_in_beam' => 'The :attribute doesn\'t exist in beam.', - 'tokens_exist_in_beam_pack' => 'The :attribute doesn\'t exist in beam pack.', ]; diff --git a/src/BeamServiceProvider.php b/src/BeamServiceProvider.php index f3c9c20..9adab5e 100644 --- a/src/BeamServiceProvider.php +++ b/src/BeamServiceProvider.php @@ -39,7 +39,6 @@ public function configurePackage(Package $package): void ->hasMigration('update_beams_table') ->hasMigration('add_collection_chain_id_to_beam_batches_table') ->hasMigration('add_idempotency_key_to_beam_claims_table') - ->hasMigration('beam_packs') ->hasMigration('add_source_to_beams_table') ->hasRoute('enjin-platform-beam') ->hasTranslations(); diff --git a/src/GraphQL/Mutations/AddTokensMutation.php b/src/GraphQL/Mutations/AddTokensMutation.php index 8c89dfa..3b5e3cc 100644 --- a/src/GraphQL/Mutations/AddTokensMutation.php +++ b/src/GraphQL/Mutations/AddTokensMutation.php @@ -3,21 +3,31 @@ namespace Enjin\Platform\Beam\GraphQL\Mutations; use Closure; +use Enjin\Platform\Beam\Enums\BeamType; use Enjin\Platform\Beam\GraphQL\Traits\HasBeamCommonFields; -use Enjin\Platform\Beam\GraphQL\Traits\HasTokenInputRules; use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Rules\BeamExists; +use Enjin\Platform\Beam\Rules\MaxTokenCount; +use Enjin\Platform\Beam\Rules\MaxTokenSupply; +use Enjin\Platform\Beam\Rules\TokensDoNotExistInBeam; +use Enjin\Platform\Beam\Rules\TokensDoNotExistInCollection; +use Enjin\Platform\Beam\Rules\TokensExistInCollection; +use Enjin\Platform\Beam\Rules\TokenUploadExistInCollection; +use Enjin\Platform\Beam\Rules\TokenUploadNotExistInBeam; +use Enjin\Platform\Beam\Rules\TokenUploadNotExistInCollection; +use Enjin\Platform\Beam\Rules\UniqueTokenIds; use Enjin\Platform\Beam\Services\BeamService; +use Enjin\Platform\Rules\DistinctAttributes; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rule; use Rebing\GraphQL\Support\Facades\GraphQL; class AddTokensMutation extends Mutation { use HasBeamCommonFields; - use HasTokenInputRules; /** * Get the mutation's attributes. @@ -49,13 +59,9 @@ public function args(): array 'description' => __('enjin-platform-beam::mutation.claim_beam.args.code'), ], 'tokens' => [ - 'type' => GraphQL::type('[ClaimToken!]'), + 'type' => GraphQL::type('[ClaimToken!]!'), 'description' => __('enjin-platform-beam::input_type.claim_token.description'), ], - 'packs' => [ - 'type' => GraphQL::type('[BeamPackInput!]'), - 'description' => __('enjin-platform-beam::input_type.beam_pack.description'), - ], ]; } @@ -70,13 +76,7 @@ public function resolve( Closure $getSelectFields, BeamService $beam ) { - return DB::transaction( - fn () => $beam->addTokens( - $args['code'], - Arr::get($args, 'tokens', []), - Arr::get($args, 'packs', []) - ) - ); + return DB::transaction(fn () => $beam->addTokens($args['code'], $args['tokens'])); } /** @@ -92,11 +92,61 @@ protected function rules(array $args = []): array 'max:1024', new BeamExists(), ], - ...match (true) { - !$beam => [], - !$beam?->is_pack => $this->tokenRules($args, $beam?->collection_chain_id), - default => $this->packTokenRules($args, $beam?->collection_chain_id), - }, + 'tokens' => ['bail', 'array', 'min:1', new UniqueTokenIds()], + 'tokens.*.attributes' => Rule::forEach(function ($value, $attribute) use ($args) { + if (empty($value)) { + return []; + } + + return [ + 'nullable', + 'bail', + 'array', + 'min:1', + 'max:10', + new DistinctAttributes(), + Rule::prohibitedIf(BeamType::getEnumCase(Arr::get($args, str_replace('attributes', 'type', $attribute))) == BeamType::TRANSFER_TOKEN), + ]; + }), + 'tokens.*.attributes.*.key' => 'max:255', + 'tokens.*.attributes.*.value' => 'max:1000', + 'tokens.*.tokenIds' => Rule::forEach(function ($value, $attribute) use ($args, $beam) { + return [ + 'bail', + 'required_without:tokens.*.tokenIdDataUpload', + 'prohibits:tokens.*.tokenIdDataUpload', + 'distinct', + BeamType::getEnumCase(Arr::get($args, str_replace('tokenIds', 'type', $attribute))) == BeamType::TRANSFER_TOKEN + ? new TokensExistInCollection($beam?->collection_chain_id) + : new TokensDoNotExistInCollection($beam?->collection_chain_id), + new TokensDoNotExistInBeam($beam), + ]; + }), + 'tokens.*.tokenIdDataUpload' => Rule::forEach(function ($value, $attribute) use ($args, $beam) { + return [ + 'bail', + 'required_without:tokens.*.tokenIds', + 'prohibits:tokens.*.tokenIds', + BeamType::getEnumCase(Arr::get($args, str_replace('tokenIdDataUpload', 'type', $attribute))) == BeamType::TRANSFER_TOKEN + ? new TokenUploadExistInCollection($beam?->collection_chain_id) + : new TokenUploadNotExistInCollection($beam?->collection_chain_id), + new TokenUploadNotExistInBeam($beam), + ]; + }), + 'tokens.*.tokenQuantityPerClaim' => [ + 'bail', + 'filled', + 'integer', + 'min:1', + new MaxTokenSupply($beam?->collection_chain_id), + ], + 'tokens.*.claimQuantity' => [ + 'bail', + 'filled', + 'integer', + 'min:1', + new MaxTokenCount($beam?->collection_chain_id), + ], ]; } } diff --git a/src/GraphQL/Mutations/CreateBeamMutation.php b/src/GraphQL/Mutations/CreateBeamMutation.php index 1893954..3cdef48 100644 --- a/src/GraphQL/Mutations/CreateBeamMutation.php +++ b/src/GraphQL/Mutations/CreateBeamMutation.php @@ -3,22 +3,30 @@ namespace Enjin\Platform\Beam\GraphQL\Mutations; use Closure; +use Enjin\Platform\Beam\Enums\BeamType; use Enjin\Platform\Beam\GraphQL\Traits\HasBeamCommonFields; -use Enjin\Platform\Beam\GraphQL\Traits\HasTokenInputRules; +use Enjin\Platform\Beam\Rules\MaxTokenCount; +use Enjin\Platform\Beam\Rules\MaxTokenSupply; +use Enjin\Platform\Beam\Rules\TokensDoNotExistInBeam; +use Enjin\Platform\Beam\Rules\TokensExistInCollection; +use Enjin\Platform\Beam\Rules\TokenUploadExistInCollection; +use Enjin\Platform\Beam\Rules\TokenUploadNotExistInBeam; +use Enjin\Platform\Beam\Rules\UniqueTokenIds; use Enjin\Platform\Beam\Services\BeamService; use Enjin\Platform\Models\Collection; +use Enjin\Platform\Rules\DistinctAttributes; use Enjin\Platform\Rules\IsCollectionOwnerOrApproved; use Enjin\Platform\Rules\ValidSubstrateAddress; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rule; use Rebing\GraphQL\Support\Facades\GraphQL; class CreateBeamMutation extends Mutation { use HasBeamCommonFields; - use HasTokenInputRules; /** * Get the mutation's attributes. @@ -56,13 +64,9 @@ public function args(): array 'description' => __('enjin-platform-beam::mutation.create_beam.args.collectionId'), ], 'tokens' => [ - 'type' => GraphQL::type('[ClaimToken!]'), + 'type' => GraphQL::type('[ClaimToken!]!'), 'description' => __('enjin-platform-beam::input_type.claim_token.description'), ], - 'packs' => [ - 'type' => GraphQL::type('[BeamPackInput!]'), - 'description' => __('enjin-platform-beam::input_type.beam_pack.description'), - ], ]; } @@ -77,10 +81,7 @@ public function resolve( Closure $getSelectFields, BeamService $beam ) { - return DB::transaction( - fn () => $beam->create($args, (bool) Arr::get($args, 'packs'))->code, - 3 - ); + return DB::transaction(fn () => $beam->create($args)->code, 3); } /** @@ -104,9 +105,62 @@ function (string $attribute, mixed $value, Closure $fail) { }, new IsCollectionOwnerOrApproved(), ], + 'tokens' => ['bail', 'array', 'min:1', 'max:1000', new UniqueTokenIds()], + 'tokens.*.attributes' => Rule::forEach(function ($value, $attribute) use ($args) { + if (empty($value)) { + return []; + } + + return [ + 'nullable', + 'bail', + 'array', + 'min:1', + 'max:10', + new DistinctAttributes(), + Rule::prohibitedIf(BeamType::getEnumCase(Arr::get($args, str_replace('attributes', 'type', $attribute))) == BeamType::TRANSFER_TOKEN), + ]; + }), + 'tokens.*.attributes.*.key' => 'max:255', + 'tokens.*.attributes.*.value' => 'max:1000', + 'tokens.*.tokenIds' => Rule::forEach(function ($value, $attribute) use ($args) { + return [ + 'bail', + 'required_without:tokens.*.tokenIdDataUpload', + 'prohibits:tokens.*.tokenIdDataUpload', + 'distinct', + BeamType::getEnumCase(Arr::get($args, str_replace('tokenIds', 'type', $attribute))) == BeamType::TRANSFER_TOKEN + ? new TokensExistInCollection($args['collectionId']) + : '', + new TokensDoNotExistInBeam(), + ]; + }), + 'tokens.*.tokenIdDataUpload' => Rule::forEach(function ($value, $attribute) use ($args) { + return [ + 'bail', + 'required_without:tokens.*.tokenIds', + 'prohibits:tokens.*.tokenIds', + BeamType::getEnumCase(Arr::get($args, str_replace('tokenIdDataUpload', 'type', $attribute))) == BeamType::TRANSFER_TOKEN + ? new TokenUploadExistInCollection($args['collectionId']) + : '', + new TokenUploadNotExistInBeam(), + ]; + }), + 'tokens.*.tokenQuantityPerClaim' => [ + 'bail', + 'filled', + 'integer', + 'min:1', + new MaxTokenSupply($args['collectionId']), + ], + 'tokens.*.claimQuantity' => [ + 'bail', + 'filled', + 'integer', + 'min:1', + new MaxTokenCount($args['collectionId']), + ], 'flags.*.flag' => ['required', 'distinct'], - ...$this->tokenRules($args, $args['collectionId'], true), - ...$this->packTokenRules($args, $args['collectionId'], true), 'source' => [ 'nullable', new ValidSubstrateAddress(), diff --git a/src/GraphQL/Mutations/RemoveTokensMutation.php b/src/GraphQL/Mutations/RemoveTokensMutation.php index cb18ba4..9d7df97 100644 --- a/src/GraphQL/Mutations/RemoveTokensMutation.php +++ b/src/GraphQL/Mutations/RemoveTokensMutation.php @@ -3,15 +3,11 @@ namespace Enjin\Platform\Beam\GraphQL\Mutations; use Closure; -use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Rules\BeamExists; -use Enjin\Platform\Beam\Rules\BeamPackExistInBeam; use Enjin\Platform\Beam\Rules\TokensExistInBeam; -use Enjin\Platform\Beam\Rules\TokensExistInBeamPack; use Enjin\Platform\Beam\Services\BeamService; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; -use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; use Rebing\GraphQL\Support\Facades\GraphQL; @@ -47,13 +43,9 @@ public function args(): array 'description' => __('enjin-platform-beam::mutation.claim_beam.args.code'), ], 'tokenIds' => [ - 'type' => GraphQL::type('[IntegerRangeString!]'), + 'type' => GraphQL::type('[IntegerRangeString!]!'), 'description' => __('enjin-platform-beam::mutation.remove_tokens.args.tokenIds'), ], - 'packs' => [ - 'type' => GraphQL::type('[RemoveBeamPack!]'), - 'description' => __('enjin-platform-beam::input_type.remove_beam_pack.description'), - ], ]; } @@ -68,13 +60,7 @@ public function resolve( Closure $getSelectFields, BeamService $beam ) { - return DB::transaction( - fn () => $beam->removeTokens( - $args['code'], - Arr::get($args, 'tokenIds', []), - Arr::get($args, 'packs', []), - ) - ); + return DB::transaction(fn () => $beam->removeTokens($args['code'], $args['tokenIds'])); } /** @@ -82,29 +68,13 @@ public function resolve( */ protected function rules(array $args = []): array { - $beam = Beam::whereCode($args['code'])->first(); - return [ 'code' => [ 'filled', 'max:1024', new BeamExists(), ], - ...match (true) { - !$beam => [], - !$beam?->is_pack => $this->tokenIdRules(), - default => $this->packTokenIdRules(), - }, - ]; - } - - protected function tokenIdRules(): array - { - return [ 'tokenIds' => [ - 'bail', - 'required', - 'prohibits:packs', 'array', 'min:1', 'max:1000', @@ -117,36 +87,4 @@ protected function tokenIdRules(): array ], ]; } - - protected function packTokenIdRules(): array - { - return [ - 'packs' => [ - 'bail', - 'required', - 'prohibits:tokens', - 'array', - 'min:1', - 'max:1000', - ], - 'packs.*.id' => [ - 'filled', - 'integer', - 'distinct', - new BeamPackExistInBeam(), - ], - 'packs.*.tokenIds' => [ - 'array', - 'min:1', - 'max:1000', - 'distinct', - ], - 'packs.*.tokenIds.*' => [ - 'bail', - 'filled', - 'distinct', - new TokensExistInBeamPack(), - ], - ]; - } } diff --git a/src/GraphQL/Mutations/UpdateBeamMutation.php b/src/GraphQL/Mutations/UpdateBeamMutation.php index a08ca6f..a0994d5 100644 --- a/src/GraphQL/Mutations/UpdateBeamMutation.php +++ b/src/GraphQL/Mutations/UpdateBeamMutation.php @@ -3,23 +3,33 @@ namespace Enjin\Platform\Beam\GraphQL\Mutations; use Closure; +use Enjin\Platform\Beam\Enums\BeamType; use Enjin\Platform\Beam\GraphQL\Traits\HasBeamCommonFields; -use Enjin\Platform\Beam\GraphQL\Traits\HasTokenInputRules; use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Rules\BeamExists; use Enjin\Platform\Beam\Rules\IsEndDateValid; use Enjin\Platform\Beam\Rules\IsStartDateValid; +use Enjin\Platform\Beam\Rules\MaxTokenCount; +use Enjin\Platform\Beam\Rules\MaxTokenSupply; +use Enjin\Platform\Beam\Rules\TokensDoNotExistInBeam; +use Enjin\Platform\Beam\Rules\TokensDoNotExistInCollection; +use Enjin\Platform\Beam\Rules\TokensExistInCollection; +use Enjin\Platform\Beam\Rules\TokenUploadExistInCollection; +use Enjin\Platform\Beam\Rules\TokenUploadNotExistInBeam; +use Enjin\Platform\Beam\Rules\TokenUploadNotExistInCollection; +use Enjin\Platform\Beam\Rules\UniqueTokenIds; use Enjin\Platform\Beam\Services\BeamService; +use Enjin\Platform\Rules\DistinctAttributes; use GraphQL\Type\Definition\ResolveInfo; use GraphQL\Type\Definition\Type; use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rule; use Rebing\GraphQL\Support\Facades\GraphQL; class UpdateBeamMutation extends Mutation { use HasBeamCommonFields; - use HasTokenInputRules; /** * Get the mutation's attributes. @@ -59,10 +69,6 @@ public function args(): array 'type' => GraphQL::type('[ClaimToken!]'), 'description' => __('enjin-platform-beam::input_type.claim_token.description'), ], - 'packs' => [ - 'type' => GraphQL::type('[BeamPackInput!]'), - 'description' => __('enjin-platform-beam::input_type.beam_pack.description'), - ], ]; } @@ -105,11 +111,61 @@ protected function rules(array $args = []): array 'flags.*.flag' => ['required', 'distinct'], 'start' => ['filled', 'date', new IsStartDateValid()], 'end' => ['filled', 'date', new IsEndDateValid()], - ...match (true) { - !$beam => [], - !$beam?->is_pack => $this->tokenRules($args, $beam?->collection_chain_id), - default => $this->packTokenRules($args, $beam?->collection_chain_id), - }, + 'tokens' => ['bail', 'array', 'min:1', new UniqueTokenIds()], + 'tokens.*.attributes' => Rule::forEach(function ($value, $attribute) use ($args) { + if (empty($value)) { + return []; + } + + return [ + 'nullable', + 'bail', + 'array', + 'min:1', + 'max:10', + new DistinctAttributes(), + Rule::prohibitedIf(BeamType::getEnumCase(Arr::get($args, str_replace('attributes', 'type', $attribute))) == BeamType::TRANSFER_TOKEN), + ]; + }), + 'tokens.*.attributes.*.key' => 'max:255', + 'tokens.*.attributes.*.value' => 'max:1000', + 'tokens.*.tokenIds' => Rule::forEach(function ($value, $attribute) use ($args, $beam) { + return [ + 'bail', + 'required_without:tokens.*.tokenIdDataUpload', + 'prohibits:tokens.*.tokenIdDataUpload', + 'distinct', + BeamType::getEnumCase(Arr::get($args, str_replace('tokenIds', 'type', $attribute))) == BeamType::TRANSFER_TOKEN + ? new TokensExistInCollection($beam?->collection_chain_id) + : new TokensDoNotExistInCollection($beam?->collection_chain_id), + new TokensDoNotExistInBeam($beam), + ]; + }), + 'tokens.*.tokenIdDataUpload' => Rule::forEach(function ($value, $attribute) use ($args, $beam) { + return [ + 'bail', + 'required_without:tokens.*.tokenIds', + 'prohibits:tokens.*.tokenIds', + BeamType::getEnumCase(Arr::get($args, str_replace('tokenIdDataUpload', 'type', $attribute))) == BeamType::TRANSFER_TOKEN + ? new TokenUploadExistInCollection($beam?->collection_chain_id) + : new TokenUploadNotExistInCollection($beam?->collection_chain_id), + new TokenUploadNotExistInBeam($beam), + ]; + }), + 'tokens.*.tokenQuantityPerClaim' => [ + 'bail', + 'filled', + 'integer', + 'min:1', + new MaxTokenSupply($beam?->collection_chain_id), + ], + 'tokens.*.claimQuantity' => [ + 'bail', + 'filled', + 'integer', + 'min:1', + new MaxTokenCount($beam?->collection_chain_id), + ], ]; } } diff --git a/src/GraphQL/Queries/GetSingleUseCodesQuery.php b/src/GraphQL/Queries/GetSingleUseCodesQuery.php index 5a31480..2a43d69 100644 --- a/src/GraphQL/Queries/GetSingleUseCodesQuery.php +++ b/src/GraphQL/Queries/GetSingleUseCodesQuery.php @@ -4,9 +4,7 @@ use Closure; use Enjin\Platform\Beam\Enums\BeamFlag; -use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Models\BeamClaim; -use Enjin\Platform\Beam\Models\BeamPack; use Enjin\Platform\Beam\Rules\HasBeamFlag; use Enjin\Platform\GraphQL\Middleware\ResolvePage; use Enjin\Platform\GraphQL\Types\Pagination\ConnectionInput; @@ -36,7 +34,7 @@ public function attributes(): array */ public function type(): Type { - return GraphQL::paginate('ClaimUnion', 'ClaimUnionConnection'); + return GraphQL::paginate('BeamClaim', 'BeamClaimConnection'); } /** @@ -62,12 +60,8 @@ public function resolve( ResolveInfo $resolveInfo, Closure $getSelectFields ) { - $beam = Beam::whereCode($args['code'])->firstOrFail(); - - return ($beam->is_pack ? new BeamPack() : new BeamClaim()) - ->loadSelectFields($resolveInfo, $this->name) + return BeamClaim::loadSelectFields($resolveInfo, $this->name) ->hasCode($args['code']) - ->where('nonce', 1) ->with('beam') ->claimable() ->cursorPaginateWithTotalDesc('id', $args['first']); diff --git a/src/GraphQL/Traits/HasTokenInputRules.php b/src/GraphQL/Traits/HasTokenInputRules.php deleted file mode 100644 index 2996ade..0000000 --- a/src/GraphQL/Traits/HasTokenInputRules.php +++ /dev/null @@ -1,171 +0,0 @@ - [ - 'bail', - ...($withPacks ? ['required_without:packs', 'prohibits:packs'] : ['prohibits:packs']), - 'array', - 'min:1', - 'max:1000', - new UniqueTokenIds(), - ], - 'tokens.*.attributes' => Rule::forEach(function ($value, $attribute) use ($args) { - if (empty($value)) { - return []; - } - - return [ - 'nullable', - 'bail', - 'array', - 'min:1', - 'max:10', - new DistinctAttributes(), - Rule::prohibitedIf(BeamType::getEnumCase(Arr::get($args, str_replace('attributes', 'type', $attribute))) == BeamType::TRANSFER_TOKEN), - ]; - }), - 'tokens.*.attributes.*.key' => 'max:255', - 'tokens.*.attributes.*.value' => 'max:1000', - 'tokens.*.tokenIds' => Rule::forEach(function ($value, $attribute) use ($args, $collectionId) { - return [ - 'bail', - 'required_without:tokens.*.tokenIdDataUpload', - 'prohibits:tokens.*.tokenIdDataUpload', - 'distinct', - BeamType::getEnumCase(Arr::get($args, str_replace('tokenIds', 'type', $attribute))) == BeamType::TRANSFER_TOKEN - ? new TokensExistInCollection($collectionId) - : '', - new TokensDoNotExistInBeam(), - ]; - }), - 'tokens.*.tokenIdDataUpload' => Rule::forEach(function ($value, $attribute) use ($args, $collectionId) { - return [ - 'bail', - 'required_without:tokens.*.tokenIds', - 'prohibits:tokens.*.tokenIds', - BeamType::getEnumCase(Arr::get($args, str_replace('tokenIdDataUpload', 'type', $attribute))) == BeamType::TRANSFER_TOKEN - ? new TokenUploadExistInCollection($collectionId) - : '', - new TokenUploadNotExistInBeam(), - ]; - }), - 'tokens.*.tokenQuantityPerClaim' => [ - 'bail', - 'filled', - 'integer', - 'min:1', - new MaxTokenSupply($collectionId), - ], - 'tokens.*.claimQuantity' => [ - 'bail', - 'filled', - 'integer', - 'min:1', - new MaxTokenCount($collectionId), - ], - ]; - } - - public function packTokenRules(array $args, ?string $collectionId = null, bool $withTokens = false): array - { - return [ - 'packs' => [ - 'bail', - ...($withTokens ? ['required_without:tokens', 'prohibits:tokens'] : ['prohibits:tokens']), - 'array', - 'min:1', - 'max:1000', - ], - $withTokens ? '' : 'packs.*.id' => [new BeamPackExistInBeam()], - 'packs.*.tokens' => [ - 'bail', - 'array', - 'min:1', - 'max:1000', - new UniqueTokenIds(), - ], - 'packs.*.tokens.*.attributes' => Rule::forEach(function ($value, $attribute) use ($args) { - if (empty($value)) { - return []; - } - - return [ - 'nullable', - 'bail', - 'array', - 'min:1', - 'max:10', - new DistinctAttributes(), - Rule::prohibitedIf(BeamType::getEnumCase(Arr::get($args, str_replace('attributes', 'type', $attribute))) == BeamType::TRANSFER_TOKEN), - ]; - }), - 'packs.*.tokens.*.attributes.*.key' => 'max:255', - 'packs.*.tokens.*.attributes.*.value' => 'max:1000', - 'packs.*.tokens.*.tokenIds' => Rule::forEach(function ($value, $attribute) use ($args, $collectionId) { - $key = str_replace('tokenIds', 'tokenIdDataUpload', $attribute); - - return [ - 'bail', - "required_without:{$key}", - "prohibits:{$key}", - 'distinct', - BeamType::getEnumCase(Arr::get($args, str_replace('tokenIds', 'type', $attribute))) == BeamType::TRANSFER_TOKEN - ? new TokensExistInCollection($collectionId) - : '', - new TokensDoNotExistInBeam(), - ]; - }), - 'packs.*.tokens.*.tokenIdDataUpload' => Rule::forEach(function ($value, $attribute) use ($args, $collectionId) { - $key = str_replace('tokenIdDataUpload', 'tokenIds', $attribute); - - return [ - 'bail', - "required_without:{$key}", - "prohibits:{$key}", - BeamType::getEnumCase(Arr::get($args, str_replace('tokenIdDataUpload', 'type', $attribute))) == BeamType::TRANSFER_TOKEN - ? new TokenUploadExistInCollection($collectionId) - : '', - new TokenUploadNotExistInBeam(), - ]; - }), - 'packs.*.tokens.*.tokenQuantityPerClaim' => [ - 'bail', - 'filled', - 'integer', - 'min:1', - new BeamPackMaxTokenSupply($collectionId), - ], - 'packs.*.tokens.*.claimQuantity' => [ - 'prohibited', - ], - 'packs.*.claimQuantity' => [ - 'bail', - 'integer', - 'min:1', - 'max:1000', - new BeamPackMaxTokenCount($collectionId), - ], - ]; - } -} diff --git a/src/GraphQL/Types/BeamPackType.php b/src/GraphQL/Types/BeamPackType.php deleted file mode 100644 index 859f39f..0000000 --- a/src/GraphQL/Types/BeamPackType.php +++ /dev/null @@ -1,74 +0,0 @@ - 'BeamPack', - 'description' => __('enjin-platform-beam::type.beam_pack.description'), - 'model' => BeamPack::class, - ]; - } - - /** - * Get the type's fields. - */ - public function fields(): array - { - return [ - 'id' => [ - 'type' => GraphQL::type('Int'), - 'description' => __('enjin-platform-beam::type.beam_pack.field.id'), - ], - 'code' => [ - 'type' => GraphQL::type('String!'), - 'description' => __('enjin-platform-beam::type.beam_claim.field.code'), - 'resolve' => fn ($claim) => $claim->code ? $claim->singleUseCode : '', - 'excludeFrom' => ['GetBeam', 'GetBeams', 'GetPendingClaims'], - ], - 'isClaimed' => [ - 'type' => GraphQL::type('Boolean!'), - 'description' => __('enjin-platform-beam::type.beam_pack.field.isClaimed'), - 'alias' => 'is_claimed', - ], - 'beam' => [ - 'type' => GraphQL::type('Beam'), - 'description' => __('enjin-platform-beam::type.beam_claim.field.beam'), - 'is_relation' => true, - ], - 'qr' => [ - 'type' => GraphQL::type('BeamQr'), - 'description' => __('enjin-platform-beam::type.beam.field.qr'), - 'resolve' => function ($claim) { - return [ - 'url' => $claim->qrUrl, - 'payload' => $claim->claimableCode, - ]; - }, - 'selectable' => false, - 'is_relation' => false, - 'excludeFrom' => ['GetBeam', 'GetBeams', 'GetPendingClaims'], - ], - 'claims' => [ - 'type' => GraphQL::type('[BeamClaim!]'), - 'description' => __('enjin-platform-beam::type.beam_claim.description'), - 'selectable' => false, - 'is_relation' => true, - ], - ]; - } -} diff --git a/src/GraphQL/Types/BeamType.php b/src/GraphQL/Types/BeamType.php index 5fe7dcd..881481a 100644 --- a/src/GraphQL/Types/BeamType.php +++ b/src/GraphQL/Types/BeamType.php @@ -137,12 +137,6 @@ public function fields(): array 'selectable' => false, 'is_relation' => false, ], - 'packs' => [ - 'type' => GraphQL::type('[BeamPack!]'), - 'description' => __('enjin-platform-beam::type.beam_pack.description'), - 'selectable' => false, - 'is_relation' => true, - ], ]; } } diff --git a/src/GraphQL/Types/Input/BeamPackInputType.php b/src/GraphQL/Types/Input/BeamPackInputType.php deleted file mode 100644 index 02b73f1..0000000 --- a/src/GraphQL/Types/Input/BeamPackInputType.php +++ /dev/null @@ -1,41 +0,0 @@ - 'BeamPackInput', - 'description' => __('enjin-platform-beam::input_type.beam_pack.description'), - ]; - } - - /** - * Get the input type's fields. - */ - public function fields(): array - { - return [ - 'id' => [ - 'type' => GraphQL::type('Int'), - 'description' => __('enjin-platform-beam::input_type.beam_pack.field.id'), - ], - 'tokens' => [ - 'type' => GraphQL::type('[ClaimToken!]!'), - 'description' => __('enjin-platform-beam::input_type.claim_token.description'), - ], - 'claimQuantity' => [ - 'type' => GraphQL::type('Int'), - 'description' => __('enjin-platform-beam::input_type.beam_pack.field.beam_pack'), - 'defaultValue' => 1, - ], - ]; - } -} diff --git a/src/GraphQL/Types/Input/ClaimTokenInputType.php b/src/GraphQL/Types/Input/ClaimTokenInputType.php index e7f3d65..f90b001 100644 --- a/src/GraphQL/Types/Input/ClaimTokenInputType.php +++ b/src/GraphQL/Types/Input/ClaimTokenInputType.php @@ -53,6 +53,7 @@ public function fields(): array 'type' => GraphQL::type('Int'), 'description' => __('enjin-platform-beam::input_type.claim_token.field.claimQuantity'), 'rules' => ['integer'], + 'defaultValue' => 1, ], 'type' => [ 'type' => GraphQL::type('BeamType'), diff --git a/src/GraphQL/Types/Input/RemoveBeamPackType.php b/src/GraphQL/Types/Input/RemoveBeamPackType.php deleted file mode 100644 index 58830e0..0000000 --- a/src/GraphQL/Types/Input/RemoveBeamPackType.php +++ /dev/null @@ -1,36 +0,0 @@ - 'RemoveBeamPack', - 'description' => __('enjin-platform-beam::input_type.remove_beam_pack.description'), - ]; - } - - /** - * Get the input type's fields. - */ - public function fields(): array - { - return [ - 'id' => [ - 'type' => GraphQL::type('Int!'), - 'description' => __('enjin-platform-beam::input_type.beam_pack.field.id'), - ], - 'tokenIds' => [ - 'type' => GraphQL::type('[IntegerRangeString!]'), - 'description' => __('enjin-platform-beam::mutation.remove_tokens.args.tokenIds'), - ], - ]; - } -} diff --git a/src/GraphQL/Unions/ClaimUnion.php b/src/GraphQL/Unions/ClaimUnion.php deleted file mode 100644 index a4a43d5..0000000 --- a/src/GraphQL/Unions/ClaimUnion.php +++ /dev/null @@ -1,41 +0,0 @@ - 'ClaimUnion', - 'description' => __('enjin-platform-beam::union.claim_union.description'), - ]; - } - - /** - * The possible types that this union can be. - */ - public function types(): array - { - return [ - GraphQL::type('BeamClaim'), - GraphQL::type('BeamPack'), - ]; - } - - /** - * Resolves concrete ObjectType for given object value. - */ - public function resolveType($objectValue, $context, ResolveInfo $info) - { - return GraphQL::type($objectValue?->is_pack ? 'BeamPack' : 'BeamClaim'); - } -} diff --git a/src/Jobs/ClaimBeam.php b/src/Jobs/ClaimBeam.php index ee1a52f..e4d5876 100644 --- a/src/Jobs/ClaimBeam.php +++ b/src/Jobs/ClaimBeam.php @@ -4,19 +4,16 @@ use Enjin\Platform\Beam\Enums\BeamType; use Enjin\Platform\Beam\Enums\PlatformBeamCache; -use Enjin\Platform\Beam\Exceptions\BeamException; use Enjin\Platform\Beam\Models\BeamClaim; -use Enjin\Platform\Beam\Models\BeamPack; use Enjin\Platform\Beam\Models\BeamScan; use Enjin\Platform\Beam\Services\BatchService; use Enjin\Platform\Beam\Services\BeamService; -use Enjin\Platform\Models\Collection as CollectionModel; +use Enjin\Platform\Models\Collection; use Enjin\Platform\Services\Database\WalletService; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Cache\LockTimeoutException; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; @@ -52,23 +49,17 @@ public function handle(BatchService $batch, WalletService $wallet): void try { $lock->block(5); - $claims = $this->claims($data); - if (count($claims)) { - $wallet->firstOrStore(['public_key' => $data['wallet_public_key']]); - $isPackUpdated = false; + if ($claim = $this->claimQuery($data)->first()) { DB::beginTransaction(); - foreach ($claims as $claim) { - $claim->forceFill($this->buildBeamClaimAttributes($batch, $claim))->save(); - Log::info('ClaimBeamJob: Claim assigned.', $claim->toArray()); - - if ($claim->beamPack && Arr::get($this->data, 'is_pack') && ! $isPackUpdated) { - $claim->beamPack->update(['is_claimed' => true]); - $isPackUpdated = true; - } - } + $wallet->firstOrStore(['public_key' => $data['wallet_public_key']]); + $claim->forceFill($this->buildBeamClaimAttributes($batch, $claim))->save(); + // Delete scan after claim is set up so the signed data can't be used to claim again. BeamScan::firstWhere(['wallet_public_key' => $data['wallet_public_key'], 'beam_id' => $data['beam']['id']])?->delete(); + DB::commit(); + + Log::info('ClaimBeamJob: Claim assigned.', $claim->toArray()); } else { Cache::put(BeamService::key(Arr::get($data, 'beam.code')), 0); Log::info('ClaimBeamJob: No claim available, setting remaining count to 0', $data); @@ -79,7 +70,7 @@ public function handle(BatchService $batch, WalletService $wallet): void } catch (Throwable $e) { DB::rollBack(); - Log::error('ClaimBeamJob: Claim error, message: ' . $e->getMessage(), $data); + Log::error('ClaimBeamJob: Claim error, message:' . $e->getMessage(), $data); throw $e; } finally { @@ -94,7 +85,7 @@ public function handle(BatchService $batch, WalletService $wallet): void public function failed(Throwable $exception): void { if ($data = $this->data) { - if (count($this->claims($data)) > 0) { + if ($this->claimQuery($data)->count() > 0) { // Idempotency key prevents incrementing cache on same claim request even with manual retry on horizon $key = Arr::get($data, 'idempotency_key'); if (! Cache::get(PlatformBeamCache::IDEMPOTENCY_KEY->key($key))) { @@ -112,28 +103,16 @@ public function failed(Throwable $exception): void /** * Get the claim query. */ - protected function claims(array $data): Collection + protected function claimQuery(array $data): Builder { - $collection = CollectionModel::where('collection_chain_id', Arr::get($data, 'beam.collection_chain_id')) + $collection = Collection::where('collection_chain_id', Arr::get($data, 'beam.collection_chain_id')) ->first(['id', 'collection_chain_id', 'is_frozen']); return BeamClaim::where('beam_id', $data['beam']['id']) - ->with(['beam:id,collection_chain_id', 'beamPack:id,beam_id']) ->claimable() - ->when($isPack = Arr::get($data, 'is_pack'), function (Builder $query) use ($data) { - if (!($pack = BeamPack::where('is_claimed', false) - ->where('beam_id', $data['beam']['id']) - ->when($data['code'], fn ($subquery) => $subquery->where('code', $data['code'])) - ->inRandomOrder() - ->first())) { - throw new BeamException('No available packs to claim.'); - } - $query->where('beam_pack_id', $pack->id); - }) - ->when(!$isPack && $data['code'], fn ($query) => $query->withSingleUseCode($data['code'])) - ->when(!$isPack, fn ($query) => $query->inRandomOrder()) + ->when($data['code'], fn ($query) => $query->withSingleUseCode($data['code'])) ->when($collection?->is_frozen, fn ($query) => $query->where('type', BeamType::MINT_ON_DEMAND->name)) - ->get(['id', 'beam_id', 'type', 'beam_pack_id']); + ->unless($data['code'], fn ($query) => $query->inRandomOrder()); } /** diff --git a/src/Jobs/DispatchCreateBeamClaimsJobs.php b/src/Jobs/DispatchCreateBeamClaimsJobs.php index 7b2031f..9591aef 100644 --- a/src/Jobs/DispatchCreateBeamClaimsJobs.php +++ b/src/Jobs/DispatchCreateBeamClaimsJobs.php @@ -11,8 +11,6 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Support\Collection; use Illuminate\Support\LazyCollection; -use Illuminate\Support\Arr; -use Illuminate\Support\Facades\Log; class DispatchCreateBeamClaimsJobs implements ShouldQueue { @@ -27,11 +25,8 @@ class DispatchCreateBeamClaimsJobs implements ShouldQueue */ public function __construct( protected Model $beam, - protected ?array $tokens, - protected ?int $packId = null - ) { - $this->onQueue(config('enjin-platform-beam.queue')); - } + protected ?array $tokens + ) {} /** * Execute the job. @@ -55,7 +50,7 @@ public function handle(): void collect($token['tokenIds'])->each(function ($tokenId) use ($beam, $claims, $token) { $range = $this->integerRange($tokenId); if ($range === false) { - for ($i = 0; $i < Arr::get($token, 'claimQuantity', 1); $i++) { + for ($i = 0; $i < $token['claimQuantity']; $i++) { $claims->push([ 'beam_id' => $beam->id, 'token_chain_id' => $tokenId, @@ -65,7 +60,6 @@ public function handle(): void 'nonce' => 1, 'attributes' => json_encode($token['attributes']) ?: null, 'quantity' => $token['quantity'], - 'beam_pack_id' => $this->packId, ]); } } else { @@ -79,7 +73,7 @@ public function handle(): void })->chunk(10000)->each(function (LazyCollection $tokenIds) use ($beam, $token) { $claims = collect(); $tokenIds->each(function ($tokenId) use ($token, $beam, $claims) { - for ($i = 0; $i < Arr::get($token, 'claimQuantity', 1); $i++) { + for ($i = 0; $i < $token['claimQuantity']; $i++) { $claims->push([ 'beam_id' => $beam->id, 'token_chain_id' => $tokenId, @@ -89,7 +83,6 @@ public function handle(): void 'nonce' => 1, 'attributes' => json_encode($token['attributes']) ?: null, 'quantity' => $token['quantity'], - 'beam_pack_id' => $this->packId, ]); } }); diff --git a/src/Models/BeamPack.php b/src/Models/BeamPack.php deleted file mode 100644 index 5f690bd..0000000 --- a/src/Models/BeamPack.php +++ /dev/null @@ -1,7 +0,0 @@ -hasMany(BeamPack::class, 'beam_id'); - } - /** * Interact with the beam's start attribute. */ diff --git a/src/Models/Laravel/BeamClaim.php b/src/Models/Laravel/BeamClaim.php index c6293f8..b0a82f0 100644 --- a/src/Models/Laravel/BeamClaim.php +++ b/src/Models/Laravel/BeamClaim.php @@ -12,6 +12,7 @@ use Enjin\Platform\Models\Laravel\Token; use Enjin\Platform\Models\Laravel\Transaction; use Enjin\Platform\Models\Laravel\Wallet; +use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\MassPrunable; @@ -76,7 +77,6 @@ class BeamClaim extends BaseModel 'beam_id', 'nonce', 'code', - 'beam_pack_id', ]; /** @@ -130,11 +130,31 @@ public function collection(): BelongsTo } /** - * The Beam Pack's relationship. + * Local scope for single use. */ - public function beamPack(): BelongsTo + public function scopeSingleUse(Builder $query): Builder { - return $this->belongsTo(BeamPack::class, 'beam_pack_id'); + return $query->whereNotNull('code'); + } + + /** + * Local scope for single use code. + */ + public function scopeWithSingleUseCode(Builder $query, string $code): Builder + { + $parsed = BeamService::getSingleUseCodeData($code); + + return $query->where(['code' => $parsed->claimCode, 'nonce' => $parsed->nonce]); + } + + /** + * The claimable code, encoded with the open platform host url. + */ + public function singleUseCode(): Attribute + { + return Attribute::make( + get: fn () => encrypt(implode(':', [$this->code, $this->beam?->code, $this->nonce])) + ); } /** diff --git a/src/Models/Laravel/BeamPack.php b/src/Models/Laravel/BeamPack.php deleted file mode 100644 index 62ecd15..0000000 --- a/src/Models/Laravel/BeamPack.php +++ /dev/null @@ -1,136 +0,0 @@ -|bool - */ - public $guarded = []; - - /** - * The fillable fields. - * - * @var array - */ - protected $fillable = [ - 'is_claimed', - 'beam_id', - 'code', - 'nonce', - ]; - - /** - * The hidden fields. - * - * @var array - */ - protected $hidden = [ - 'created_at', - 'updated_at', - 'beam_id', - ]; - - /** - * The beam's relationship. - */ - public function beam(): BelongsTo - { - return $this->belongsTo(Beam::class); - } - - /** - * The beam claim's relationship. - */ - public function claims(): HasMany - { - return $this->hasMany(BeamClaim::class, 'beam_pack_id'); - } - - public function scopeClaimable(Builder $query): Builder - { - return $query->where('is_claimed', false); - } - - /** - * Load beam claim's select and relationship fields. - */ - public static function loadClaims( - array $selections, - string $attribute, - array $args = [], - ?string $key = null, - bool $isParent = false - ): array { - $fields = Arr::get($selections, $attribute, $selections); - $select = array_filter([ - 'id', - 'beam_id', - ...(isset($fields['qr']) ? ['code'] : []), - ...(static::$query == 'GetSingleUseCodes' ? ['code', 'nonce'] : ['nonce']), - ...BeamPackType::getSelectFields($fieldKeys = array_keys($fields)), - ]); - - $with = []; - $withCount = []; - - if (! $isParent) { - $with = [ - $key => function ($query) use ($select, $args) { - $query->select(array_unique($select)) - ->when($cursor = Cursor::fromEncoded(Arr::get($args, 'after')), fn ($q) => $q->where('id', '>', $cursor->parameter('id'))) - ->orderBy('beam_packs.id'); - // This must be done this way to load eager limit correctly. - if ($limit = Arr::get($args, 'first')) { - $query->limit($limit + 1); - } - }, - ]; - } - - foreach ([ - ...BeamPackType::getRelationFields($fieldKeys), - ...(isset($fields['code']) ? ['beam'] : []), - ] as $relation) { - $with = array_merge( - $with, - static::getRelationQuery( - BeamPackType::class, - $relation, - $fields, - $key, - $with - ) - ); - } - - return [$select, $with, $withCount]; - } - - /** - * This model's factory. - */ - protected static function newFactory(): BeamPackFactory - { - return BeamPackFactory::new(); - } -} diff --git a/src/Models/Laravel/Traits/HasSingleUseCodeScope.php b/src/Models/Laravel/Traits/HasSingleUseCodeScope.php index a758046..a499683 100644 --- a/src/Models/Laravel/Traits/HasSingleUseCodeScope.php +++ b/src/Models/Laravel/Traits/HasSingleUseCodeScope.php @@ -4,7 +4,6 @@ use Enjin\Platform\Beam\Services\BeamService; use Illuminate\Contracts\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Support\Arr; trait HasSingleUseCodeScope @@ -28,32 +27,4 @@ public function scopeHasSingleUseCode(Builder $query, string|array|null $code): return $query; } } - - /** - * Local scope for single use. - */ - public function scopeSingleUse(Builder $query): Builder - { - return $query->whereNotNull('code'); - } - - /** - * Local scope for single use code. - */ - public function scopeWithSingleUseCode(Builder $query, string $code): Builder - { - $parsed = BeamService::getSingleUseCodeData($code); - - return $query->where(['code' => $parsed->claimCode, 'nonce' => $parsed->nonce]); - } - - /** - * The claimable code, encoded with the open platform host url. - */ - public function singleUseCode(): Attribute - { - return Attribute::make( - get: fn () => encrypt(implode(':', [$this->code, $this->beam?->code, $this->nonce])) - ); - } } diff --git a/src/Rules/BeamPackExistInBeam.php b/src/Rules/BeamPackExistInBeam.php deleted file mode 100644 index 1d50bef..0000000 --- a/src/Rules/BeamPackExistInBeam.php +++ /dev/null @@ -1,33 +0,0 @@ -data['code'])->whereHas('packs', fn ($query) => $query->where('id', $value))->exists()) { - $fail('enjin-platform-beam::validation.beam_pack_exist_in_beam')->translate(); - } - - } -} diff --git a/src/Rules/BeamPackMaxTokenCount.php b/src/Rules/BeamPackMaxTokenCount.php deleted file mode 100644 index 23043ed..0000000 --- a/src/Rules/BeamPackMaxTokenCount.php +++ /dev/null @@ -1,13 +0,0 @@ -data, 'packs'))->flatMap(fn ($row) => Arr::get($row, 'tokens', []))->toArray(); - } -} diff --git a/src/Rules/BeamPackMaxTokenSupply.php b/src/Rules/BeamPackMaxTokenSupply.php deleted file mode 100644 index cf03634..0000000 --- a/src/Rules/BeamPackMaxTokenSupply.php +++ /dev/null @@ -1,13 +0,0 @@ -data, 'packs'))->flatMap(fn ($row) => Arr::get($row, 'tokens', []))->toArray(); - } -} diff --git a/src/Rules/MaxTokenCount.php b/src/Rules/MaxTokenCount.php index cf0f7b0..3cb1d1f 100644 --- a/src/Rules/MaxTokenCount.php +++ b/src/Rules/MaxTokenCount.php @@ -39,10 +39,6 @@ public function validate(string $attribute, mixed $value, Closure $fail): void * The sum of all unique tokens (including existing tokens, tokens in beams, and tokens to be created) * must not exceed the collection's maximum token count. */ - if (!$inputTokens = $this->getInputTokens()) { - return; - } - if ($this->collectionId && ($collection = Collection::withCount('tokens')->firstWhere(['collection_chain_id' => $this->collectionId])) && ! is_null($this->limit = $collection->max_token_count) @@ -65,12 +61,12 @@ public function validate(string $attribute, mixed $value, Closure $fail): void ->groupBy('token_chain_id') ->count(); - $tokens = collect($inputTokens) + $tokens = collect($this->data['tokens']) ->filter(fn ($data) => !empty(Arr::get($data, 'tokenIds'))) ->pluck('tokenIds') ->flatten(); - collect($inputTokens) + collect($this->data['tokens']) ->filter(fn ($data) => !empty(Arr::get($data, 'tokenIdDataUpload'))) ->map(function ($data) use ($tokens) { $handle = fopen($data['tokenIdDataUpload']->getPathname(), 'r'); @@ -137,9 +133,4 @@ public function validate(string $attribute, mixed $value, Closure $fail): void } } } - - protected function getInputTokens(): array - { - return Arr::get($this->data, 'tokens', []); - } } diff --git a/src/Rules/MaxTokenSupply.php b/src/Rules/MaxTokenSupply.php index a876a9e..963102a 100644 --- a/src/Rules/MaxTokenSupply.php +++ b/src/Rules/MaxTokenSupply.php @@ -49,10 +49,6 @@ public function validate(string $attribute, mixed $value, Closure $fail): void * For example, if the maximum token count is 10 and the maximum token supply is 10, * the total circulating supply must not exceed 100. */ - if (!$inputTokens = $this->getInputTokens()) { - return; - } - if ($this->collectionId && ($collection = Collection::firstWhere(['collection_chain_id' => $this->collectionId])) && ! is_null($this->limit = $collection->max_token_supply) @@ -81,7 +77,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void ->sum('quantity'); $tokenCount = 0; - $tokenCount = collect($inputTokens) + $tokenCount = collect($this->data['tokens']) ->reduce(function ($carry, $token) { if (Arr::get($token, 'tokenIds')) { @@ -123,9 +119,4 @@ public function validate(string $attribute, mixed $value, Closure $fail): void } } } - - protected function getInputTokens(): array - { - return Arr::get($this->data, 'tokens', []); - } } diff --git a/src/Rules/SingleUseCodeExist.php b/src/Rules/SingleUseCodeExist.php index d025058..35bc924 100644 --- a/src/Rules/SingleUseCodeExist.php +++ b/src/Rules/SingleUseCodeExist.php @@ -3,9 +3,7 @@ namespace Enjin\Platform\Beam\Rules; use Closure; -use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Models\BeamClaim; -use Enjin\Platform\Beam\Models\BeamPack; use Enjin\Platform\Beam\Services\BeamService; use Illuminate\Contracts\Validation\ValidationRule; @@ -20,14 +18,12 @@ public function __construct(protected bool $isClaiming = false) {} */ public function validate(string $attribute, mixed $value, Closure $fail): void { - $beamCode = BeamService::getSingleUseCodeData($value)?->beamCode; - if ($beamCode && ($beam = Beam::where('code', $beamCode)->first())) { - if (($beam->is_pack ? new BeamPack() : new BeamClaim()) - ->withSingleUseCode($value) - ->when($this->isClaiming, fn ($query) => $query->claimable()) - ->exists()) { - return; - } + if (BeamService::isSingleUse($value) && + BeamClaim::withSingleUseCode($value) + ->when($this->isClaiming, fn ($query) => $query->claimable()) + ->exists() + ) { + return; } $fail('enjin-platform-beam::validation.verify_signed_message')->translate(); diff --git a/src/Rules/TokensExistInBeamPack.php b/src/Rules/TokensExistInBeamPack.php deleted file mode 100644 index 651bbe4..0000000 --- a/src/Rules/TokensExistInBeamPack.php +++ /dev/null @@ -1,62 +0,0 @@ -data, $key)) { - [$integers, $ranges] = collect($value)->partition(fn ($val) => $this->integerRange($val) === false); - if (count($integers)) { - $count = BeamClaim::whereIn('token_chain_id', $integers) - ->whereNull('claimed_at') - ->where('beam_pack_id', $id) - ->count(); - if ($count != count($integers)) { - $fail($this->message())->translate(); - - return; - } - } - foreach ($ranges as $range) { - [$from, $to] = $this->integerRange($range); - $count = BeamClaim::whereBetween('token_chain_id', [(int) $from, (int) $to]) - ->whereNull('claimed_at') - ->where('beam_pack_id', $id) - ->count(); - if ($count !== ($to - $from) + 1) { - $fail($this->message())->translate(); - } - } - } - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return 'enjin-platform-beam::validation.tokens_exist_in_beam_pack'; - } -} diff --git a/src/Services/BeamService.php b/src/Services/BeamService.php index 15ec324..022f35d 100644 --- a/src/Services/BeamService.php +++ b/src/Services/BeamService.php @@ -19,7 +19,6 @@ use Enjin\Platform\Beam\Jobs\DispatchCreateBeamClaimsJobs; use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Models\BeamClaim; -use Enjin\Platform\Beam\Models\BeamPack; use Enjin\Platform\Beam\Rules\Traits\IntegerRange; use Enjin\Platform\Beam\Support\ClaimProbabilities; use Enjin\Platform\Support\BitMask; @@ -29,7 +28,6 @@ use Illuminate\Contracts\Cache\LockTimeoutException; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; -use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; use Illuminate\Support\LazyCollection; @@ -79,23 +77,18 @@ public static function getFlagsValue(?array $flags, int $initial = 0): ?int /** * Create a beam. */ - public function create(array $args, bool $isPack = false): Model + public function create(array $args): Model { $beam = Beam::create([ - ...Arr::except($args, ['tokens', 'packs', 'flags']), + ...Arr::except($args, ['tokens', 'flags']), 'flags_mask' => static::getFlagsValue(Arr::get($args, 'flags')), 'code' => bin2hex(openssl_random_pseudo_bytes(16)), - 'is_pack' => $isPack, ]); if ($beam) { - if ($isPack) { - $this->createPackClaims($beam, Arr::get($args, 'packs', []), true); - } else { - Cache::forever( - self::key($beam->code), - $this->createClaims($beam, Arr::get($args, 'tokens', [])) - ); - } + Cache::forever( + self::key($beam->code), + $this->createClaims(Arr::get($args, 'tokens', []), $beam) + ); event(new BeamCreated($beam)); return $beam; @@ -104,79 +97,6 @@ public function create(array $args, bool $isPack = false): Model return throw new BeamException(__('enjin-platform-beam::error.unable_to_save')); } - /** - * Create beam pack claims. - */ - public function createPackClaims(Model $beam, array $packs, bool $isNew = false): bool - { - if (empty($packs)) { - return false; - } - - $quantity = 0; - $allTokenIds = []; - foreach ($packs as $pack) { - if (!($id = Arr::get($pack, 'id'))) { - $quantity++; - } - - $beamPack = BeamPack::firstOrcreate(['id' => $id], [ - 'beam_id' => $beam->id, - 'code' => bin2hex(openssl_random_pseudo_bytes(16)), - 'nonce' => 1, - ]); - - $tokens = Collection::times( - Arr::get($pack, 'claimQuantity', 1), - fn () => $pack['tokens'] - )->flatMap(fn ($rows) => $rows); - $tokenIds = $tokens->whereNotNull('tokenIds'); - - if ($tokenIds->count()) { - $allTokenIds = $tokenIds->pluck('tokenIds')->flatten()->all(); - DispatchCreateBeamClaimsJobs::dispatch($beam, $tokenIds->all(), $beamPack->id)->afterCommit(); - } - - $tokenUploads = $tokens->whereNotNull('tokenIdDataUpload'); - if ($tokenUploads->count()) { - $ids = $tokenIds->pluck('tokenIds'); - $tokenUploads->each(function ($token) use ($beam, $ids, $beamPack) { - LazyCollection::make(function () use ($token, $ids) { - $handle = fopen($token['tokenIdDataUpload']->getPathname(), 'r'); - while (($line = fgets($handle)) !== false) { - if (! $this->tokenIdExists($ids->all(), $tokenId = trim($line))) { - $ids->push($tokenId); - yield $tokenId; - } - } - fclose($handle); - })->chunk(10000)->each(function (LazyCollection $tokenIds) use ($beam, $token, $beamPack) { - $token['tokenIds'] = $tokenIds->all(); - unset($token['tokenIdDataUpload']); - DispatchCreateBeamClaimsJobs::dispatch($beam, [$token], $beamPack->id)->afterCommit(); - unset($tokenIds, $token); - }); - }); - $allTokenIds = $ids->pluck('tokenIds')->flatten()->all(); - } - - } - - if ($isNew) { - return Cache::forever(self::key($beam->code), count($packs)); - } - - TokensAdded::safeBroadcast( - event: [ - 'beamCode' => $beam->code, - 'code' => $beam->code, - 'tokenIds' => $allTokenIds, - ] - ); - - return Cache::increment(self::key($beam->code), $quantity); - } - /** * Update beam by code. */ @@ -189,12 +109,10 @@ public function updateByCode(string $code, array $values): Model } if ($beam->fill($values)->save()) { - if ($beam->is_pack && ($packs = Arr::get($values, 'packs', []))) { - $this->createPackClaims($beam, $packs); - } elseif ($tokens = Arr::get($values, 'tokens', [])) { + if ($tokens = Arr::get($values, 'tokens', [])) { Cache::increment( self::key($beam->code), - $this->createClaims($beam, $tokens) + $this->createClaims($tokens, $beam) ); TokensAdded::safeBroadcast(event: ['beamCode' => $beam->code, 'code' => $code, 'tokenIds' => collect($tokens)->pluck('tokenIds')->all()]); } @@ -209,19 +127,14 @@ public function updateByCode(string $code, array $values): Model /** * Update beam by code. */ - public function addTokens(string $code, ?array $tokens = [], ?array $packs = []): bool + public function addTokens(string $code, array $tokens): bool { $beam = Beam::whereCode($code)->firstOrFail(); - - if ($beam->is_pack && $packs) { - $this->createPackClaims($beam, $packs); - } elseif ($tokens) { - Cache::increment( - self::key($beam->code), - $this->createClaims($beam, $tokens) - ); - TokensAdded::safeBroadcast(event: ['beamCode' => $beam->code, 'code' => $code, 'tokenIds' => collect($tokens)->pluck('tokenIds')->all()]); - } + Cache::increment( + self::key($beam->code), + $this->createClaims($tokens, $beam) + ); + TokensAdded::safeBroadcast(event: ['beamCode' => $beam->code, 'code' => $code, 'tokenIds' => collect($tokens)->pluck('tokenIds')->all()]); return true; } @@ -239,16 +152,14 @@ public function findByCode(string $code): ?Model */ public function scanByCode(string $code, ?string $wallet = null): ?Model { - $beamCode = static::getSingleUseCodeData($code)?->beamCode; - $beam = Beam::whereCode($beamCode ?? $code)->firstOrFail(); - - if ($beamCode) { - ($beam->is_pack ? new BeamPack() : new BeamClaim()) - ->withSingleUseCode($code) - ->firstOrFail(); - } - + $isSingleUse = static::isSingleUse($code); + $beam = $isSingleUse + ? BeamClaim::withSingleUseCode($code) + ->with('beam') + ->first() + ->beam + : $this->findByCode($code); if ($wallet) { // Pushing this to the queue for performance CreateClaim::dispatch($claim = [ @@ -260,7 +171,7 @@ public function scanByCode(string $code, ?string $wallet = null): ?Model $beam->setRelation('scans', collect(json_decode(json_encode([$claim])))); } - if ($beamCode) { + if ($isSingleUse) { $beam['code'] = $code; } @@ -273,20 +184,21 @@ public function scanByCode(string $code, ?string $wallet = null): ?Model public function claim(string $code, string $wallet, ?string $idempotencyKey = null): bool { $singleUseCode = null; - $singleUse = static::getSingleUseCodeData($code); - $beam = $this->findByCode($singleUse ? $singleUse->beamCode : $code); - if (! $beam) { - throw new BeamException(__('enjin-platform-beam::error.beam_not_found', ['code' => $code])); - } + $singleUse = static::isSingleUse($code); if ($singleUse) { - if (!($beam->is_pack ? new BeamPack() : new BeamClaim()) - ->withSingleUseCode($code) - ->first()) { - throw new BeamException(__('enjin-platform-beam::error.beam_not_found', ['code' => $code])); - } $singleUseCode = $code; - $code = $singleUse->beamCode; + $beam = BeamClaim::withSingleUseCode($singleUseCode) + ->with('beam') + ->first() + ->beam; + $code = $beam?->code; + } else { + $beam = $this->findByCode($code); + } + + if (! $beam) { + throw new BeamException(__('enjin-platform-beam::error.beam_not_found', ['code' => $code])); } $lock = Cache::lock(self::key($code, 'claim-lock'), 5); @@ -354,25 +266,22 @@ public static function key(string $name, ?string $suffix = null): string */ public function expireSingleUseCodes(array $codes): int { - $beamCodes = collect($codes) - ->keyBy(fn ($code) => static::getSingleUseCodeData($code)->beamCode) - ->all(); - - Beam::whereIn('code', array_keys($beamCodes)) - ->get(['id', 'code', 'is_pack']) - ->each(function ($beam) use ($beamCodes) { - if ($claim = ($beam->is_pack ? new BeamPack() : new BeamClaim()) - ->claimable() - ->where('beam_id', $beam->id) - ->withSingleUseCode($beamCodes[$beam->code]) - ->first() - ) { - $claim->increment('nonce'); - Cache::decrement($this->key($beam->code)); + $beams = []; + collect($codes)->each(function ($code) use (&$beams) { + if ($claim = BeamClaim::claimable()->withSingleUseCode($code)->first()) { + if (! isset($beams[$claim->beam_id])) { + $beams[$claim->beam_id] = 0; } - }); + $beams[$claim->beam_id] += $claim->increment('nonce'); + } + }); + + if ($beams) { + Beam::findMany(array_keys($beams), ['id', 'code']) + ->each(fn ($beam) => Cache::decrement($this->key($beam->code, $beams[$beam->id]))); + } - return count($codes); + return array_sum($beams); } /** @@ -432,97 +341,34 @@ public function deleteByCode(string $code): bool /** * Remove tokens from a beam. */ - public function removeTokens(string $code, ?array $tokens = [], ?array $packs = []): bool + public function removeTokens(string $code, array $tokens): bool { - $beam = Beam::whereCode($code)->firstOrFail(); - if ($beam->is_pack) { - $this->removeBeamPack($packs, $beam); - } else { - $this->removeClaimTokens($tokens, $beam); - } - - return true; - } - - public function removeClaimTokens(array $tokens, Model $beam): void - { - [$integers, $ranges] = collect($tokens)->partition(fn ($val) => $this->integerRange($val) === false)->all(); + $integers = collect($tokens)->filter(fn ($val) => $this->integerRange($val) === false)->all(); if ($integers) { Cache::decrement( - self::key($beam->code), + self::key($code), BeamClaim::whereIn('token_chain_id', $integers) - ->where('beam_id', $beam->id) + ->whereHas('beam', fn ($query) => $query->where('code', $code)) ->whereNull('claimed_at') ->delete() ); } + $ranges = collect($tokens)->filter(fn ($val) => $this->integerRange($val) !== false)->all(); foreach ($ranges as $range) { [$from, $to] = $this->integerRange($range); Cache::decrement( - self::key($beam->code), + self::key($code), BeamClaim::whereBetween('token_chain_id', [(int) $from, (int) $to]) - ->where('beam_id', $beam->id) + ->whereHas('beam', fn ($query) => $query->where('code', $code)) ->whereNull('claimed_at') ->delete() ); } if ($tokens) { - $this->probability->removeTokens($beam->code, $tokens); - TokensRemoved::safeBroadcast(event: ['code' => $beam->code, 'tokenIds' => $tokens]); - } - } - - /** - * Remove beam pack tokens. - */ - public function removeBeamPack(array $packs, Model $beam): bool - { - $packCollection = collect($packs)->keyBy('id'); - $deletedTokens = 0; - $forDeletion = []; - foreach ($packCollection as $pack) { - if (empty($pack['tokenIds'])) { - $forDeletion[] = $pack['id']; - - continue; - } - - [$tokenIds, $tokenIdRanges] = collect($pack['tokenIds'])->partition(fn ($val) => $this->integerRange($val) === false); - if ($tokenIds) { - $deletedTokens += BeamClaim::where('beam_pack_id', $pack['id']) - ->whereNull('claimed_at') - ->whereIn('token_chain_id', $tokenIds) - ->delete(); - } - - if ($tokenIdRanges) { - $deletedTokens += BeamClaim::where('beam_pack_id', $pack['id']) - ->whereNull('claimed_at') - ->where(function ($query) use ($tokenIdRanges) { - $tokenIdRanges->each(function ($tokenString) use ($query) { - $ranges = $this->integerRange($tokenString); - $query->orWhereBetween('token_chain_id', [(int) $ranges[0], (int) $ranges[1]]); - }); - }) - ->delete(); - } - } - - $beamPacks = BeamPack::where('beam_id', $beam->id) - ->whereIn('id', $packCollection->pluck('id')) - ->withCount('claims') - ->get(['id']); - $forDeletion = array_merge($forDeletion, $beamPacks->where('claims_count', 0)->pluck('id')->all()); - if (count($forDeletion)) { - BeamPack::whereIn('id', $forDeletion) - ->whereDoesntHave('claims', fn ($query) => $query->whereNotNull('claimed_at')) - ->delete(); - } - - if ($deletedTokens) { - TokensRemoved::safeBroadcast(event: ['code' => $beam->code, 'tokenIds' => $packCollection->pluck('tokenIds')->flatten()->all()]); + $this->probability->removeTokens($code, $tokens); + TokensRemoved::safeBroadcast(event: ['code' => $code, 'tokenIds' => $tokens]); } return true; @@ -531,7 +377,7 @@ public function removeBeamPack(array $packs, Model $beam): bool /** * Create beam claims. */ - protected function createClaims(Model $beam, array $tokens): int + protected function createClaims(array $tokens, Model $beam): int { $totalClaimCount = 0; $tokens = collect($tokens); @@ -541,12 +387,10 @@ protected function createClaims(Model $beam, array $tokens): int return collect($token['tokenIds'])->reduce(function ($val, $tokenId) use ($token) { $range = $this->integerRange($tokenId); - $claimQuantity = Arr::get($token, 'claimQuantity', 1); - return $val + ( $range === false - ? $claimQuantity - : (($range[1] - $range[0]) + 1) * $claimQuantity + ? $token['claimQuantity'] + : (($range[1] - $range[0]) + 1) * $token['claimQuantity'] ); }, $carry); }, $totalClaimCount); @@ -573,12 +417,10 @@ protected function createClaims(Model $beam, array $tokens): int $totalClaimCount = $tokenIds->reduce(function ($carry, $tokenId) use ($token) { $range = $this->integerRange($tokenId); - $claimQuantity = Arr::get($token, 'claimQuantity', 1); - return $carry + ( $range === false - ? $claimQuantity - : (($range[1] - $range[0]) + 1) * $claimQuantity + ? $token['claimQuantity'] + : (($range[1] - $range[0]) + 1) * $token['claimQuantity'] ); }, $totalClaimCount); unset($token['tokenIdDataUpload']); @@ -623,7 +465,6 @@ protected function buildRequiredClaimBeamData( 'state' => ClaimStatus::PENDING->name, 'beam' => $beam->toArray(), 'beam_id' => $beam->id, - 'is_pack' => $beam->is_pack, 'ip_address' => request()->getClientIp(), 'code' => $singleUseCode, 'idempotency_key' => $idempotencyKey ?: Str::uuid()->toString(), diff --git a/src/Support/ClaimProbabilities.php b/src/Support/ClaimProbabilities.php index 69b3950..351c78c 100644 --- a/src/Support/ClaimProbabilities.php +++ b/src/Support/ClaimProbabilities.php @@ -167,8 +167,8 @@ protected function formatClaims(Collection $claims): array foreach ($claim['tokenIds'] as $tokenId) { $range = $this->integerRange($tokenId); $tokens[$tokenId] = $range !== false - ? (($range[1] - $range[0]) + 1) * Arr::get($claim, 'claimQuantity', 1) - : Arr::get($claim, 'claimQuantity', 1); + ? (($range[1] - $range[0]) + 1) * $claim['claimQuantity'] + : $claim['claimQuantity']; } } @@ -181,7 +181,7 @@ protected function formatClaims(Collection $claims): array protected function filterClaims(array $claims): array { [$nfts, $fts] = collect($claims)->partition( - fn ($claim) => Arr::get($claim, 'claimQuantity', 1) == 1 && Arr::get($claim, 'tokenQuantityPerClaim', 1) == 1 + fn ($claim) => $claim['claimQuantity'] == 1 && Arr::get($claim, 'tokenQuantityPerClaim', 1) == 1 ); return [ diff --git a/tests/Feature/GraphQL/Mutations/AddTokensTest.php b/tests/Feature/GraphQL/Mutations/AddTokensTest.php index 739f858..13a6706 100644 --- a/tests/Feature/GraphQL/Mutations/AddTokensTest.php +++ b/tests/Feature/GraphQL/Mutations/AddTokensTest.php @@ -44,17 +44,6 @@ public function test_it_add_tokens(): void ); $this->assertTrue($response); Event::assertDispatched(TokensAdded::class); - - $this->seedBeamPack(); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [['tokenIds' => ['1..5'], 'type' => BeamType::MINT_ON_DEMAND->name]]]], - ] - ); - $this->assertTrue($response); - Event::assertDispatched(TokensAdded::class); } public function test_it_can_add_token_with_attributes(): void @@ -78,31 +67,10 @@ public function test_it_can_add_token_with_attributes(): void ); $this->assertTrue($response); Event::assertDispatched(TokensAdded::class); - - $this->seedBeamPack(); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [ - [ - 'tokenIds' => ['1..5'], - 'type' => BeamType::MINT_ON_DEMAND->name, - 'attributes' => [ - ['key' => 'test', 'value' => 'test'], - ['key' => 'test2', 'value' => 'test2'], - ], - ], - ], - ]]], - ); - $this->assertTrue($response); - Event::assertDispatched(TokensAdded::class); } public function test_it_can_update_beam_with_file_upload(): void { - Event::fake(); $file = UploadedFile::fake()->createWithContent('tokens.txt', "1\n2..10"); $response = $this->graphql( $this->method, @@ -124,31 +92,6 @@ public function test_it_can_update_beam_with_file_upload(): void ); $this->assertTrue($response); Event::assertDispatched(TokensAdded::class); - - $this->seedBeamPack(); - $file = UploadedFile::fake()->createWithContent('tokens.txt', "1\n2..10"); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [[ - 'tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]], - ]], - ] - ); - $this->assertTrue($response); - Event::assertDispatched(TokensAdded::class); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', "{$this->token->token_chain_id}\n{$this->token->token_chain_id}..{$this->token->token_chain_id}"); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [['tokenIdDataUpload' => $file]]]], - ] - ); - $this->assertTrue($response); - Event::assertDispatched(TokensAdded::class); } public function test_it_will_fail_with_token_exist_in_beam(): void @@ -181,44 +124,38 @@ public function test_it_will_fail_with_token_exist_in_beam(): void $this->assertArraySubset([ 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload already exist in beam.'], ], $response['error']); + } - - $this->seedBeamPack(); - $claim = $this->claims->first(); - $claim->forceFill(['token_chain_id' => $this->token->token_chain_id])->save(); + public function test_it_will_fail_to_create_beam_with_invalid_file_upload(): void + { + $file = UploadedFile::fake()->createWithContent('tokens.txt', $this->token->token_chain_id); $response = $this->graphql( $this->method, [ 'code' => $this->beam->code, - 'packs' => [[ - 'tokens' => [['tokenIds' => [$claim->token_chain_id], 'type' => BeamType::TRANSFER_TOKEN->name]], - ]], + 'tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]], ], true ); $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIds' => ['The packs.0.tokens.0.tokenIds already exist in beam.'], + 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload exists in the specified collection.'], ], $response['error']); + Event::assertNotDispatched(BeamUpdated::class); - $file = UploadedFile::fake()->createWithContent('tokens.txt', $this->token->token_chain_id); + $file = UploadedFile::fake()->createWithContent('tokens.txt', "{$this->token->token_chain_id}..{$this->token->token_chain_id}"); $response = $this->graphql( $this->method, [ 'code' => $this->beam->code, - 'packs' => [[ - 'tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::TRANSFER_TOKEN->name]], - ]], + 'tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]], ], true ); $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIdDataUpload' => ['The packs.0.tokens.0.tokenIdDataUpload already exist in beam.'], + 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload exists in the specified collection.'], ], $response['error']); + Event::assertNotDispatched(BeamUpdated::class); - } - - public function test_it_will_fail_to_create_beam_with_invalid_file_upload(): void - { $file = UploadedFile::fake()->createWithContent('tokens.txt', '1'); $response = $this->graphql( $this->method, @@ -231,6 +168,7 @@ public function test_it_will_fail_to_create_beam_with_invalid_file_upload(): voi $this->assertArraySubset([ 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload does not exist in the specified collection.'], ], $response['error']); + Event::assertNotDispatched(BeamUpdated::class); $file = UploadedFile::fake()->createWithContent('tokens.txt', '1..10'); $response = $this->graphql( @@ -244,33 +182,7 @@ public function test_it_will_fail_to_create_beam_with_invalid_file_upload(): voi $this->assertArraySubset([ 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload does not exist in the specified collection.'], ], $response['error']); - - $this->seedBeamPack(); - $file = UploadedFile::fake()->createWithContent('tokens.txt', '1'); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [['tokenIdDataUpload' => $file]]]], - ], - true - ); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIdDataUpload' => ['The packs.0.tokens.0.tokenIdDataUpload does not exist in the specified collection.'], - ], $response['error']); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', '1..10'); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [['tokenIdDataUpload' => $file]]]], - ], - true - ); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIdDataUpload' => ['The packs.0.tokens.0.tokenIdDataUpload does not exist in the specified collection.'], - ], $response['error']); + Event::assertNotDispatched(BeamUpdated::class); } /** @@ -288,30 +200,28 @@ public function test_it_will_fail_with_invalid_parameters(): void ); $this->assertArraySubset([ 'code' => ['The selected code is invalid.'], + 'tokens' => ['The tokens field must have at least 1 items.'], ], $response['error']); - $response = $this->graphql( $this->method, [ - 'code' => $this->beam->code, - 'tokens' => [], + 'code' => null, + 'tokens' => null, ], true ); - $this->assertArraySubset([ - 'tokens' => ['The tokens field must have at least 1 items.'], - ], $response['error']); + $this->assertEquals($response['error'], 'Variable "$code" of non-null type "String!" must not be null.'); $response = $this->graphql( $this->method, [ - 'code' => null, + 'code' => $this->beam->code, 'tokens' => null, ], true ); - $this->assertEquals($response['error'], 'Variable "$code" of non-null type "String!" must not be null.'); + $this->assertEquals($response['error'], 'Variable "$tokens" of non-null type "[ClaimToken!]!" must not be null.'); $response = $this->graphql($this->method, [ 'code' => Str::random(1500), @@ -321,18 +231,5 @@ public function test_it_will_fail_with_invalid_parameters(): void ['code' => ['The code field must not be greater than 1024 characters.']], $response['error'] ); - - $this->seedBeamPack(); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [], - ], - true - ); - $this->assertArraySubset([ - 'packs' => ['The packs field must have at least 1 items.'], - ], $response['error']); } } diff --git a/tests/Feature/GraphQL/Mutations/ClaimBeamTest.php b/tests/Feature/GraphQL/Mutations/ClaimBeamTest.php index 8781db3..287660b 100644 --- a/tests/Feature/GraphQL/Mutations/ClaimBeamTest.php +++ b/tests/Feature/GraphQL/Mutations/ClaimBeamTest.php @@ -26,7 +26,6 @@ use Enjin\Platform\Support\SS58Address; use Faker\Generator; use Illuminate\Support\Arr; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Queue; @@ -103,20 +102,6 @@ public function test_it_can_claim_beam_with_sr25519_single_use_codes(): void $this->genericClaimTest(CryptoSignatureType::SR25519, Arr::get($response, 'edges.0.node.code')); } - public function test_it_can_claim_beam_pack_with_sr25519_single_use_codes(): void - { - $code = $this->graphql('CreateBeam', $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - 1, - [], - [['flag' => 'SINGLE_USE']], - )); - $response = $this->graphql('GetSingleUseCodes', ['code' => $code]); - $this->assertNotEmpty($response['totalCount']); - - $this->genericClaimTest(CryptoSignatureType::SR25519, Arr::get($response, 'edges.0.node.code')); - } - /** * Test claiming beam with ed25519. */ @@ -125,44 +110,6 @@ public function test_it_can_claim_beam_with_ed25519(): void $this->genericClaimTest(CryptoSignatureType::ED25519); } - public function test_it_can_claim_beam_pack_with_ed25519(): void - { - $this->seedBeamPack(); - $this->genericClaimTest(CryptoSignatureType::ED25519); - } - - public function test_it_can_claim_beam_pack_with_sr25519(): void - { - $this->seedBeamPack(); - $this->genericClaimTest(CryptoSignatureType::SR25519); - } - - public function test_it_cannot_claim_beam_pack_with_expired_single_use(): void - { - $code = $this->graphql('CreateBeam', $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - 1, - [], - [['flag' => 'SINGLE_USE']], - )); - $response = $this->graphql('GetSingleUseCodes', ['code' => $code]); - $this->assertNotEmpty($response['totalCount']); - - $singleUse = Arr::get($response, 'edges.0.node.code'); - $response = $this->graphql('ExpireSingleUseCodes', ['codes' => [$singleUse]]); - $this->assertTrue($response); - - [$keypair, $publicKey, $privateKey] = $this->getKeyPair(CryptoSignatureType::ED25519); - - $response = $this->graphql($this->method, [ - 'code' => $singleUse, - 'account' => $publicKey, - 'signature' => '', - ], true); - - $this->assertArraySubset(['code' => ['The code is invalid.']], $response['error']); - } - public function test_it_can_claim_beam_job_with_idempotency_key(): void { $data = [ @@ -643,7 +590,7 @@ protected function genericClaimTest(CryptoSignatureType $type = CryptoSignatureT ]); $this->assertNotEmpty($response['message']); if (! $singleUseCode) { - $this->assertEquals(1, DB::table('beam_scans')->where('beam_id', $this->beam->id)->count()); + $this->assertEquals(1, $this->beam->scans()->count()); } $message = $response['message']['message']; diff --git a/tests/Feature/GraphQL/Mutations/CreateBeamTest.php b/tests/Feature/GraphQL/Mutations/CreateBeamTest.php index b726032..0c80ccc 100644 --- a/tests/Feature/GraphQL/Mutations/CreateBeamTest.php +++ b/tests/Feature/GraphQL/Mutations/CreateBeamTest.php @@ -33,8 +33,6 @@ class CreateBeamTest extends TestCaseGraphQL public function test_it_can_create_beam_with_transfer_token(): void { $this->genericTestCreateBeam(BeamType::TRANSFER_TOKEN, 1); - - $this->genericTestCreateBeamPack(BeamType::TRANSFER_TOKEN, 1); } /** @@ -48,6 +46,7 @@ public function test_it_can_create_beam_with_file_upload(): void ['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]]] )); $this->assertNotEmpty($response); + Event::assertDispatched(BeamCreated::class); $this->assertEquals(10, Cache::get(BeamService::key($response))); @@ -57,24 +56,7 @@ public function test_it_can_create_beam_with_file_upload(): void ['tokens' => [['tokenIdDataUpload' => $file]]] )); $this->assertNotEmpty($response); - Event::assertDispatched(BeamCreated::class); - $this->assertEquals(1, Cache::get(BeamService::key($response))); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', "1\n2..10"); - $response = $this->graphql($this->method, array_merge( - $this->generateBeamPackData(BeamType::MINT_ON_DEMAND), - ['packs' => [['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]]]]] - )); - $this->assertNotEmpty($response); - Event::assertDispatched(BeamCreated::class); - $this->assertEquals(1, Cache::get(BeamService::key($response))); - $file = UploadedFile::fake()->createWithContent('tokens.txt', "{$this->token->token_chain_id}\n{$this->token->token_chain_id}..{$this->token->token_chain_id}"); - $response = $this->graphql($this->method, array_merge( - $this->generateBeamPackData(BeamType::MINT_ON_DEMAND), - ['packs' => [['tokens' => [['tokenIdDataUpload' => $file]]]]] - )); - $this->assertNotEmpty($response); Event::assertDispatched(BeamCreated::class); $this->assertEquals(1, Cache::get(BeamService::key($response))); } @@ -85,8 +67,6 @@ public function test_it_can_create_beam_with_file_upload(): void public function test_it_can_create_beam_with_mint_on_demand(): void { $this->genericTestCreateBeam(BeamType::MINT_ON_DEMAND, random_int(1, 20)); - - $this->genericTestCreateBeamPack(BeamType::MINT_ON_DEMAND, random_int(1, 20)); } /** @@ -97,10 +77,6 @@ public function test_it_can_create_beam_with_single_use_code(): void $this->genericTestCreateBeam(BeamType::MINT_ON_DEMAND, random_int(1, 20), [], [ ['flag' => 'SINGLE_USE'], ]); - - $this->genericTestCreateBeamPack(BeamType::MINT_ON_DEMAND, random_int(1, 20), [], [ - ['flag' => 'SINGLE_USE'], - ]); } /** @@ -113,12 +89,6 @@ public function test_it_can_create_beam_with_attribute_mint_on_demand(): void random_int(1, 20), [['key' => 'key1', 'value' => 'value1'], ['key' => 'key2', 'value' => 'value2']] ); - - $this->genericTestCreateBeamPack( - BeamType::MINT_ON_DEMAND, - random_int(1, 20), - [['key' => 'key1', 'value' => 'value1'], ['key' => 'key2', 'value' => 'value2']] - ); } /** @@ -145,26 +115,6 @@ public function test_it_will_fail_to_create_beam_with_invalid_file_upload(): voi 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload does not exist in the specified collection.'], ], $response['error']); Event::assertNotDispatched(BeamCreated::class); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', '1'); - $response = $this->graphql($this->method, array_merge( - $this->generateBeamPackData(), - ['packs' => [['tokens' => [['tokenIdDataUpload' => $file]]]]] - ), true); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIdDataUpload' => ['The packs.0.tokens.0.tokenIdDataUpload does not exist in the specified collection.'], - ], $response['error']); - Event::assertNotDispatched(BeamCreated::class); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', '1..10'); - $response = $this->graphql($this->method, array_merge( - $this->generateBeamPackData(), - ['tokens' => [['tokenIdDataUpload' => $file]]] - ), true); - $this->assertArraySubset([ - 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload does not exist in the specified collection.'], - ], $response['error']); - Event::assertNotDispatched(BeamCreated::class); } /** @@ -200,31 +150,6 @@ public function test_it_will_fail_with_token_exist_in_beam(): void $this->assertArraySubset([ 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload already exist in beam.'], ], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge( - $data = $this->generateBeamPackData(BeamType::TRANSFER_TOKEN), - ['packs' => [['tokens' => [['tokenIds' => [$claim->token_chain_id], 'type' => BeamType::TRANSFER_TOKEN->name]]]]] - ), - true - ); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIds' => ['The packs.0.tokens.0.tokenIds already exist in beam.'], - ], $response['error']); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', $this->token->token_chain_id); - $response = $this->graphql( - $this->method, - array_merge( - $data, - ['packs' => [['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::TRANSFER_TOKEN->name]]]]] - ), - true - ); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIdDataUpload' => ['The packs.0.tokens.0.tokenIdDataUpload already exist in beam.'], - ], $response['error']); } /** @@ -246,21 +171,6 @@ public function test_it_will_fail_with_max_length_attribute_mint_on_demand(): vo 'tokens.0.attributes.0.key' => ['The tokens.0.attributes.0.key field must not be greater than 255 characters.'], 'tokens.0.attributes.0.value' => ['The tokens.0.attributes.0.value field must not be greater than 1000 characters.'], ], $response['error']); - - $response = $this->graphql( - $this->method, - $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - random_int(1, 20), - [['key' => Str::random(256), 'value' => Str::random(1001)]] - ), - true - ); - - $this->assertArraySubset([ - 'packs.0.tokens.0.attributes.0.key' => ['The packs.0.tokens.0.attributes.0.key field must not be greater than 255 characters.'], - 'packs.0.tokens.0.attributes.0.value' => ['The packs.0.tokens.0.attributes.0.value field must not be greater than 1000 characters.'], - ], $response['error']); } /** @@ -276,6 +186,7 @@ public function test_it_will_fail_with_empty_params(): void ['message' => 'Variable "$start" of required type "DateTime!" was not provided.'], ['message' => 'Variable "$end" of required type "DateTime!" was not provided.'], ['message' => 'Variable "$collectionId" of required type "BigInt!" was not provided.'], + ['message' => 'Variable "$tokens" of required type "[ClaimToken!]!" was not provided.'], ], $response['errors']); } @@ -311,24 +222,7 @@ public function test_it_will_fail_with_empty_token_ids(): void ['tokens' => []] ), true); - $this->assertArraySubset(['tokens' => ['The tokens field is required when packs is not present.']], $response['error']); - - $response = $this->graphql($this->method, array_merge( - $this->generateBeamData(), - ['packs' => []] - ), true); - - $this->assertArraySubset(['packs' => ['The packs field must have at least 1 items.']], $response['error']); - - $response = $this->graphql($this->method, array_merge( - $this->generateBeamData(), - ['packs' => [], 'tokens' => []] - ), true); - - $this->assertArraySubset([ - 'tokens' => ['The tokens field is required when packs is not present.'], - 'packs' => ['The packs field is required when tokens is not present.'], - ], $response['error']); + $this->assertArraySubset(['tokens' => ['The tokens field must have at least 1 items.']], $response['error']); } /** @@ -403,64 +297,6 @@ public function test_it_will_fail_with_invalid_parameters(): void true ); $this->assertArraySubset(['tokens' => ['There are some duplicate token IDs supplied in the data.']], $response['error']); - - - - $data = $this->generateBeamPackData(); - $response = $this->graphql( - $this->method, - array_merge($data, ['packs' => [['tokens' => [['tokenIds' => '1']]]]]), - true - ); - $this->assertArraySubset(['packs.0.tokens.0.tokenIds' => ['The packs.0.tokens.0.tokenIds does not exist in the specified collection.']], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge($data, ['packs' => [['tokens' => [['tokenIds' => '1..10']]]]]), - true - ); - $this->assertArraySubset(['packs.0.tokens.0.tokenIds' => ['The packs.0.tokens.0.tokenIds does not exist in the specified collection.']], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge($data, ['packs' => [['tokens' => [['tokenIds' => '1'], ['tokenIds' => '1']]]]]), - true - ); - $this->assertArraySubset(['packs.0.tokens' => ['There are some duplicate token IDs supplied in the data.']], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge($data, ['packs' => [['tokens' => [['tokenIds' => '1'], ['tokenIds' => '1..10']]]]]), - true - ); - $this->assertArraySubset(['packs.0.tokens' => ['There are some duplicate token IDs supplied in the data.']], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge($data, ['packs' => [['tokens' => [['tokenIds' => '1..10'], ['tokenIds' => '1']]]]]), - true - ); - $this->assertArraySubset(['packs.0.tokens' => ['There are some duplicate token IDs supplied in the data.']], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge($data, ['packs' => [['tokens' => [['tokenIds' => '1..10'], ['tokenIds' => '5..10']]]]]), - true - ); - $this->assertArraySubset(['packs.0.tokens' => ['There are some duplicate token IDs supplied in the data.']], $response['error']); - - $response = $this->graphql( - $this->method, - array_merge($data, [ - 'packs' => [['tokens' => [['tokenIds' => '1..10']]]], - 'tokens' => [['tokenIds' => '1..10']], - ]), - true - ); - $this->assertArraySubset([ - 'tokens' => ['The tokens field prohibits packs from being present.'], - 'packs' => ['The packs field prohibits tokens from being present.'], - ], $response['error']); } /** @@ -477,13 +313,29 @@ public function test_it_will_fail_with_invalid_ownership(): void $this->assertArraySubset(['collectionId' => ['The collection id provided is not owned by you and you are not currently approved to use it.']], $response['error']); } + /** + * Test creating beam with invalid token collection. + */ + public function test_it_will_fail_with_invalid_token_collection(): void + { + $tokenId = $this->token->token_chain_id; + $this->prepareCollectionData(); + + $response = $this->graphql( + $this->method, + array_merge($this->generateBeamData(), ['tokens' => [['tokenIds' => [(string) $tokenId]]]]), + true + ); + $this->assertArraySubset(['tokens.0.tokenIds' => ['The tokens.0.tokenIds does not exist in the specified collection.']], $response['error']); + } + /** * Test creating beam with invalid claimQuantity. */ public function test_it_will_fail_with_invalid_claim_quantity(): void { $this->prepareCollectionData(); - $this->collection->update(['max_token_count' => 0, 'max_token_supply' => 0]); + $this->collection->update(['max_token_count' => 0]); $response = $this->graphql( $this->method, $this->generateBeamData(BeamType::MINT_ON_DEMAND, 10), @@ -502,11 +354,7 @@ public function test_it_will_fail_with_invalid_claim_quantity(): void $this->assertNotEmpty($response); $response = $this->graphql($this->method, $data, true); - $this->assertArraySubset([ - 'tokens.0.tokenQuantityPerClaim' => [ - 'The tokens.0.tokenQuantityPerClaim exceeded the maximum supply limit of 0 for unique tokens for this collection.', - ], - ], $response['error']); + $this->assertArraySubset(['tokens.0.claimQuantity' => ['The token count exceeded the maximum limit of 0 for this collection.']], $response['error']); } /** @@ -536,12 +384,6 @@ public function test_it_will_fail_with_invalid_token_quantity_per_claim(): void ['tokens.0.tokenQuantityPerClaim' => ['The tokens.0.tokenQuantityPerClaim exceeded the maximum supply limit of 0 for unique tokens for this collection.']], $response['error'] ); - - $response = $this->graphql($this->method, $this->generateBeamPackData(), true); - $this->assertArraySubset( - ['packs.0.tokens.0.tokenQuantityPerClaim' => ['The packs.0.tokens.0.tokenQuantityPerClaim exceeded the maximum supply limit of 0 for unique tokens for this collection.']], - $response['error'] - ); } /** @@ -559,19 +401,4 @@ protected function genericTestCreateBeam(BeamType $type = BeamType::MINT_ON_DEMA $tokenIds = $this->expandRanges(array_column($data['tokens'], 'tokenIds')[0]); $this->assertEquals(count($tokenIds) * $count, Cache::get(BeamService::key($response))); } - - /** - * Generic test for create beam pack. - */ - protected function genericTestCreateBeamPack(BeamType $type = BeamType::MINT_ON_DEMAND, int $count = 1, array $attributes = [], array $singleUse = []): void - { - $this->truncateBeamTables(); - - $response = $this->graphql($this->method, $data = $this->generateBeamPackData($type, $count, $attributes, $singleUse)); - - $this->assertNotEmpty($response); - - Event::assertDispatched(BeamCreated::class); - $this->assertEquals($count, Cache::get(BeamService::key($response))); - } } diff --git a/tests/Feature/GraphQL/Mutations/ExpireSingleUseCodesTest.php b/tests/Feature/GraphQL/Mutations/ExpireSingleUseCodesTest.php index 7747041..613ce83 100644 --- a/tests/Feature/GraphQL/Mutations/ExpireSingleUseCodesTest.php +++ b/tests/Feature/GraphQL/Mutations/ExpireSingleUseCodesTest.php @@ -6,7 +6,6 @@ use Enjin\Platform\Beam\Tests\Feature\GraphQL\TestCaseGraphQL; use Enjin\Platform\Beam\Tests\Feature\Traits\CreateBeamData; use Enjin\Platform\Beam\Tests\Feature\Traits\SeedBeamData; -use Faker\Generator; use Illuminate\Support\Arr; class ExpireSingleUseCodesTest extends TestCaseGraphQL @@ -43,54 +42,6 @@ public function test_it_can_expire_single_use_codes(): void $this->assertTrue($response); } - public function test_it_can_expire_single_use_codes_beam_pack(): void - { - $this->truncateBeamTables(); - - $code = $this->graphql('CreateBeam', $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - 1, - [], - [['flag' => 'SINGLE_USE']], - )); - $this->assertNotEmpty($code); - - $singleUseCodes = $this->graphql('GetSingleUseCodes', ['code' => $code]); - $this->assertNotEmpty($singleUseCodes['totalCount']); - - $response = $this->graphql($this->method, [ - 'codes' => [Arr::get($singleUseCodes, 'edges.0.node.code')], - ]); - $this->assertTrue($response); - } - - public function test_it_cannot_claim_expire_single_use_codes_beam_pack(): void - { - $this->truncateBeamTables(); - - $code = $this->graphql('CreateBeam', $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - 1, - [], - [['flag' => 'SINGLE_USE']], - )); - $this->assertNotEmpty($code); - - $singleUseCodes = $this->graphql('GetSingleUseCodes', ['code' => $code]); - $this->assertNotEmpty($singleUseCodes['totalCount']); - - $response = $this->graphql($this->method, [ - 'codes' => [Arr::get($singleUseCodes, 'edges.0.node.code')], - ]); - $this->assertTrue($response); - - $response = $this->graphql('ClaimBeam', [ - 'code' => Arr::get($singleUseCodes, 'edges.0.node.code'), - 'account' => app(Generator::class)->public_key(), - ], true); - - } - /** * Test get single use beam with invalid claims. */ diff --git a/tests/Feature/GraphQL/Mutations/RemoveTokensTest.php b/tests/Feature/GraphQL/Mutations/RemoveTokensTest.php index 524a9ea..d7d6ce5 100644 --- a/tests/Feature/GraphQL/Mutations/RemoveTokensTest.php +++ b/tests/Feature/GraphQL/Mutations/RemoveTokensTest.php @@ -31,7 +31,7 @@ public function test_it_can_remove_tokens(): void $this->assertTrue($response); Event::assertDispatched(TokensRemoved::class); - + Event::fake(); $claim = $this->claims->shift(); $response = $this->graphql($this->method, [ 'code' => $this->beam->code, @@ -39,37 +39,6 @@ public function test_it_can_remove_tokens(): void ]); $this->assertTrue($response); Event::assertDispatched(TokensRemoved::class); - - $this->seedBeamPack(3); - $claim = $this->claims->shift(); - $response = $this->graphql($this->method, [ - 'code' => $this->beam->code, - 'packs' => [ - ['id' => $claim->beam_pack_id, 'tokenIds' => [$claim->token_chain_id]], - ], - ]); - $this->assertTrue($response); - Event::assertDispatched(TokensRemoved::class); - - $claim = $this->claims->shift(); - $response = $this->graphql($this->method, [ - 'code' => $this->beam->code, - 'packs' => [ - ['id' => $claim->beam_pack_id, 'tokenIds' => ["{$claim->token_chain_id}..{$claim->token_chain_id}"]], - ], - ]); - $this->assertTrue($response); - Event::assertDispatched(TokensRemoved::class); - - $claim = $this->claims->shift(); - $response = $this->graphql($this->method, [ - 'code' => $this->beam->code, - 'packs' => [ - ['id' => $claim->beam_pack_id], - ], - ]); - $this->assertTrue($response); - Event::assertDispatched(TokensRemoved::class); } /** @@ -101,7 +70,7 @@ public function test_it_will_fail_with_invalid_paramters(): void 'tokenIds' => null, ], true); $this->assertEquals( - ['tokenIds' => ['The token ids field is required.']], + 'Variable "$tokenIds" of non-null type "[IntegerRangeString!]!" must not be null.', $response['error'] ); @@ -110,7 +79,7 @@ public function test_it_will_fail_with_invalid_paramters(): void 'tokenIds' => [], ], true); $this->assertArraySubset( - ['tokenIds' => ['The token ids field is required.']], + ['tokenIds' => ['The token ids field must have at least 1 items.']], $response['error'] ); @@ -171,37 +140,5 @@ public function test_it_will_fail_with_invalid_paramters(): void ['tokenIds.0' => ["The tokenIds.0 doesn't exist in beam."]], $response['error'] ); - - $this->seedBeamPack(); - $response = $this->graphql($this->method, [ - 'code' => $this->beam->code, - 'packs' => [], - ], true); - $this->assertArraySubset( - ['packs' => ['The packs field is required.']], - $response['error'] - ); - - $response = $this->graphql($this->method, [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => null]], - ], true); - $this->assertEquals( - 'Variable "$packs" got invalid value {"tokens":null} at "packs[0]"; Field "id" of required type "Int!" was not provided.', - $response['error'] - ); - - $response = $this->graphql($this->method, [ - 'code' => $this->beam->code, - 'packs' => [['id' => 100000, 'tokenIds' => ['10000']]], - ], true); - $this->assertArraySubset( - [ - 'packs.0.id' => ['The packs.0.id doesn\'t exist in beam.'], - 'packs.0.tokenIds.0' => ['The packs.0.tokenIds.0 doesn\'t exist in beam pack.'], - ], - $response['error'] - ); - } } diff --git a/tests/Feature/GraphQL/Mutations/UpdateBeamTest.php b/tests/Feature/GraphQL/Mutations/UpdateBeamTest.php index 30a759e..9fd71b6 100644 --- a/tests/Feature/GraphQL/Mutations/UpdateBeamTest.php +++ b/tests/Feature/GraphQL/Mutations/UpdateBeamTest.php @@ -10,7 +10,6 @@ use Enjin\Platform\Beam\Rules\Traits\IntegerRange; use Enjin\Platform\Beam\Services\BeamService; use Enjin\Platform\Beam\Tests\Feature\GraphQL\TestCaseGraphQL; -use Enjin\Platform\Beam\Tests\Feature\Traits\CreateBeamData; use Enjin\Platform\Beam\Tests\Feature\Traits\SeedBeamData; use Enjin\Platform\Enums\Substrate\TokenMintCapType; use Enjin\Platform\GraphQL\Types\Scalars\Traits\HasIntegerRanges; @@ -23,10 +22,6 @@ class UpdateBeamTest extends TestCaseGraphQL { - use CreateBeamData { - generateBeamData as protected parentGenerateBeamData; - generateBeamPackData as protected parentGenerateBeamPackData; - } use HasIntegerRanges; use IntegerRange; use SeedBeamData; @@ -53,12 +48,11 @@ public function test_it_can_update_beam(): void Event::fake(); $response = $this->graphql($this->method, $updates = $this->generateBeamData(BeamType::MINT_ON_DEMAND)); $this->assertTrue($response); - Event::assertDispatched(BeamUpdated::class); Event::assertDispatched(TokensAdded::class); $this->beam->refresh(); $this->assertEquals( - $expected = Arr::except($updates, ['tokens', 'collectionId']), + $expected = Arr::except($updates, ['tokens']), $this->beam->only(array_keys($expected)) ); @@ -74,16 +68,6 @@ public function test_it_can_update_beam(): void }, 10); }); $this->assertEquals($totalClaims, Cache::get(BeamService::key($this->beam->code))); - - $this->seedBeamPack(1); - $response = $this->graphql( - $this->method, - $updates = $this->generateBeamPackData(BeamType::MINT_ON_DEMAND, $count = random_int(1, 10)) - ); - $this->assertTrue($response); - Event::assertDispatched(BeamUpdated::class); - Event::assertDispatched(TokensAdded::class); - $this->assertEquals(1 + $count, Cache::get(BeamService::key($this->beam->code))); } /** @@ -104,23 +88,6 @@ public function test_it_can_update_beam_with_attributes(): void ) ); $this->assertTrue($response); - Event::assertDispatched(BeamUpdated::class); - Event::assertDispatched(TokensAdded::class); - - $this->seedBeamPack(1); - $response = $this->graphql( - $this->method, - $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - 1, - [ - ['key' => 'test', 'value' => 'test'], - ['key' => 'test2', 'value' => 'test2'], - ] - ) - ); - $this->assertTrue($response); - Event::assertDispatched(BeamUpdated::class); Event::assertDispatched(TokensAdded::class); } @@ -129,7 +96,6 @@ public function test_it_can_update_beam_with_attributes(): void */ public function test_it_can_update_beam_with_file_upload(): void { - Event::fake(); $file = UploadedFile::fake()->createWithContent('tokens.txt', "1\n2..10"); $response = $this->graphql($this->method, array_merge( $this->generateBeamData(BeamType::MINT_ON_DEMAND), @@ -137,7 +103,6 @@ public function test_it_can_update_beam_with_file_upload(): void )); $this->assertNotEmpty($response); Event::assertDispatched(BeamUpdated::class); - Event::assertDispatched(TokensAdded::class); $file = UploadedFile::fake()->createWithContent('tokens.txt', "{$this->token->token_chain_id}\n{$this->token->token_chain_id}..{$this->token->token_chain_id}"); $response = $this->graphql($this->method, array_merge( @@ -146,26 +111,6 @@ public function test_it_can_update_beam_with_file_upload(): void )); $this->assertNotEmpty($response); Event::assertDispatched(BeamUpdated::class); - Event::assertDispatched(TokensAdded::class); - - $this->seedBeamPack(1); - $file = UploadedFile::fake()->createWithContent('tokens.txt', "1\n2..10"); - $response = $this->graphql($this->method, array_merge( - $data = Arr::except($this->generateBeamPackData(BeamType::MINT_ON_DEMAND), ['start']), - ['packs' => [['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]]]]] - )); - $this->assertNotEmpty($response); - Event::assertDispatched(BeamUpdated::class); - Event::assertDispatched(TokensAdded::class); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', "{$this->token->token_chain_id}\n{$this->token->token_chain_id}..{$this->token->token_chain_id}"); - $response = $this->graphql($this->method, array_merge( - $data, - ['packs' => [['tokens' => [['tokenIdDataUpload' => $file]]]]] - )); - $this->assertNotEmpty($response); - Event::assertDispatched(BeamUpdated::class); - Event::assertDispatched(TokensAdded::class); } /** @@ -201,36 +146,6 @@ public function test_it_will_fail_with_token_exist_in_beam(): void $this->assertArraySubset([ 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload already exist in beam.'], ], $response['error']); - - - $this->seedBeamPack(); - $claim = $this->claims->first(); - $claim->forceFill(['token_chain_id' => $this->token->token_chain_id])->save(); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [['tokenIds' => [$claim->token_chain_id], 'type' => BeamType::TRANSFER_TOKEN->name]]]], - ], - true - ); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIds' => ['The packs.0.tokens.0.tokenIds already exist in beam.'], - ], $response['error']); - - $file = UploadedFile::fake()->createWithContent('tokens.txt', $claim->token_chain_id); - $response = $this->graphql( - $this->method, - [ - 'code' => $this->beam->code, - 'packs' => [['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::TRANSFER_TOKEN->name]]]], - ], - true - ); - $this->assertArraySubset([ - 'packs.0.tokens.0.tokenIdDataUpload' => ['The packs.0.tokens.0.tokenIdDataUpload already exist in beam.'], - ], $response['error']); - } /** @@ -238,6 +153,26 @@ public function test_it_will_fail_with_token_exist_in_beam(): void */ public function test_it_will_fail_to_create_beam_with_invalid_file_upload(): void { + $file = UploadedFile::fake()->createWithContent('tokens.txt', $this->token->token_chain_id); + $response = $this->graphql($this->method, array_merge( + $this->generateBeamData(), + ['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]]] + ), true); + $this->assertArraySubset([ + 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload exists in the specified collection.'], + ], $response['error']); + Event::assertNotDispatched(BeamUpdated::class); + + $file = UploadedFile::fake()->createWithContent('tokens.txt', "{$this->token->token_chain_id}..{$this->token->token_chain_id}"); + $response = $this->graphql($this->method, array_merge( + $this->generateBeamData(), + ['tokens' => [['tokenIdDataUpload' => $file, 'type' => BeamType::MINT_ON_DEMAND->name]]] + ), true); + $this->assertArraySubset([ + 'tokens.0.tokenIdDataUpload' => ['The tokens.0.tokenIdDataUpload exists in the specified collection.'], + ], $response['error']); + Event::assertNotDispatched(BeamUpdated::class); + $file = UploadedFile::fake()->createWithContent('tokens.txt', '1'); $response = $this->graphql($this->method, array_merge( $this->generateBeamData(), @@ -316,7 +251,7 @@ public function test_it_will_fail_existing_tokens(): void ); $response = $this->graphql($this->method, $updates, true); $this->assertArraySubset( - ['tokens.0.tokenIds' => ['The tokens.0.tokenIds already exist in beam.']], + ['tokens.0.tokenIds' => ['The tokens.0.tokenIds exists in the specified collection.']], $response['error'] ); } @@ -497,40 +432,27 @@ public function test_it_will_fail_with_invalid_tokens(): void ); } + /** + * Generate beam data. + */ protected function generateBeamData(BeamType $type = BeamType::TRANSFER_TOKEN, int $count = 1, array $attributes = [], array $singleUse = []): array { - return $this->parentGenerateBeamData( - $type, - $count, - $attributes, - $singleUse, - [ - 'code' => $this->beam->code, - 'name' => 'Updated', - 'description' => 'Updated', - 'collectionId' => $this->beam->collection_chain_id, - ] - ); - } - - protected function generateBeamPackData( - BeamType $type = BeamType::TRANSFER_TOKEN, - int $count = 1, - array $attributes = [], - array $flags = [], - array $extra = [] - ): array { - return $this->parentGenerateBeamPackData( - $type, - $count, - $attributes, - $flags, - [ - 'code' => $this->beam->code, - 'name' => 'Updated', - 'description' => 'Updated', - 'collectionId' => $this->beam->collection_chain_id, - ] - ); + return [ + 'code' => $this->beam->code, + 'name' => 'Updated', + 'description' => 'Updated', + 'image' => fake()->url(), + 'start' => Carbon::now()->addDays(10)->toDateTimeString(), + 'end' => Carbon::now()->addDays(20)->toDateTimeString(), + 'tokens' => [[ + 'type' => $type->name, + 'tokenIds' => $type == BeamType::TRANSFER_TOKEN + ? [(string) $this->token->token_chain_id] + : [(string) fake()->unique()->numberBetween(100, 10000), fake()->unique()->numberBetween(0, 10) . '..' . fake()->unique()->numberBetween(11, 20)], + 'tokenQuantityPerClaim' => random_int(1, $count), + 'claimQuantity' => $count, + 'attributes' => $attributes ?: null, + ]], + ]; } } diff --git a/tests/Feature/GraphQL/Queries/GetSingleUseCodesTest.php b/tests/Feature/GraphQL/Queries/GetSingleUseCodesTest.php index b5ca6e4..cdc9eb1 100644 --- a/tests/Feature/GraphQL/Queries/GetSingleUseCodesTest.php +++ b/tests/Feature/GraphQL/Queries/GetSingleUseCodesTest.php @@ -29,16 +29,6 @@ public function test_it_can_get_single_use_codes(): void $response = $this->graphql($this->method, ['code' => $code]); $this->assertNotEmpty($response['totalCount']); - - $code = $this->graphql('CreateBeam', $this->generateBeamPackData( - BeamType::MINT_ON_DEMAND, - 10, - [], - [['flag' => 'SINGLE_USE']] - )); - - $response = $this->graphql($this->method, ['code' => $code]); - $this->assertNotEmpty($response['totalCount']); } /** diff --git a/tests/Feature/GraphQL/Resources/AddTokens.graphql b/tests/Feature/GraphQL/Resources/AddTokens.graphql index fffeb22..3d0b5c5 100644 --- a/tests/Feature/GraphQL/Resources/AddTokens.graphql +++ b/tests/Feature/GraphQL/Resources/AddTokens.graphql @@ -1,7 +1,9 @@ mutation AddTokens( $code: String! - $tokens: [ClaimToken!] - $packs: [BeamPackInput!] + $tokens: [ClaimToken!]! ) { - AddTokens(code: $code, tokens: $tokens, packs: $packs) + AddTokens( + code: $code + tokens: $tokens + ) } diff --git a/tests/Feature/GraphQL/Resources/CreateBeam.graphql b/tests/Feature/GraphQL/Resources/CreateBeam.graphql index 3e9f5f9..0fc6927 100644 --- a/tests/Feature/GraphQL/Resources/CreateBeam.graphql +++ b/tests/Feature/GraphQL/Resources/CreateBeam.graphql @@ -5,8 +5,7 @@ mutation CreateBeam( $start: DateTime! $end: DateTime! $collectionId: BigInt! - $tokens: [ClaimToken!] - $packs: [BeamPackInput!] + $tokens: [ClaimToken!]! $flags: [BeamFlagInputType!] ) { CreateBeam( @@ -17,7 +16,6 @@ mutation CreateBeam( end: $end collectionId: $collectionId tokens: $tokens - packs: $packs flags: $flags ) } diff --git a/tests/Feature/GraphQL/Resources/GetSingleUseCodes.graphql b/tests/Feature/GraphQL/Resources/GetSingleUseCodes.graphql index 03c6144..d47289a 100644 --- a/tests/Feature/GraphQL/Resources/GetSingleUseCodes.graphql +++ b/tests/Feature/GraphQL/Resources/GetSingleUseCodes.graphql @@ -3,20 +3,10 @@ query GetSingleUseCodes($code: String!) { edges { cursor node { - ... on BeamClaim { - code - qr { - url - payload - } - } - - ... on BeamPack { - code - qr { - url - payload - } + code + qr { + url + payload } } } diff --git a/tests/Feature/GraphQL/Resources/RemoveTokens.graphql b/tests/Feature/GraphQL/Resources/RemoveTokens.graphql index 3dddb64..a1a550f 100644 --- a/tests/Feature/GraphQL/Resources/RemoveTokens.graphql +++ b/tests/Feature/GraphQL/Resources/RemoveTokens.graphql @@ -1,7 +1,3 @@ -mutation RemoveTokens( - $code: String! - $tokenIds: [IntegerRangeString!] - $packs: [RemoveBeamPack!] -) { - RemoveTokens(code: $code, tokenIds: $tokenIds, packs: $packs) +mutation RemoveTokens($code: String!, $tokenIds: [IntegerRangeString!]!) { + RemoveTokens(code: $code, tokenIds: $tokenIds) } diff --git a/tests/Feature/GraphQL/Resources/UpdateBeam.graphql b/tests/Feature/GraphQL/Resources/UpdateBeam.graphql index 6e6a1c2..f28311f 100644 --- a/tests/Feature/GraphQL/Resources/UpdateBeam.graphql +++ b/tests/Feature/GraphQL/Resources/UpdateBeam.graphql @@ -7,7 +7,6 @@ mutation UpdateBeam( $end: DateTime $flags: [BeamFlagInputType!] $tokens: [ClaimToken!] - $packs: [BeamPackInput!] ) { UpdateBeam( code: $code @@ -18,6 +17,5 @@ mutation UpdateBeam( end: $end flags: $flags tokens: $tokens - packs: $packs ) } diff --git a/tests/Feature/Traits/CreateBeamData.php b/tests/Feature/Traits/CreateBeamData.php index 4b21958..35e2b1f 100644 --- a/tests/Feature/Traits/CreateBeamData.php +++ b/tests/Feature/Traits/CreateBeamData.php @@ -4,27 +4,20 @@ use Carbon\Carbon; use Enjin\Platform\Beam\Enums\BeamType; -use Illuminate\Support\Arr; -use Illuminate\Support\Collection; trait CreateBeamData { /** * Generate beam data. */ - protected function generateBeamData( - BeamType $type = BeamType::TRANSFER_TOKEN, - int $count = 1, - array $attributes = [], - array $singleUse = [], - array $extra = [], - ): array { + protected function generateBeamData(BeamType $type = BeamType::TRANSFER_TOKEN, int $count = 1, array $attributes = [], array $singleUse = []): array + { return [ 'name' => fake()->name(), 'description' => fake()->word(), 'image' => fake()->url(), - 'start' => Carbon::now()->addDays(Arr::get($extra, 'code') ? 20 : 0)->toDateTimeString(), - 'end' => Carbon::now()->addDays(random_int(100, 1000))->toDateTimeString(), + 'start' => Carbon::now()->toDateTimeString(), + 'end' => Carbon::now()->addDays(random_int(1, 1000))->toDateTimeString(), 'collectionId' => $this->collection->collection_chain_id, 'flags' => $singleUse, 'tokens' => [[ @@ -36,39 +29,6 @@ protected function generateBeamData( 'claimQuantity' => $count, 'attributes' => $attributes ?: null, ]], - ...$extra, ]; } - - /** - * Generate beam pack data. - */ - protected function generateBeamPackData( - BeamType $type = BeamType::TRANSFER_TOKEN, - int $count = 1, - array $attributes = [], - array $flags = [], - array $extra = [] - ): array { - $data = [ - 'name' => fake()->name(), - 'description' => fake()->word(), - 'image' => fake()->url(), - 'start' => Carbon::now()->toDateTimeString(), - 'end' => Carbon::now()->addDays(random_int(1, 1000))->toDateTimeString(), - 'collectionId' => $this->collection->collection_chain_id, - 'flags' => $flags, - 'packs' => Collection::times($count, fn () => ['tokens' => [[ - 'type' => $type->name, - 'tokenIds' => $type == BeamType::TRANSFER_TOKEN - ? [(string) $this->token->token_chain_id] - : [(string) fake()->numberBetween(100, 1000), fake()->numberBetween(0, 10) . '..' . fake()->numberBetween(11, 20)], - 'tokenQuantityPerClaim' => random_int(1, $count), - 'attributes' => $attributes ?: null, - ]]])->all(), - ...$extra, - ]; - - return $data; - } } diff --git a/tests/Feature/Traits/SeedBeamData.php b/tests/Feature/Traits/SeedBeamData.php index e88780d..7fa09d6 100644 --- a/tests/Feature/Traits/SeedBeamData.php +++ b/tests/Feature/Traits/SeedBeamData.php @@ -7,7 +7,6 @@ use Enjin\Platform\Beam\Models\Beam; use Enjin\Platform\Beam\Models\BeamBatch; use Enjin\Platform\Beam\Models\BeamClaim; -use Enjin\Platform\Beam\Models\BeamPack; use Enjin\Platform\Beam\Models\BeamScan; use Enjin\Platform\Beam\Services\BeamService; use Illuminate\Database\Eloquent\Model; @@ -53,37 +52,6 @@ public function seedBeam(?int $claimsCount = null, bool $isClaimed = false, ?Bea Cache::remember(BeamService::key($this->beam->code), 3600, fn () => count($this->claims)); } - /** - * Seed beam claim data. - */ - public function seedBeamPack(?int $claimsCount = null, ?BeamType $type = null, array $beam = []): void - { - - $this->beam = Beam::factory([ - 'collection_chain_id' => $this->collection->collection_chain_id, - 'is_pack' => true, - ...$beam, - ])->create(); - - $this->claims = collect(); - Collection::times($claimsCount ?: 1, function () use ($type) { - $this->claims->push( - BeamClaim::factory() - ->create([ - 'collection_id' => $this->collection->id, - 'wallet_public_key' => null, - 'claimed_at' => null, - 'state' => null, - 'beam_id' => $this->beam->id, - 'beam_pack_id' => BeamPack::factory(['beam_id' => $this->beam])->create()->id, - ...($type ? ['type' => $type->name] : []), - ]) - ); - }); - - Cache::remember(BeamService::key($this->beam->code), 3600, fn () => $claimsCount); - } - /** * Claim all beam. */