UserControllerTest.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. namespace Tests\Api\v1\Controllers\Auth;
  3. use App\Api\v1\Controllers\UserController;
  4. use App\Api\v1\Resources\UserResource;
  5. use App\Models\User;
  6. use PHPUnit\Framework\Attributes\CoversClass;
  7. use Tests\FeatureTestCase;
  8. /**
  9. * UserControllerTest test class
  10. */
  11. #[CoversClass(UserController::class)]
  12. #[CoversClass(UserResource::class)]
  13. class UserControllerTest extends FeatureTestCase
  14. {
  15. /**
  16. * @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
  17. */
  18. protected $user;
  19. private const PREFERENCE_JSON_STRUCTURE = [
  20. 'key',
  21. 'value',
  22. ];
  23. /**
  24. * @test
  25. */
  26. public function setUp() : void
  27. {
  28. parent::setUp();
  29. $this->user = User::factory()->create();
  30. }
  31. /**
  32. * @test
  33. */
  34. public function test_show_existing_user_when_authenticated_returns_success()
  35. {
  36. $response = $this->actingAs($this->user, 'api-guard')
  37. ->json('GET', '/api/v1/user')
  38. ->assertOk()
  39. ->assertJsonFragment([
  40. 'name' => $this->user->name,
  41. 'id' => $this->user->id,
  42. 'email' => $this->user->email,
  43. 'is_admin' => $this->user->is_admin,
  44. ])
  45. ->assertJsonStructure([
  46. 'preferences',
  47. ]);
  48. }
  49. /**
  50. * @test
  51. */
  52. public function test_allPreferences_returns_consistent_json_structure()
  53. {
  54. $response = $this->actingAs($this->user, 'api-guard')
  55. ->json('GET', '/api/v1/user/preferences')
  56. ->assertOk()
  57. ->assertJsonStructure([
  58. '*' => self::PREFERENCE_JSON_STRUCTURE,
  59. ]);
  60. }
  61. /**
  62. * @test
  63. */
  64. public function test_allPreferences_returns_preferences_with_default_values()
  65. {
  66. $response = $this->actingAs($this->user, 'api-guard')
  67. ->json('GET', '/api/v1/user/preferences')
  68. ->assertJsonCount(count(config('2fauth.preferences')), $key = null);
  69. foreach (config('2fauth.preferences') as $pref => $value) {
  70. $response->assertJsonFragment([
  71. 'key' => $pref,
  72. 'value' => $value,
  73. ]);
  74. }
  75. }
  76. /**
  77. * @test
  78. */
  79. public function test_allPreferences_returns_preferences_with_user_values()
  80. {
  81. $userPrefs = [
  82. 'showOtpAsDot' => true,
  83. 'closeOtpOnCopy' => true,
  84. 'copyOtpOnDisplay' => true,
  85. 'useBasicQrcodeReader' => true,
  86. 'displayMode' => 'grid',
  87. 'showAccountsIcons' => false,
  88. 'kickUserAfter' => 5,
  89. 'activeGroup' => 1,
  90. 'rememberActiveGroup' => false,
  91. 'defaultGroup' => 1,
  92. 'defaultCaptureMode' => 'advancedForm',
  93. 'useDirectCapture' => true,
  94. 'useWebauthnOnly' => true,
  95. 'getOfficialIcons' => false,
  96. 'theme' => 'dark',
  97. 'formatPassword' => false,
  98. 'formatPasswordBy' => 1,
  99. 'lang' => 'fr',
  100. ];
  101. $this->user['preferences->showOtpAsDot'] = $userPrefs['showOtpAsDot'];
  102. $this->user['preferences->closeOtpOnCopy'] = $userPrefs['closeOtpOnCopy'];
  103. $this->user['preferences->copyOtpOnDisplay'] = $userPrefs['copyOtpOnDisplay'];
  104. $this->user['preferences->useBasicQrcodeReader'] = $userPrefs['useBasicQrcodeReader'];
  105. $this->user['preferences->displayMode'] = $userPrefs['displayMode'];
  106. $this->user['preferences->showAccountsIcons'] = $userPrefs['showAccountsIcons'];
  107. $this->user['preferences->kickUserAfter'] = $userPrefs['kickUserAfter'];
  108. $this->user['preferences->activeGroup'] = $userPrefs['activeGroup'];
  109. $this->user['preferences->rememberActiveGroup'] = $userPrefs['rememberActiveGroup'];
  110. $this->user['preferences->defaultGroup'] = $userPrefs['defaultGroup'];
  111. $this->user['preferences->defaultCaptureMode'] = $userPrefs['defaultCaptureMode'];
  112. $this->user['preferences->useDirectCapture'] = $userPrefs['useDirectCapture'];
  113. $this->user['preferences->useWebauthnOnly'] = $userPrefs['useWebauthnOnly'];
  114. $this->user['preferences->getOfficialIcons'] = $userPrefs['getOfficialIcons'];
  115. $this->user['preferences->theme'] = $userPrefs['theme'];
  116. $this->user['preferences->formatPassword'] = $userPrefs['formatPassword'];
  117. $this->user['preferences->formatPasswordBy'] = $userPrefs['formatPasswordBy'];
  118. $this->user['preferences->lang'] = $userPrefs['lang'];
  119. $this->user->save();
  120. $response = $this->actingAs($this->user, 'api-guard')
  121. ->json('GET', '/api/v1/user/preferences')
  122. ->assertJsonCount(count(config('2fauth.preferences')), $key = null);
  123. foreach ($userPrefs as $pref => $value) {
  124. $response->assertJsonFragment([
  125. 'key' => $pref,
  126. 'value' => $value,
  127. ]);
  128. }
  129. }
  130. /**
  131. * @test
  132. */
  133. public function test_showPreference_returns_preference_with_default_value()
  134. {
  135. /**
  136. * @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
  137. */
  138. $this->user = User::factory()->create();
  139. $response = $this->actingAs($this->user, 'api-guard')
  140. ->json('GET', '/api/v1/user/preferences/showOtpAsDot')
  141. ->assertOk()
  142. ->assertExactJson([
  143. 'key' => 'showOtpAsDot',
  144. 'value' => config('2fauth.preferences.showOtpAsDot'),
  145. ]);
  146. }
  147. /**
  148. * @test
  149. */
  150. public function test_showPreference_returns_preference_with_custom_value()
  151. {
  152. $showOtpAsDot = ! config('2fauth.preferences.showOtpAsDot');
  153. $this->user['preferences->showOtpAsDot'] = $showOtpAsDot;
  154. $this->user->save();
  155. $response = $this->actingAs($this->user, 'api-guard')
  156. ->json('GET', '/api/v1/user/preferences/showOtpAsDot')
  157. ->assertJsonFragment([
  158. 'key' => 'showOtpAsDot',
  159. 'value' => $showOtpAsDot,
  160. ]);
  161. }
  162. /**
  163. * @test
  164. */
  165. public function test_showPreference_for_missing_preference_returns_not_found()
  166. {
  167. $response = $this->actingAs($this->user, 'api-guard')
  168. ->json('GET', '/api/v1/user/preferences/unknown')
  169. ->assertNotFound();
  170. }
  171. /**
  172. * @test
  173. */
  174. public function test_setPreference_returns_updated_preference()
  175. {
  176. /**
  177. * @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
  178. */
  179. $this->user = User::factory()->create();
  180. $showOtpAsDot = ! config('2fauth.preferences.showOtpAsDot');
  181. $response = $this->actingAs($this->user, 'api-guard')
  182. ->json('PUT', '/api/v1/user/preferences/showOtpAsDot', [
  183. 'key' => 'showOtpAsDot',
  184. 'value' => $showOtpAsDot,
  185. ])
  186. ->assertCreated()
  187. ->assertExactJson([
  188. 'key' => 'showOtpAsDot',
  189. 'value' => $showOtpAsDot,
  190. ]);
  191. }
  192. /**
  193. * @test
  194. */
  195. public function test_setPreference_for_missing_preference_returns_not_found()
  196. {
  197. $response = $this->actingAs($this->user, 'api-guard')
  198. ->json('PUT', '/api/v1/user/preferences/unknown', [
  199. 'key' => 'showOtpAsDot',
  200. 'value' => true,
  201. ])
  202. ->assertNotFound();
  203. }
  204. /**
  205. * @test
  206. */
  207. public function test_setPreference_with_invalid_data_returns_validation_error()
  208. {
  209. $response = $this->actingAs($this->user, 'api-guard')
  210. ->json('PUT', '/api/v1/user/preferences/showOtpAsDot', [
  211. 'key' => 'showOtpAsDot',
  212. 'value' => null,
  213. ])
  214. ->assertStatus(422);
  215. }
  216. }