generated from thegrind/laravel-dockerized
251 lines
7.9 KiB
PHP
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();
|
|
}); |