SettingControllerTest.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <?php
  2. namespace Tests\Api\v1\Controllers;
  3. use App\Api\v1\Controllers\SettingController;
  4. use App\Api\v1\Requests\SettingUpdateRequest;
  5. use App\Facades\Settings;
  6. use App\Models\User;
  7. use Illuminate\Support\Arr;
  8. use Illuminate\Support\Facades\Route;
  9. use Illuminate\Support\Str;
  10. use PHPUnit\Framework\Attributes\CoversClass;
  11. use PHPUnit\Framework\Attributes\CoversMethod;
  12. use PHPUnit\Framework\Attributes\Test;
  13. use Tests\FeatureTestCase;
  14. /**
  15. * SettingController test class
  16. */
  17. #[CoversClass(SettingController::class)]
  18. #[CoversMethod(SettingUpdateRequest::class, 'rules')]
  19. class SettingControllerTest extends FeatureTestCase
  20. {
  21. /**
  22. * @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
  23. */
  24. protected $user;
  25. protected $admin;
  26. private const SETTING_JSON_STRUCTURE = [
  27. 'key',
  28. 'value',
  29. ];
  30. private const TWOFAUTH_NATIVE_SETTING = 'checkForUpdate';
  31. private const TWOFAUTH_NATIVE_SETTING_DEFAULT_VALUE = true;
  32. private const TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE = false;
  33. private const USER_DEFINED_SETTING = 'mySetting';
  34. private const USER_DEFINED_SETTING_VALUE = 'mySetting';
  35. private const USER_DEFINED_SETTING_CHANGED_VALUE = 'mySetting';
  36. protected function setUp() : void
  37. {
  38. parent::setUp();
  39. $this->user = User::factory()->create();
  40. $this->admin = User::factory()->administrator()->create();
  41. }
  42. #[Test]
  43. public function test_all_controller_routes_are_protected_by_admin_middleware()
  44. {
  45. $routes = Route::getRoutes()->getRoutes();
  46. $controllerRoutes = Arr::where($routes, function (\Illuminate\Routing\Route $route, int $key) {
  47. if (Str::startsWith($route->getActionName(), SettingController::class)) {
  48. return $route;
  49. }
  50. });
  51. foreach ($controllerRoutes as $controllerRoute) {
  52. $this->assertContains('admin', $controllerRoute->middleware());
  53. }
  54. }
  55. #[Test]
  56. public function test_index_returns_setting_collection()
  57. {
  58. $response = $this->actingAs($this->admin, 'api-guard')
  59. ->json('GET', '/api/v1/settings')
  60. ->assertOk()
  61. ->assertJsonStructure([
  62. '*' => self::SETTING_JSON_STRUCTURE,
  63. ]);
  64. }
  65. #[Test]
  66. public function test_index_is_forbidden_to_users()
  67. {
  68. $response = $this->actingAs($this->user, 'api-guard')
  69. ->json('GET', '/api/v1/settings')
  70. ->assertForbidden()
  71. ->assertJsonStructure([
  72. 'message',
  73. ]);
  74. }
  75. #[Test]
  76. public function test_show_native_unchanged_setting_returns_consistent_value()
  77. {
  78. $response = $this->actingAs($this->admin, 'api-guard')
  79. ->json('GET', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
  80. ->assertOk()
  81. ->assertExactJson([
  82. 'key' => self::TWOFAUTH_NATIVE_SETTING,
  83. 'value' => self::TWOFAUTH_NATIVE_SETTING_DEFAULT_VALUE,
  84. ]);
  85. }
  86. #[Test]
  87. public function test_show_native_changed_setting_returns_consistent_value()
  88. {
  89. Settings::set(self::TWOFAUTH_NATIVE_SETTING, self::TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE);
  90. $response = $this->actingAs($this->admin, 'api-guard')
  91. ->json('GET', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
  92. ->assertOk()
  93. ->assertExactJson([
  94. 'key' => self::TWOFAUTH_NATIVE_SETTING,
  95. 'value' => self::TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE,
  96. ]);
  97. }
  98. #[Test]
  99. public function test_show_custom_user_setting_returns_consistent_value()
  100. {
  101. Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
  102. $response = $this->actingAs($this->admin, 'api-guard')
  103. ->json('GET', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
  104. ->assertOk()
  105. ->assertExactJson([
  106. 'key' => self::USER_DEFINED_SETTING,
  107. 'value' => self::USER_DEFINED_SETTING_VALUE,
  108. ]);
  109. }
  110. #[Test]
  111. public function test_show_missing_setting_returns_not_found()
  112. {
  113. $response = $this->actingAs($this->admin, 'api-guard')
  114. ->json('GET', '/api/v1/settings/missing')
  115. ->assertNotFound();
  116. }
  117. #[Test]
  118. public function test_show_setting_is_forbidden_to_users()
  119. {
  120. $response = $this->actingAs($this->user, 'api-guard')
  121. ->json('GET', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
  122. ->assertForbidden()
  123. ->assertJsonStructure([
  124. 'message',
  125. ]);
  126. }
  127. #[Test]
  128. public function test_store_custom_user_setting_returns_success()
  129. {
  130. $response = $this->actingAs($this->admin, 'api-guard')
  131. ->json('POST', '/api/v1/settings', [
  132. 'key' => self::USER_DEFINED_SETTING,
  133. 'value' => self::USER_DEFINED_SETTING_VALUE,
  134. ])
  135. ->assertCreated()
  136. ->assertExactJson([
  137. 'key' => self::USER_DEFINED_SETTING,
  138. 'value' => self::USER_DEFINED_SETTING_VALUE,
  139. ]);
  140. }
  141. #[Test]
  142. public function test_store_invalid_custom_user_setting_returns_validation_error()
  143. {
  144. $response = $this->actingAs($this->admin, 'api-guard')
  145. ->json('POST', '/api/v1/settings', [
  146. 'key' => null,
  147. 'value' => null,
  148. ])
  149. ->assertStatus(422);
  150. }
  151. #[Test]
  152. public function test_store_existing_custom_user_setting_returns_validation_error()
  153. {
  154. Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
  155. $response = $this->actingAs($this->admin, 'api-guard')
  156. ->json('POST', '/api/v1/settings', [
  157. 'key' => self::USER_DEFINED_SETTING,
  158. 'value' => self::USER_DEFINED_SETTING_VALUE,
  159. ])
  160. ->assertStatus(422);
  161. }
  162. #[Test]
  163. public function test_update_unchanged_native_setting_returns_updated_setting()
  164. {
  165. $response = $this->actingAs($this->admin, 'api-guard')
  166. ->json('PUT', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING, [
  167. 'value' => self::TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE,
  168. ])
  169. ->assertOk()
  170. ->assertExactJson([
  171. 'key' => self::TWOFAUTH_NATIVE_SETTING,
  172. 'value' => self::TWOFAUTH_NATIVE_SETTING_CHANGED_VALUE,
  173. ]);
  174. }
  175. #[Test]
  176. public function test_update_custom_user_setting_returns_updated_setting()
  177. {
  178. Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
  179. $response = $this->actingAs($this->admin, 'api-guard')
  180. ->json('PUT', '/api/v1/settings/' . self::USER_DEFINED_SETTING, [
  181. 'value' => self::USER_DEFINED_SETTING_CHANGED_VALUE,
  182. ])
  183. ->assertOk()
  184. ->assertExactJson([
  185. 'key' => self::USER_DEFINED_SETTING,
  186. 'value' => self::USER_DEFINED_SETTING_CHANGED_VALUE,
  187. ]);
  188. }
  189. #[Test]
  190. public function test_update_missing_user_setting_returns_created_setting()
  191. {
  192. $response = $this->actingAs($this->admin, 'api-guard')
  193. ->json('PUT', '/api/v1/settings/' . self::USER_DEFINED_SETTING, [
  194. 'value' => self::USER_DEFINED_SETTING_CHANGED_VALUE,
  195. ])
  196. ->assertOk()
  197. ->assertExactJson([
  198. 'key' => self::USER_DEFINED_SETTING,
  199. 'value' => self::USER_DEFINED_SETTING_CHANGED_VALUE,
  200. ]);
  201. }
  202. #[Test]
  203. public function test_update_restrictList_setting_rejects_invalid_email_list()
  204. {
  205. $response = $this->actingAs($this->admin, 'api-guard')
  206. ->json('PUT', '/api/v1/settings/restrictList', [
  207. 'value' => 'johndoe@example.com|janedoeexamplecom',
  208. ])
  209. ->assertJsonValidationErrorFor('value');
  210. }
  211. #[Test]
  212. public function test_destroy_user_setting_returns_success()
  213. {
  214. Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
  215. $response = $this->actingAs($this->admin, 'api-guard')
  216. ->json('DELETE', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
  217. ->assertNoContent();
  218. }
  219. #[Test]
  220. public function test_destroy_native_setting_returns_bad_request()
  221. {
  222. $response = $this->actingAs($this->admin, 'api-guard')
  223. ->json('DELETE', '/api/v1/settings/' . self::TWOFAUTH_NATIVE_SETTING)
  224. ->assertStatus(400)
  225. ->assertJsonStructure([
  226. 'message',
  227. 'reason',
  228. ]);
  229. }
  230. #[Test]
  231. public function test_destroy_missing_user_setting_returns_not_found()
  232. {
  233. $response = $this->actingAs($this->admin, 'api-guard')
  234. ->json('DELETE', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
  235. ->assertNotFound();
  236. }
  237. #[Test]
  238. public function test_destroy_is_forbidden_to_users()
  239. {
  240. Settings::set(self::USER_DEFINED_SETTING, self::USER_DEFINED_SETTING_VALUE);
  241. $response = $this->actingAs($this->user, 'api-guard')
  242. ->json('DELETE', '/api/v1/settings/' . self::USER_DEFINED_SETTING)
  243. ->assertForbidden()
  244. ->assertJsonStructure([
  245. 'message',
  246. ]);
  247. }
  248. }