UserControllerTest.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. namespace Tests\Feature;
  3. use App\Models\Role;
  4. use App\Models\User;
  5. use Illuminate\Foundation\Testing\RefreshDatabase;
  6. use Tests\TestCase;
  7. class UserControllerTest extends TestCase
  8. {
  9. use RefreshDatabase;
  10. protected $seed = true;
  11. private User $adminUser;
  12. private User $managerUser;
  13. protected function setUp(): void
  14. {
  15. parent::setUp();
  16. $this->adminUser = User::factory()->create(['role' => Role::ADMIN]);
  17. $this->managerUser = User::factory()->create(['role' => Role::MANAGER]);
  18. }
  19. private function validUserData(): array
  20. {
  21. return [
  22. 'name' => 'Тест Пользователь',
  23. 'email' => 'test_new@example.com',
  24. 'password' => 'password123',
  25. 'role' => Role::MANAGER,
  26. ];
  27. }
  28. // ==================== Guest redirects ====================
  29. public function test_guest_cannot_access_users_index(): void
  30. {
  31. $response = $this->get(route('user.index'));
  32. $response->assertRedirect(route('login'));
  33. }
  34. public function test_guest_cannot_access_user_create(): void
  35. {
  36. $response = $this->get(route('user.create'));
  37. $response->assertRedirect(route('login'));
  38. }
  39. public function test_guest_cannot_store_user(): void
  40. {
  41. $response = $this->post(route('user.store'), $this->validUserData());
  42. $response->assertRedirect(route('login'));
  43. }
  44. public function test_guest_cannot_delete_user(): void
  45. {
  46. $user = User::factory()->create(['role' => Role::MANAGER]);
  47. $response = $this->delete(route('user.destroy', $user));
  48. $response->assertRedirect(route('login'));
  49. }
  50. // ==================== Authorization - manager gets 403 ====================
  51. public function test_manager_cannot_access_users_index(): void
  52. {
  53. $response = $this->actingAs($this->managerUser)
  54. ->get(route('user.index'));
  55. $response->assertStatus(403);
  56. }
  57. public function test_manager_cannot_create_user(): void
  58. {
  59. $response = $this->actingAs($this->managerUser)
  60. ->post(route('user.store'), $this->validUserData());
  61. $response->assertStatus(403);
  62. }
  63. public function test_manager_cannot_delete_user(): void
  64. {
  65. $user = User::factory()->create(['role' => Role::MANAGER]);
  66. $response = $this->actingAs($this->managerUser)
  67. ->delete(route('user.destroy', $user));
  68. $response->assertStatus(403);
  69. }
  70. // ==================== Index ====================
  71. public function test_admin_can_access_users_index(): void
  72. {
  73. $response = $this->actingAs($this->adminUser)
  74. ->get(route('user.index'));
  75. $response->assertStatus(200);
  76. $response->assertViewIs('users.index');
  77. }
  78. // ==================== Create form ====================
  79. public function test_admin_can_access_user_create(): void
  80. {
  81. $response = $this->actingAs($this->adminUser)
  82. ->get(route('user.create'));
  83. $response->assertStatus(200);
  84. $response->assertViewIs('users.edit');
  85. }
  86. // ==================== Show ====================
  87. public function test_admin_can_view_user(): void
  88. {
  89. $user = User::factory()->create(['role' => Role::MANAGER]);
  90. $response = $this->actingAs($this->adminUser)
  91. ->get(route('user.show', $user));
  92. $response->assertStatus(200);
  93. $response->assertViewIs('users.edit');
  94. }
  95. public function test_user_show_uses_nav_context_back_url(): void
  96. {
  97. $user = User::factory()->create(['role' => Role::MANAGER]);
  98. $response = $this->actingAs($this->adminUser)
  99. ->withSession([
  100. 'navigation' => [
  101. 'user-nav' => [
  102. 'updated_at' => now()->timestamp,
  103. 'stack' => [
  104. route('user.index', ['page' => 2]),
  105. ],
  106. ],
  107. ],
  108. ])
  109. ->get(route('user.show', ['user' => $user, 'nav' => 'user-nav']));
  110. $response->assertOk();
  111. $response->assertViewHas('nav', 'user-nav');
  112. $response->assertViewHas('back_url', route('user.index', ['page' => 2]));
  113. }
  114. // ==================== Store - create new user ====================
  115. public function test_admin_can_create_user(): void
  116. {
  117. $data = $this->validUserData();
  118. $response = $this->actingAs($this->adminUser)
  119. ->post(route('user.store'), $data);
  120. $response->assertRedirect(route('user.index'));
  121. $this->assertDatabaseHas('users', ['email' => $data['email']]);
  122. }
  123. public function test_store_requires_name(): void
  124. {
  125. $data = $this->validUserData();
  126. unset($data['name']);
  127. $response = $this->actingAs($this->adminUser)
  128. ->post(route('user.store'), $data);
  129. $response->assertSessionHasErrors('name');
  130. }
  131. public function test_store_requires_password_for_new_user(): void
  132. {
  133. $data = $this->validUserData();
  134. unset($data['password']);
  135. $response = $this->actingAs($this->adminUser)
  136. ->post(route('user.store'), $data);
  137. $response->assertSessionHasErrors('password');
  138. }
  139. // ==================== Update existing user ====================
  140. public function test_admin_can_update_user(): void
  141. {
  142. $user = User::factory()->create(['role' => Role::MANAGER]);
  143. $newName = 'Обновлённое Имя';
  144. $response = $this->actingAs($this->adminUser)
  145. ->post(route('user.store'), [
  146. 'id' => $user->id,
  147. 'name' => $newName,
  148. 'role' => Role::MANAGER,
  149. ]);
  150. $response->assertRedirect(route('user.index'));
  151. $this->assertDatabaseHas('users', ['id' => $user->id, 'name' => $newName]);
  152. }
  153. // ==================== Delete ====================
  154. public function test_admin_can_delete_user(): void
  155. {
  156. $user = User::factory()->create(['role' => Role::MANAGER]);
  157. $response = $this->actingAs($this->adminUser)
  158. ->delete(route('user.destroy', $user));
  159. $response->assertRedirect(route('user.index'));
  160. $this->assertSoftDeleted('users', ['id' => $user->id]);
  161. }
  162. public function test_admin_cannot_delete_self(): void
  163. {
  164. $response = $this->actingAs($this->adminUser)
  165. ->delete(route('user.destroy', $this->adminUser));
  166. $response->assertRedirect(route('user.index'));
  167. $response->assertSessionHas('danger');
  168. }
  169. // ==================== Undelete ====================
  170. public function test_admin_can_restore_deleted_user(): void
  171. {
  172. $user = User::factory()->create(['role' => Role::MANAGER]);
  173. $user->delete();
  174. $response = $this->actingAs($this->adminUser)
  175. ->post(route('user.undelete', $user->id));
  176. $response->assertRedirect();
  177. $this->assertDatabaseHas('users', ['id' => $user->id, 'deleted_at' => null]);
  178. }
  179. // ==================== Impersonate ====================
  180. public function test_admin_can_impersonate_user(): void
  181. {
  182. $targetUser = User::factory()->create(['role' => Role::MANAGER]);
  183. $response = $this->actingAs($this->adminUser)
  184. ->post(route('user.impersonate', $targetUser));
  185. $response->assertRedirect(route('home'));
  186. $response->assertSessionHas('impersonator_id', $this->adminUser->id);
  187. }
  188. }