admin = User::factory()->admin()->create(); }); // =========================================== // Create Company Client Tests // =========================================== test('admin can access company clients index page', function () { $this->actingAs($this->admin) ->get(route('admin.clients.company.index')) ->assertOk(); }); test('admin can access create company client page', function () { $this->actingAs($this->admin) ->get(route('admin.clients.company.create')) ->assertOk(); }); test('admin can create company client with all valid data', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasNoErrors() ->assertRedirect(route('admin.clients.company.index')); expect(User::where('email', 'testcompany@example.com')->exists())->toBeTrue(); $client = User::where('email', 'testcompany@example.com')->first(); expect($client->user_type)->toBe(UserType::Company); expect($client->status)->toBe(UserStatus::Active); expect($client->company_name)->toBe('Test Company LLC'); expect($client->company_cert_number)->toBe('CR-123456'); expect($client->contact_person_name)->toBe('John Doe'); expect($client->contact_person_id)->toBe('987654321'); }); test('created company has user_type set to company', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasNoErrors(); $client = User::where('email', 'testcompany@example.com')->first(); expect($client->user_type)->toBe(UserType::Company); }); test('admin log entry created on successful company creation', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->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 company without required company_name field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', '') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['company_name' => 'required']); }); test('cannot create company without required company_cert_number field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', '') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['company_cert_number' => 'required']); }); test('cannot create company without required contact_person_name field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', '') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['contact_person_name' => 'required']); }); test('cannot create company without required contact_person_id field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['contact_person_id' => 'required']); }); test('cannot create company without required email field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', '') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['email' => 'required']); }); test('cannot create company without required phone field', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['phone' => 'required']); }); test('cannot create company with invalid email format', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'invalid-email') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['email' => 'email']); }); test('cannot create company with duplicate email', function () { User::factory()->company()->create(['email' => 'existing@example.com']); $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'existing@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['email' => 'unique']); }); test('cannot create company with duplicate registration number', function () { User::factory()->company()->create(['company_cert_number' => 'CR-123456']); $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'password123') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['company_cert_number' => 'unique']); }); test('cannot create company with password less than 8 characters', function () { $this->actingAs($this->admin); Volt::test('admin.clients.company.create') ->set('company_name', 'Test Company LLC') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'John Doe') ->set('contact_person_id', '987654321') ->set('email', 'testcompany@example.com') ->set('phone', '+970599123456') ->set('password', 'short') ->set('preferred_language', 'ar') ->call('create') ->assertHasErrors(['password' => 'min']); }); test('preferred language defaults to Arabic', function () { $this->actingAs($this->admin); $component = Volt::test('admin.clients.company.create'); expect($component->get('preferred_language'))->toBe('ar'); }); // =========================================== // List View Tests // =========================================== test('index page displays only company clients', function () { // Create different types of users $companyClient = User::factory()->company()->create(['company_name' => 'Company Test']); $individualClient = User::factory()->individual()->create(['full_name' => 'Individual Test']); $adminUser = User::factory()->admin()->create(['full_name' => 'Admin Test']); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->assertSee('Company Test') ->assertDontSee('Individual Test') ->assertDontSee('Admin Test'); }); test('company clients sorted by created_at desc by default', function () { $oldCompany = User::factory()->company()->create([ 'company_name' => 'Old Company', 'created_at' => now()->subDays(10), ]); $newCompany = User::factory()->company()->create([ 'company_name' => 'New Company', 'created_at' => now(), ]); $this->actingAs($this->admin); $response = Volt::test('admin.clients.company.index'); // The new company should appear before the old company $response->assertSeeInOrder(['New Company', 'Old Company']); }); test('pagination works with different per page values', function () { User::factory()->company()->count(15)->create(); $this->actingAs($this->admin); $component = Volt::test('admin.clients.company.index') ->set('perPage', 10); // Should show pagination expect($component->get('perPage'))->toBe(10); }); // =========================================== // Search & Filter Tests // =========================================== test('can search companies by company name (partial match)', function () { User::factory()->company()->create(['company_name' => 'Tech Solutions Inc']); User::factory()->company()->create(['company_name' => 'Finance Corp']); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->set('search', 'Tech') ->assertSee('Tech Solutions Inc') ->assertDontSee('Finance Corp'); }); test('can search companies by email (partial match)', function () { User::factory()->company()->create([ 'company_name' => 'Tech Solutions Inc', 'email' => 'tech@example.com', ]); User::factory()->company()->create([ 'company_name' => 'Finance Corp', 'email' => 'finance@example.com', ]); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->set('search', 'tech@') ->assertSee('Tech Solutions Inc') ->assertDontSee('Finance Corp'); }); test('can search companies by registration number (partial match)', function () { User::factory()->company()->create([ 'company_name' => 'Tech Solutions Inc', 'company_cert_number' => 'CR-111222', ]); User::factory()->company()->create([ 'company_name' => 'Finance Corp', 'company_cert_number' => 'CR-333444', ]); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->set('search', 'CR-111') ->assertSee('Tech Solutions Inc') ->assertDontSee('Finance Corp'); }); test('can filter companies by active status', function () { User::factory()->company()->create([ 'company_name' => 'Active Company', 'status' => UserStatus::Active, ]); User::factory()->company()->deactivated()->create([ 'company_name' => 'Deactivated Company', ]); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->set('statusFilter', 'active') ->assertSee('Active Company') ->assertDontSee('Deactivated Company'); }); test('can filter companies by deactivated status', function () { User::factory()->company()->create([ 'company_name' => 'Active Company', 'status' => UserStatus::Active, ]); User::factory()->company()->deactivated()->create([ 'company_name' => 'Deactivated Company', ]); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->set('statusFilter', 'deactivated') ->assertDontSee('Active Company') ->assertSee('Deactivated Company'); }); test('combined search and filter works correctly', function () { User::factory()->company()->create([ 'company_name' => 'Active Tech', 'status' => UserStatus::Active, ]); User::factory()->company()->deactivated()->create([ 'company_name' => 'Deactivated Tech', ]); User::factory()->company()->create([ 'company_name' => 'Active Finance', 'status' => UserStatus::Active, ]); $this->actingAs($this->admin); Volt::test('admin.clients.company.index') ->set('search', 'Tech') ->set('statusFilter', 'active') ->assertSee('Active Tech') ->assertDontSee('Deactivated Tech') ->assertDontSee('Active Finance'); }); test('clear filters resets search and filter', function () { User::factory()->company()->create(['company_name' => 'Test Company']); $this->actingAs($this->admin); $component = Volt::test('admin.clients.company.index') ->set('search', 'something') ->set('statusFilter', 'active') ->call('clearFilters'); expect($component->get('search'))->toBe(''); expect($component->get('statusFilter'))->toBe(''); }); // =========================================== // Edit Company Tests // =========================================== test('admin can access edit company client page', function () { $client = User::factory()->company()->create(); $this->actingAs($this->admin) ->get(route('admin.clients.company.edit', $client)) ->assertOk(); }); test('edit form pre-populates with current values', function () { $client = User::factory()->company()->create([ 'company_name' => 'Original Company', 'company_cert_number' => 'CR-ORIGINAL', 'contact_person_name' => 'Original Contact', 'contact_person_id' => '111111111', 'email' => 'original@example.com', 'phone' => '+970599000000', 'preferred_language' => 'en', ]); $this->actingAs($this->admin); $component = Volt::test('admin.clients.company.edit', ['client' => $client]); expect($component->get('company_name'))->toBe('Original Company'); expect($component->get('company_cert_number'))->toBe('CR-ORIGINAL'); expect($component->get('contact_person_name'))->toBe('Original Contact'); expect($component->get('contact_person_id'))->toBe('111111111'); expect($component->get('email'))->toBe('original@example.com'); expect($component->get('phone'))->toBe('+970599000000'); expect($component->get('preferred_language'))->toBe('en'); }); test('can edit existing company information', function () { $client = User::factory()->company()->create(); $this->actingAs($this->admin); Volt::test('admin.clients.company.edit', ['client' => $client]) ->set('company_name', 'Updated Company') ->set('company_cert_number', 'CR-UPDATED') ->set('contact_person_name', 'Updated Contact') ->set('contact_person_id', '222222222') ->set('email', 'updated@example.com') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasNoErrors() ->assertRedirect(route('admin.clients.company.index')); $client->refresh(); expect($client->company_name)->toBe('Updated Company'); expect($client->company_cert_number)->toBe('CR-UPDATED'); expect($client->contact_person_name)->toBe('Updated Contact'); expect($client->email)->toBe('updated@example.com'); }); test('validation allows same email and registration for own record', function () { $client = User::factory()->company()->create([ 'email' => 'company@example.com', 'company_cert_number' => 'CR-123456', ]); $this->actingAs($this->admin); // Should not error when keeping same email and registration number Volt::test('admin.clients.company.edit', ['client' => $client]) ->set('company_name', 'Updated Company') ->set('company_cert_number', 'CR-123456') ->set('contact_person_name', 'Contact Person') ->set('contact_person_id', '987654321') ->set('email', 'company@example.com') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasNoErrors(); }); test('validation fails for duplicate email excluding own record', function () { $existingClient = User::factory()->company()->create(['email' => 'existing@example.com']); $client = User::factory()->company()->create(['email' => 'original@example.com']); $this->actingAs($this->admin); Volt::test('admin.clients.company.edit', ['client' => $client]) ->set('company_name', 'Updated Company') ->set('company_cert_number', 'CR-UNIQUE') ->set('contact_person_name', 'Contact Person') ->set('contact_person_id', '987654321') ->set('email', 'existing@example.com') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasErrors(['email' => 'unique']); }); test('validation fails for duplicate registration number excluding own record', function () { $existingClient = User::factory()->company()->create(['company_cert_number' => 'CR-EXISTING']); $client = User::factory()->company()->create(['company_cert_number' => 'CR-ORIGINAL']); $this->actingAs($this->admin); Volt::test('admin.clients.company.edit', ['client' => $client]) ->set('company_name', 'Updated Company') ->set('company_cert_number', 'CR-EXISTING') ->set('contact_person_name', 'Contact Person') ->set('contact_person_id', '987654321') ->set('email', 'unique@example.com') ->set('phone', '+970599111111') ->set('preferred_language', 'en') ->set('status', 'active') ->call('update') ->assertHasErrors(['company_cert_number' => 'unique']); }); test('admin log entry created on successful company update', function () { $client = User::factory()->company()->create(); $this->actingAs($this->admin); Volt::test('admin.clients.company.edit', ['client' => $client]) ->set('company_name', 'Updated Company') ->set('company_cert_number', 'CR-UPDATED') ->set('contact_person_name', 'Updated Contact') ->set('contact_person_id', '222222222') ->set('email', 'updated@example.com') ->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 company client page', function () { $client = User::factory()->company()->create(); $this->actingAs($this->admin) ->get(route('admin.clients.company.show', $client)) ->assertOk(); }); test('profile page displays all company information', function () { $client = User::factory()->company()->create([ 'company_name' => 'Test Company LLC', 'company_cert_number' => 'CR-123456', 'contact_person_name' => 'John Doe', 'contact_person_id' => '987654321', 'email' => 'company@example.com', 'phone' => '+970599123456', ]); $this->actingAs($this->admin); Volt::test('admin.clients.company.show', ['client' => $client]) ->assertSee('Test Company LLC') ->assertSee('CR-123456') ->assertSee('John Doe') ->assertSee('987654321') ->assertSee('company@example.com') ->assertSee('+970599123456'); }); test('company profile shows consultation count', function () { $client = User::factory()->company()->create(); $this->actingAs($this->admin); $component = Volt::test('admin.clients.company.show', ['client' => $client]); // The component should load consultation counts expect($component->get('client')->consultations_count)->toBe(0); }); test('company profile shows timeline count', function () { $client = User::factory()->company()->create(); $this->actingAs($this->admin); $component = Volt::test('admin.clients.company.show', ['client' => $client]); // The component should load timeline counts expect($component->get('client')->timelines_count)->toBe(0); }); // =========================================== // Authorization Tests // =========================================== test('non-admin cannot access company clients pages', function () { $client = User::factory()->company()->create(); $individualUser = User::factory()->individual()->create(); $this->actingAs($individualUser); $this->get(route('admin.clients.company.index'))->assertForbidden(); $this->get(route('admin.clients.company.create'))->assertForbidden(); $this->get(route('admin.clients.company.show', $client))->assertForbidden(); $this->get(route('admin.clients.company.edit', $client))->assertForbidden(); }); test('unauthenticated user cannot access company clients pages', function () { $client = User::factory()->company()->create(); $this->get(route('admin.clients.company.index'))->assertRedirect(route('login')); $this->get(route('admin.clients.company.create'))->assertRedirect(route('login')); $this->get(route('admin.clients.company.show', $client))->assertRedirect(route('login')); $this->get(route('admin.clients.company.edit', $client))->assertRedirect(route('login')); });