admin = User::factory()->admin()->create(); }); // =========================================== // Create Client Tests // =========================================== test('admin can access individual clients index page', function () { $this->actingAs($this->admin) ->get(route('admin.clients.individual.index')) ->assertOk(); }); test('admin can access create individual client page', function () { $this->actingAs($this->admin) ->get(route('admin.clients.individual.create')) ->assertOk(); }); test('admin can create individual client with all valid data', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasNoErrors() ->assertRedirect(route('admin.clients.individual.index')); expect(User::where('email', 'testclient@example.com')->exists())->toBeTrue(); $client = User::where('email', 'testclient@example.com')->first(); expect($client->user_type)->toBe(UserType::Individual); expect($client->status)->toBe(UserStatus::Active); }); test('created client has user_type set to individual', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasNoErrors(); $client = User::where('email', 'testclient@example.com')->first(); expect($client->user_type)->toBe(UserType::Individual); }); test('admin log entry created on successful creation', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasNoErrors(); expect(AdminLog::where('action', 'create') ->where('target_type', 'user') ->where('admin_id', $this->admin->id) ->exists())->toBeTrue(); }); test('cannot create client without required name field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', '') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['full_name' => 'required']); }); test('cannot create client without required email field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', '') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['email' => 'required']); }); test('cannot create client without required national_id field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['national_id' => 'required']); }); test('cannot create client without required phone field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['phone' => 'required']); }); test('cannot create client with invalid email format', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'invalid-email') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['email' => 'email']); }); test('cannot create client with duplicate email', function () { User::factory()->individual()->create(['email' => 'existing@example.com']); $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'existing@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['email' => 'unique']); }); test('cannot create client with duplicate national_id', function () { User::factory()->individual()->create(['national_id' => '123456789']); $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['national_id' => 'unique']); }); test('cannot create client with password less than 8 characters', function () { $this->actingAs($this->admin); Volt::test('admin.clients.individual.create') ->set('full_name', 'Test Client') ->set('email', 'testclient@example.com') ->set('national_id', '123456789') ->set('phone', '+970599123456') ->set('password', 'short') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['password' => 'min']); }); // =========================================== // List View Tests // =========================================== test('index page displays only individual clients', function () { // Create different types of users $individualClient = User::factory()->individual()->create(['full_name' => 'Individual Test']); $companyClient = User::factory()->company()->create(['full_name' => 'Company Test']); $adminUser = User::factory()->admin()->create(['full_name' => 'Admin Test']); $this->actingAs($this->admin); Volt::test('admin.clients.individual.index') ->assertSee('Individual Test') ->assertDontSee('Company Test') ->assertDontSee('Admin Test'); }); test('clients sorted by created_at desc by default', function () { $oldClient = User::factory()->individual()->create([ 'full_name' => 'Old Client', 'created_at' => now()->subDays(10), ]); $newClient = User::factory()->individual()->create([ 'full_name' => 'New Client', 'created_at' => now(), ]); $this->actingAs($this->admin); $response = Volt::test('admin.clients.individual.index'); // The new client should appear before the old client $response->assertSeeInOrder(['New Client', 'Old Client']); }); // =========================================== // Search & Filter Tests // =========================================== test('can search clients by name (partial match)', function () { User::factory()->individual()->create(['full_name' => 'John Doe']); User::factory()->individual()->create(['full_name' => 'Jane Smith']); $this->actingAs($this->admin); Volt::test('admin.clients.individual.index') ->set('search', 'John') ->assertSee('John Doe') ->assertDontSee('Jane Smith'); }); test('can search clients by email (partial match)', function () { User::factory()->individual()->create([ 'full_name' => 'John Doe', 'email' => 'john@example.com', ]); User::factory()->individual()->create([ 'full_name' => 'Jane Smith', 'email' => 'jane@example.com', ]); $this->actingAs($this->admin); Volt::test('admin.clients.individual.index') ->set('search', 'john@') ->assertSee('John Doe') ->assertDontSee('Jane Smith'); }); test('can search clients by national_id (partial match)', function () { User::factory()->individual()->create([ 'full_name' => 'John Doe', 'national_id' => '111222333', ]); User::factory()->individual()->create([ 'full_name' => 'Jane Smith', 'national_id' => '444555666', ]); $this->actingAs($this->admin); Volt::test('admin.clients.individual.index') ->set('search', '111222') ->assertSee('John Doe') ->assertDontSee('Jane Smith'); }); test('can filter clients by active status', function () { User::factory()->individual()->create([ 'full_name' => 'Active Client', 'status' => UserStatus::Active, ]); User::factory()->individual()->deactivated()->create([ 'full_name' => 'Deactivated Client', ]); $this->actingAs($this->admin); Volt::test('admin.clients.individual.index') ->set('statusFilter', 'active') ->assertSee('Active Client') ->assertDontSee('Deactivated Client'); }); test('can filter clients by deactivated status', function () { User::factory()->individual()->create([ 'full_name' => 'Active Client', 'status' => UserStatus::Active, ]); User::factory()->individual()->deactivated()->create([ 'full_name' => 'Deactivated Client', ]); $this->actingAs($this->admin); Volt::test('admin.clients.individual.index') ->set('statusFilter', 'deactivated') ->assertDontSee('Active Client') ->assertSee('Deactivated Client'); }); test('clear filters resets search and filter', function () { User::factory()->individual()->create(['full_name' => 'Test Client']); $this->actingAs($this->admin); $component = Volt::test('admin.clients.individual.index') ->set('search', 'something') ->set('statusFilter', 'active') ->call('clearFilters'); expect($component->get('search'))->toBe(''); expect($component->get('statusFilter'))->toBe(''); }); // =========================================== // Edit Client Tests // =========================================== test('admin can access edit individual client page', function () { $client = User::factory()->individual()->create(); $this->actingAs($this->admin) ->get(route('admin.clients.individual.edit', $client)) ->assertOk(); }); test('edit form pre-populates with current values', function () { $client = User::factory()->individual()->create([ 'full_name' => 'Original Name', 'email' => 'original@example.com', 'national_id' => '987654321', 'phone' => '+970599000000', 'preferred_language' => 'en', ]); $this->actingAs($this->admin); $component = Volt::test('admin.clients.individual.edit', ['client' => $client]); expect($component->get('full_name'))->toBe('Original Name'); expect($component->get('email'))->toBe('original@example.com'); expect($component->get('national_id'))->toBe('987654321'); expect($component->get('phone'))->toBe('+970599000000'); expect($component->get('preferred_language'))->toBe('en'); }); test('can edit existing client information', function () { $client = User::factory()->individual()->create(); $this->actingAs($this->admin); Volt::test('admin.clients.individual.edit', ['client' => $client]) ->set('full_name', 'Updated Name') ->set('email', 'updated@example.com') ->set('national_id', '111111111') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasNoErrors() ->assertRedirect(route('admin.clients.individual.index')); $client->refresh(); expect($client->full_name)->toBe('Updated Name'); expect($client->email)->toBe('updated@example.com'); expect($client->national_id)->toBe('111111111'); }); test('validation rules apply on edit (except unique for own record)', function () { $client = User::factory()->individual()->create([ 'email' => 'client@example.com', 'national_id' => '123456789', ]); $this->actingAs($this->admin); // Should not error when keeping same email Volt::test('admin.clients.individual.edit', ['client' => $client]) ->set('full_name', 'Updated Name') ->set('email', 'client@example.com') ->set('national_id', '123456789') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasNoErrors(); }); test('admin log entry created on successful update', function () { $client = User::factory()->individual()->create(); $this->actingAs($this->admin); Volt::test('admin.clients.individual.edit', ['client' => $client]) ->set('full_name', 'Updated Name') ->set('email', 'updated@example.com') ->set('national_id', '111111111') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasNoErrors(); expect(AdminLog::where('action', 'update') ->where('target_type', 'user') ->where('target_id', $client->id) ->where('admin_id', $this->admin->id) ->exists())->toBeTrue(); }); // =========================================== // View Profile Tests // =========================================== test('admin can access view individual client page', function () { $client = User::factory()->individual()->create(); $this->actingAs($this->admin) ->get(route('admin.clients.individual.show', $client)) ->assertOk(); }); test('profile page displays all client information', function () { $client = User::factory()->individual()->create([ 'full_name' => 'John Doe', 'email' => 'john@example.com', 'national_id' => '123456789', 'phone' => '+970599123456', ]); $this->actingAs($this->admin); Volt::test('admin.clients.individual.show', ['client' => $client]) ->assertSee('John Doe') ->assertSee('john@example.com') ->assertSee('123456789') ->assertSee('+970599123456'); }); test('profile shows consultation count', function () { $client = User::factory()->individual()->create(); $this->actingAs($this->admin); $component = Volt::test('admin.clients.individual.show', ['client' => $client]); // The component should load consultation counts expect($component->get('client')->consultations_count)->toBe(0); }); test('profile shows timeline count', function () { $client = User::factory()->individual()->create(); $this->actingAs($this->admin); $component = Volt::test('admin.clients.individual.show', ['client' => $client]); // The component should load timeline counts expect($component->get('client')->timelines_count)->toBe(0); }); // =========================================== // Authorization Tests // =========================================== test('non-admin cannot access individual clients pages', function () { $client = User::factory()->individual()->create(); $this->actingAs($client); $this->get(route('admin.clients.individual.index'))->assertForbidden(); $this->get(route('admin.clients.individual.create'))->assertForbidden(); $this->get(route('admin.clients.individual.show', $client))->assertForbidden(); $this->get(route('admin.clients.individual.edit', $client))->assertForbidden(); }); test('unauthenticated user cannot access individual clients pages', function () { $client = User::factory()->individual()->create(); $this->get(route('admin.clients.individual.index'))->assertRedirect(route('login')); $this->get(route('admin.clients.individual.create'))->assertRedirect(route('login')); $this->get(route('admin.clients.individual.show', $client))->assertRedirect(route('login')); $this->get(route('admin.clients.individual.edit', $client))->assertRedirect(route('login')); });