setupUser(); $role = Role::firstOrCreate(['name' => 'Owner']); Permission::firstOrCreate(['name' => 'view account']); Permission::firstOrCreate(['name' => 'update account']); Permission::firstOrCreate(['name' => 'update profile']); Permission::firstOrCreate(['name' => 'update password']); $role->givePermissionTo(['view account', 'update account', 'update profile', 'update password']); $this->user->assignRole($role); }); it('renders the account page correctly', function () { $this->actingAs($this->user) ->get(route('studio.setting.account')) ->assertOk() ->assertSeeLivewire(Account::class); }); it('loads account data on mount', function () { Livewire::actingAs($this->user) ->test(Account::class) ->assertSet('accountForm.username', $this->user->username) ->assertSet('accountForm.email', $this->user->email) ->assertSet('accountForm.user.id', $this->user->id); }); it('loads profile data on mount', function () { Livewire::actingAs($this->user) ->test(Account::class) ->assertSet('profileForm.full_name', $this->employee->full_name) ->assertSet('profileForm.phone_number', $this->employee->phone_number) ->assertSet('profileForm.employee.id', $this->employee->id); }); // Account Update Tests it('shows validation errors when updating account with empty fields', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.username', '') ->set('accountForm.email', '') ->call('updateAccount') ->assertHasErrors([ 'accountForm.username' => 'required', 'accountForm.email' => 'required', ]); }); it('shows validation error when username is too short', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.username', 'test') ->call('updateAccount') ->assertHasErrors([ 'accountForm.username' => 'min', ]); }); it('shows validation error when username is not alphanumeric', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.username', 'test@user') ->call('updateAccount') ->assertHasErrors([ 'accountForm.username' => 'alpha_num', ]); }); it('shows validation error when email is invalid', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.email', 'invalid-email') ->call('updateAccount') ->assertHasErrors([ 'accountForm.email' => 'email', ]); }); it('shows validation error when username is already taken', function () { $existingUser = \App\Models\User::factory()->create(['username' => 'existinguser']); Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.username', 'existinguser') ->call('updateAccount') ->assertHasErrors([ 'accountForm.username' => 'unique', ]); }); it('shows validation error when email is already taken', function () { $existingUser = \App\Models\User::factory()->create(['email' => 'existing@example.com']); Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.email', 'existing@example.com') ->call('updateAccount') ->assertHasErrors([ 'accountForm.email' => 'unique', ]); }); it('can update account successfully', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.username', 'newusername') ->set('accountForm.email', 'newemail@example.com') ->call('updateAccount') ->assertHasNoErrors(); $this->assertDatabaseHas('users', [ 'id' => $this->user->id, 'username' => 'newusername', 'email' => 'newemail@example.com', ]); }); it('cannot update account without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); Livewire::actingAs($this->user) ->test(Account::class) ->set('accountForm.username', 'newusername') ->call('updateAccount') ->assertForbidden(); }); // Profile Update Tests it('shows validation errors when updating profile with empty required fields', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('profileForm.full_name', '') ->set('profileForm.phone_number', '') ->set('profileForm.birthdate', '') ->set('profileForm.gender', '') ->call('updateProfile') ->assertHasErrors([ 'profileForm.full_name' => 'required', 'profileForm.phone_number' => 'required', 'profileForm.birthdate' => 'required', 'profileForm.gender' => 'required', ]); }); it('shows validation error when phone number is invalid', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('profileForm.phone_number', '123') ->call('updateProfile') ->assertHasErrors([ 'profileForm.phone_number', ]); }); it('shows validation error when birthdate indicates user is under 18', function () { $recentDate = now()->subYears(17)->format('Y-m-d'); Livewire::actingAs($this->user) ->test(Account::class) ->set('profileForm.birthdate', $recentDate) ->call('updateProfile') ->assertHasErrors([ 'profileForm.birthdate' => 'before', ]); }); it('shows validation error when gender is invalid', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('profileForm.gender', 'invalid') ->call('updateProfile') ->assertHasErrors([ 'profileForm.gender' => 'in', ]); }); it('can update profile successfully', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('profileForm.full_name', 'New Full Name') ->set('profileForm.phone_number', '0812 3456 7890') ->set('profileForm.birthdate', '1990-01-01') ->set('profileForm.address', 'New Address') ->set('profileForm.gender', Gender::MALE->value) ->call('updateProfile') ->assertHasNoErrors(); $this->assertDatabaseHas('employees', [ 'id' => $this->employee->id, 'full_name' => 'New Full Name', 'phone_number' => '0812 3456 7890', 'birthdate' => '1990-01-01', 'address' => 'New Address', 'gender' => Gender::MALE->value, ]); }); it('cannot update profile without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); Livewire::actingAs($this->user) ->test(Account::class) ->set('profileForm.full_name', 'New Name') ->call('updateProfile') ->assertForbidden(); }); // Password Update Tests it('shows validation errors when updating password with empty fields', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('passwordForm.current_password', '') ->set('passwordForm.new_password', '') ->set('passwordForm.new_confirm_password', '') ->call('updatePassword') ->assertHasErrors([ 'passwordForm.current_password', 'passwordForm.new_password', 'passwordForm.new_confirm_password', ]); }); it('shows validation error when new password does not meet requirements', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('passwordForm.current_password', 'password') ->set('passwordForm.new_password', 'weak') ->set('passwordForm.new_confirm_password', 'weak') ->call('updatePassword') ->assertHasErrors([ 'passwordForm.new_password', ]); }); it('shows validation error when password confirmation does not match', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('passwordForm.current_password', 'password') ->set('passwordForm.new_password', 'NewPassword123!') ->set('passwordForm.new_confirm_password', 'DifferentPassword123!') ->call('updatePassword') ->assertHasErrors([ 'passwordForm.new_confirm_password', ]); }); it('shows error when current password is incorrect', function () { Livewire::actingAs($this->user) ->test(Account::class) ->set('passwordForm.current_password', 'wrongpassword') ->set('passwordForm.new_password', 'VeryStr0ng!Pass#2024') ->set('passwordForm.new_confirm_password', 'VeryStr0ng!Pass#2024') ->call('updatePassword') ->assertHasNoErrors(); }); it('can update password successfully and logout', function () { $this->user->update(['password' => \Illuminate\Support\Facades\Hash::make('CurrentStr0ng!Pass#2024')]); Livewire::actingAs($this->user) ->test(Account::class) ->set('passwordForm.current_password', 'CurrentStr0ng!Pass#2024') ->set('passwordForm.new_password', 'NewVeryStr0ng!Pass#2024') ->set('passwordForm.new_confirm_password', 'NewVeryStr0ng!Pass#2024') ->call('updatePassword') ->assertHasNoErrors() ->assertRedirect(route('login')); }); it('cannot update password without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); Livewire::actingAs($this->user) ->test(Account::class) ->set('passwordForm.current_password', 'password') ->set('passwordForm.new_password', 'NewPassword123!') ->call('updatePassword') ->assertForbidden(); });