authentikate/tests/Feature/NewApplicationTest.php
Javier Feliz 81728c1623
Some checks failed
tests / ci (push) Waiting to run
linter / quality (push) Has been cancelled
Bring up test coverage
2025-08-02 17:00:25 -04:00

251 lines
7.9 KiB
PHP

<?php
use App\Livewire\Forms\NewApplication;
use App\Models\Application;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
it('can create a new application with valid data', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', 'Test Application')
->set('redirect_uri', 'https://example.com/callback')
->call('create')
->assertRedirect(route('dashboard'));
$app = Application::where('name', 'Test Application')->first();
expect($app)->not()->toBeNull();
expect($app->name)->toBe('Test Application');
expect($app->redirect_uri)->toBe('https://example.com/callback');
expect($app->client_id)->not()->toBeNull();
expect($app->client_secret)->not()->toBeNull();
expect(strlen($app->client_secret))->toBe(40);
});
it('generates unique client_id and client_secret', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
// Create first application
Livewire::test(NewApplication::class)
->set('name', 'First App')
->set('redirect_uri', 'https://first.com/callback')
->call('create');
// Create second application
Livewire::test(NewApplication::class)
->set('name', 'Second App')
->set('redirect_uri', 'https://second.com/callback')
->call('create');
$apps = Application::all();
expect($apps->count())->toBe(2);
$firstApp = $apps->first();
$secondApp = $apps->last();
expect($firstApp->client_id)->not()->toBe($secondApp->client_id);
expect($firstApp->client_secret)->not()->toBe($secondApp->client_secret);
});
it('validates required name field', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', '')
->set('redirect_uri', 'https://example.com/callback')
->call('create')
->assertHasErrors(['name' => 'required']);
expect(Application::count())->toBe(0);
});
it('validates required redirect_uri field', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', 'Test App')
->set('redirect_uri', '')
->call('create')
->assertHasErrors(['redirect_uri' => 'required']);
expect(Application::count())->toBe(0);
});
it('validates redirect_uri must be a valid URL', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', 'Test App')
->set('redirect_uri', 'not-a-valid-url')
->call('create')
->assertHasErrors(['redirect_uri' => 'url']);
expect(Application::count())->toBe(0);
});
it('accepts various valid URL formats for redirect_uri', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
$validUrls = [
'https://example.com/callback',
'http://localhost:3000/auth',
'https://subdomain.example.com/oauth/callback',
'https://app.example.com:8080/auth/callback'
];
foreach ($validUrls as $index => $url) {
Livewire::test(NewApplication::class)
->set('name', "Test App {$index}")
->set('redirect_uri', $url)
->call('create')
->assertHasNoErrors();
}
expect(Application::count())->toBe(count($validUrls));
});
it('resets form fields after successful creation', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
$component = Livewire::test(NewApplication::class)
->set('name', 'Test Application')
->set('redirect_uri', 'https://example.com/callback')
->call('create');
expect($component->get('name'))->toBe('');
expect($component->get('redirect_uri'))->toBe('');
});
it('prevents non-admin users from creating applications', function () {
$user = User::factory()->create(['is_admin' => false]);
$this->actingAs($user);
// Test the policy directly first
expect($user->can('create', Application::class))->toBe(false);
// Test that Livewire component correctly handles authorization
$response = $this->withoutExceptionHandling();
$this->expectException(\Illuminate\Auth\Access\AuthorizationException::class);
Livewire::test(NewApplication::class)
->set('name', 'Test Application')
->set('redirect_uri', 'https://example.com/callback')
->call('create');
});
it('can be rendered by admin users', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
$component = Livewire::test(NewApplication::class);
$component->assertStatus(200);
expect($component->get('name'))->toBe('');
expect($component->get('redirect_uri'))->toBe('');
});
it('handles special characters in app name', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
$specialName = "My App's & Company's OAuth-2 Service!";
Livewire::test(NewApplication::class)
->set('name', $specialName)
->set('redirect_uri', 'https://example.com/callback')
->call('create')
->assertRedirect(route('dashboard'));
$app = Application::where('name', $specialName)->first();
expect($app)->not()->toBeNull();
expect($app->name)->toBe($specialName);
});
it('validates multiple validation errors at once', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', '')
->set('redirect_uri', 'invalid-url')
->call('create')
->assertHasErrors(['name' => 'required', 'redirect_uri' => 'url']);
expect(Application::count())->toBe(0);
});
it('generates UUID format for client_id', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', 'Test Application')
->set('redirect_uri', 'https://example.com/callback')
->call('create');
$app = Application::first();
// Check UUID format (8-4-4-4-12 characters)
expect($app->client_id)->toMatch('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/');
});
it('generates random string for client_secret with correct length', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', 'Test Application')
->set('redirect_uri', 'https://example.com/callback')
->call('create');
$app = Application::first();
expect(strlen($app->client_secret))->toBe(40);
expect($app->client_secret)->toMatch('/^[A-Za-z0-9]+$/');
});
it('creates application with all required fields populated', function () {
$admin = User::factory()->create(['is_admin' => true]);
$this->actingAs($admin);
Livewire::test(NewApplication::class)
->set('name', 'Complete Test App')
->set('redirect_uri', 'https://complete.example.com/callback')
->call('create');
$app = Application::first();
expect($app->name)->toBe('Complete Test App');
expect($app->redirect_uri)->toBe('https://complete.example.com/callback');
expect($app->client_id)->not()->toBeNull();
expect($app->client_secret)->not()->toBeNull();
expect($app->icon)->toBeNull(); // icon is not set by this form
expect($app->created_at)->not()->toBeNull();
expect($app->updated_at)->not()->toBeNull();
});