artisan('arcadia:client:regenerate-secret', ['identifier' => $invalidIdentifier]) // THEN ->expectsOutput("Invalid client identifier '{$invalidIdentifier}'. Expected a valid client identifier.") ->assertFailed(); }); it('errors when client does not exist', function (): void { // GIVEN /** @var \Tests\TestCase $this */ $nonExistentIdentifier = 'arcadia_id_' . str_repeat('f', 32); // WHEN $this->artisan('arcadia:client:regenerate-secret', ['identifier' => $nonExistentIdentifier]) // THEN ->expectsOutput("Client '{$nonExistentIdentifier}' not found.") ->assertFailed(); }); it('regenerates secret when confirmed with argument provided', function (): void { // GIVEN /** @var \Tests\TestCase $this */ $identifier = 'arcadia_id_' . str_repeat('a', 32); $oldSecret = 'arcadia_sec_' . str_repeat('1', 86); $client = ApiClient::factory()->create([ 'id' => (string) Uuid::uuid7(), 'name' => 'Production Gateway', 'slug' => 'production-gateway', 'identifier' => $identifier, 'secret' => $oldSecret, 'is_active' => true, ]); // WHEN $this->artisan('arcadia:client:regenerate-secret', ['identifier' => $identifier]) // THEN ->expectsConfirmation('Do you want to proceed?', 'yes') ->expectsOutputToContain("Secret for client '{$identifier}' regenerated successfully.") ->expectsOutputToContain('Store the new secret securely') ->assertSuccessful(); $client->refresh(); expect($client->secret->value)->not->toBe($oldSecret) ->and((string) $client->secret->value)->toStartWith('arcadia_sec_'); }); it('aborts and keeps old secret when confirmation is declined', function (): void { // GIVEN /** @var \Tests\TestCase $this */ $identifier = 'arcadia_id_' . str_repeat('b', 32); $oldSecret = 'arcadia_sec_' . str_repeat('2', 86); $client = ApiClient::factory()->create([ 'id' => (string) Uuid::uuid7(), 'name' => 'Staging Gateway', 'slug' => 'staging-gateway', 'identifier' => $identifier, 'secret' => $oldSecret, 'is_active' => true, ]); // WHEN $this->artisan('arcadia:client:regenerate-secret', ['identifier' => $identifier]) // THEN ->expectsConfirmation('Do you want to proceed?', 'no') ->expectsOutput('Secret regeneration cancelled.') ->assertSuccessful(); $client->refresh(); expect($client->secret->value)->toBe($oldSecret); }); it('interactively prompts and searches client when no argument is provided', function (): void { // GIVEN /** @var \Tests\TestCase $this */ $identifier = 'arcadia_id_' . str_repeat('d', 32); $oldSecret = 'arcadia_sec_' . str_repeat('3', 86); $client = ApiClient::factory()->create([ 'id' => (string) Uuid::uuid7(), 'name' => 'Searchable Client', 'slug' => 'searchable-client', 'identifier' => $identifier, 'secret' => $oldSecret, 'is_active' => true, ]); // WHEN $this->artisan('arcadia:client:regenerate-secret') // THEN ->expectsQuestion('Search client (by name, ID, identifier, or slug):', $identifier) ->expectsChoice('Search client (by name, ID, identifier, or slug):', $identifier, [ $identifier => "Searchable Client (Active) - {$identifier}", ]) ->expectsConfirmation('Do you want to proceed?', 'yes') ->expectsOutputToContain("Secret for client '{$identifier}' regenerated successfully.") ->assertSuccessful(); $client->refresh(); expect($client->secret->value)->not->toBe($oldSecret); }); it('provides autocompletion suggestions for identifier', function (): void { // GIVEN /** @var \Tests\TestCase $this */ ApiClient::query()->delete(); ApiClient::factory()->create([ 'id' => (string) Uuid::uuid7(), 'name' => 'Alpha Client', 'slug' => 'alpha-client', 'identifier' => 'arcadia_id_' . str_repeat('1', 32), 'secret' => 'arcadia_sec_' . str_repeat('2', 86), 'is_active' => true, ]); ApiClient::factory()->create([ 'id' => (string) Uuid::uuid7(), 'name' => 'Beta Client', 'slug' => 'beta-client', 'identifier' => 'arcadia_id_' . str_repeat('3', 32), 'secret' => 'arcadia_sec_' . str_repeat('4', 86), 'is_active' => false, ]); /** @var RegenerateClientSecretCommand $command */ $command = app(RegenerateClientSecretCommand::class); $tester = new CommandCompletionTester($command); // WHEN $suggestions = $tester->complete(['']); // THEN expect($suggestions) ->toContain('arcadia_id_' . str_repeat('1', 32)) ->toContain('arcadia_id_' . str_repeat('3', 32)); }); });