SparePartOrderControllerTest.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. <?php
  2. namespace Tests\Feature;
  3. use App\Models\Reservation;
  4. use App\Models\Role;
  5. use App\Models\SparePart;
  6. use App\Models\SparePartOrder;
  7. use App\Models\User;
  8. use Illuminate\Foundation\Testing\RefreshDatabase;
  9. use Tests\TestCase;
  10. class SparePartOrderControllerTest extends TestCase
  11. {
  12. use RefreshDatabase;
  13. protected $seed = true;
  14. private User $adminUser;
  15. private User $managerUser;
  16. protected function setUp(): void
  17. {
  18. parent::setUp();
  19. $this->adminUser = User::factory()->create(['role' => Role::ADMIN]);
  20. $this->managerUser = User::factory()->create(['role' => Role::MANAGER]);
  21. }
  22. private function assertRedirectsToShowWithGeneratedNav($response, SparePartOrder $sparePartOrder): void
  23. {
  24. $location = $response->headers->get('Location');
  25. $this->assertNotNull($location);
  26. $this->assertStringStartsWith(route('spare_part_orders.show', $sparePartOrder), $location);
  27. $this->assertStringContainsString('nav=', $location);
  28. }
  29. // ==================== Authentication ====================
  30. public function test_guest_cannot_access_spare_part_orders_index(): void
  31. {
  32. $response = $this->get(route('spare_part_orders.index'));
  33. $response->assertRedirect(route('login'));
  34. }
  35. public function test_guest_cannot_access_spare_part_order_create(): void
  36. {
  37. $response = $this->get(route('spare_part_orders.create'));
  38. $response->assertRedirect(route('login'));
  39. }
  40. public function test_guest_cannot_store_spare_part_order(): void
  41. {
  42. $response = $this->post(route('spare_part_orders.store'), []);
  43. $response->assertRedirect(route('login'));
  44. }
  45. // ==================== Index ====================
  46. public function test_admin_can_access_spare_part_orders_index(): void
  47. {
  48. $response = $this->actingAs($this->adminUser)
  49. ->get(route('spare_part_orders.index'));
  50. $response->assertStatus(200);
  51. $response->assertViewIs('spare_parts.index');
  52. }
  53. public function test_manager_can_access_spare_part_orders_index(): void
  54. {
  55. $response = $this->actingAs($this->managerUser)
  56. ->get(route('spare_part_orders.index'));
  57. $response->assertStatus(200);
  58. $response->assertViewIs('spare_parts.index');
  59. }
  60. public function test_index_passes_only_ordered_order_numbers_to_view(): void
  61. {
  62. SparePartOrder::factory()->ordered()->create([
  63. 'order_number' => 'SP-BULK-001',
  64. ]);
  65. SparePartOrder::factory()->ordered()->create([
  66. 'order_number' => 'SP-BULK-001',
  67. ]);
  68. SparePartOrder::factory()->ordered()->create([
  69. 'order_number' => 'SP-BULK-002',
  70. ]);
  71. SparePartOrder::factory()->inStock()->create([
  72. 'order_number' => 'SP-IN-STOCK-001',
  73. ]);
  74. SparePartOrder::factory()->ordered()->create([
  75. 'order_number' => '',
  76. ]);
  77. SparePartOrder::factory()->ordered()->create([
  78. 'order_number' => null,
  79. ]);
  80. $response = $this->actingAs($this->adminUser)
  81. ->get(route('spare_part_orders.index'));
  82. $response->assertStatus(200);
  83. $response->assertViewHas('order_numbers', function ($orderNumbers) {
  84. return $orderNumbers->values()->all() === ['SP-BULK-001', 'SP-BULK-002'];
  85. });
  86. }
  87. // ==================== Show ====================
  88. public function test_admin_can_view_spare_part_order(): void
  89. {
  90. $sparePartOrder = SparePartOrder::factory()->create();
  91. $response = $this->actingAs($this->adminUser)
  92. ->get(route('spare_part_orders.show', $sparePartOrder));
  93. $response->assertStatus(200);
  94. $response->assertViewIs('spare_part_orders.edit');
  95. }
  96. public function test_manager_can_view_spare_part_order(): void
  97. {
  98. $sparePartOrder = SparePartOrder::factory()->create();
  99. $response = $this->actingAs($this->managerUser)
  100. ->get(route('spare_part_orders.show', $sparePartOrder));
  101. $response->assertStatus(200);
  102. $response->assertViewIs('spare_part_orders.edit');
  103. }
  104. public function test_spare_part_order_show_uses_nav_context_back_url(): void
  105. {
  106. $sparePartOrder = SparePartOrder::factory()->create();
  107. $indexResponse = $this->actingAs($this->adminUser)
  108. ->get(route('spare_part_orders.index', [
  109. 'spare_part_id' => $sparePartOrder->spare_part_id,
  110. ]));
  111. $nav = $indexResponse->viewData('nav');
  112. $response = $this->actingAs($this->adminUser)
  113. ->get(route('spare_part_orders.show', [
  114. 'sparePartOrder' => $sparePartOrder,
  115. 'nav' => $nav,
  116. ]));
  117. $response->assertOk();
  118. $response->assertViewHas('nav', $nav);
  119. $response->assertViewHas('back_url', function (string $backUrl) use ($sparePartOrder): bool {
  120. if (!str_starts_with($backUrl, route('spare_part_orders.index'))) {
  121. return false;
  122. }
  123. $query = parse_url($backUrl, PHP_URL_QUERY);
  124. parse_str((string) $query, $params);
  125. return (int) ($params['spare_part_id'] ?? 0) === (int) $sparePartOrder->spare_part_id;
  126. });
  127. }
  128. public function test_ordered_spare_part_order_page_renders_set_in_stock_button_with_separate_form(): void
  129. {
  130. $sparePartOrder = SparePartOrder::factory()->ordered()->create();
  131. $response = $this->actingAs($this->managerUser)
  132. ->get(route('spare_part_orders.show', $sparePartOrder));
  133. $response->assertStatus(200);
  134. $response->assertSee('form="set-in-stock-form"', false);
  135. $response->assertSee('id="set-in-stock-form"', false);
  136. $response->assertSee(route('spare_part_orders.set_in_stock', $sparePartOrder), false);
  137. }
  138. public function test_guest_cannot_view_spare_part_order(): void
  139. {
  140. $sparePartOrder = SparePartOrder::factory()->create();
  141. $response = $this->get(route('spare_part_orders.show', $sparePartOrder));
  142. $response->assertRedirect(route('login'));
  143. }
  144. // ==================== Create ====================
  145. public function test_admin_can_access_create_form(): void
  146. {
  147. $response = $this->actingAs($this->adminUser)
  148. ->get(route('spare_part_orders.create'));
  149. $response->assertStatus(200);
  150. $response->assertViewIs('spare_part_orders.edit');
  151. }
  152. public function test_manager_can_access_create_form(): void
  153. {
  154. $response = $this->actingAs($this->managerUser)
  155. ->get(route('spare_part_orders.create'));
  156. $response->assertStatus(200);
  157. $response->assertViewIs('spare_part_orders.edit');
  158. }
  159. // ==================== Store ====================
  160. public function test_admin_can_create_spare_part_order(): void
  161. {
  162. $sparePart = SparePart::factory()->create();
  163. $response = $this->actingAs($this->adminUser)
  164. ->post(route('spare_part_orders.store'), [
  165. 'spare_part_id' => $sparePart->id,
  166. 'status' => SparePartOrder::STATUS_ORDERED,
  167. 'ordered_quantity' => 10,
  168. 'source_text' => 'Test Supplier',
  169. ]);
  170. $response->assertRedirect();
  171. $response->assertSessionHas('success');
  172. $this->assertDatabaseHas('spare_part_orders', [
  173. 'spare_part_id' => $sparePart->id,
  174. 'status' => SparePartOrder::STATUS_ORDERED,
  175. 'ordered_quantity' => 10,
  176. ]);
  177. }
  178. public function test_store_spare_part_order_redirects_to_parent_url_from_nav_context(): void
  179. {
  180. $sparePart = SparePart::factory()->create();
  181. $response = $this->actingAs($this->adminUser)
  182. ->withSession([
  183. 'navigation' => [
  184. 'spare-part-order-nav-token' => [
  185. 'updated_at' => time(),
  186. 'stack' => [
  187. route('spare_part_orders.index'),
  188. route('spare_part_orders.create'),
  189. ],
  190. ],
  191. ],
  192. ])
  193. ->post(route('spare_part_orders.store'), [
  194. 'nav' => 'spare-part-order-nav-token',
  195. 'spare_part_id' => $sparePart->id,
  196. 'status' => SparePartOrder::STATUS_ORDERED,
  197. 'ordered_quantity' => 10,
  198. 'source_text' => 'Test Supplier',
  199. ]);
  200. $response->assertRedirect(route('spare_part_orders.index'));
  201. }
  202. public function test_manager_can_create_spare_part_order(): void
  203. {
  204. $sparePart = SparePart::factory()->create();
  205. $response = $this->actingAs($this->managerUser)
  206. ->post(route('spare_part_orders.store'), [
  207. 'spare_part_id' => $sparePart->id,
  208. 'status' => SparePartOrder::STATUS_ORDERED,
  209. 'ordered_quantity' => 5,
  210. ]);
  211. $response->assertRedirect();
  212. $response->assertSessionHas('success');
  213. }
  214. public function test_store_validates_required_spare_part_id(): void
  215. {
  216. $response = $this->actingAs($this->adminUser)
  217. ->post(route('spare_part_orders.store'), [
  218. 'status' => SparePartOrder::STATUS_ORDERED,
  219. 'ordered_quantity' => 10,
  220. ]);
  221. $response->assertSessionHasErrors('spare_part_id');
  222. }
  223. public function test_store_validates_required_ordered_quantity(): void
  224. {
  225. $sparePart = SparePart::factory()->create();
  226. $response = $this->actingAs($this->adminUser)
  227. ->post(route('spare_part_orders.store'), [
  228. 'spare_part_id' => $sparePart->id,
  229. 'status' => SparePartOrder::STATUS_ORDERED,
  230. ]);
  231. $response->assertSessionHasErrors('ordered_quantity');
  232. }
  233. // ==================== Update ====================
  234. public function test_admin_can_update_spare_part_order(): void
  235. {
  236. $sparePartOrder = SparePartOrder::factory()->ordered()->create();
  237. $response = $this->actingAs($this->adminUser)
  238. ->put(route('spare_part_orders.update', $sparePartOrder), [
  239. 'spare_part_id' => $sparePartOrder->spare_part_id,
  240. 'status' => SparePartOrder::STATUS_ORDERED,
  241. 'ordered_quantity' => 20,
  242. 'order_number' => 'ORD-2024-001',
  243. ]);
  244. $response->assertRedirect();
  245. $response->assertSessionHas('success');
  246. $this->assertDatabaseHas('spare_part_orders', [
  247. 'id' => $sparePartOrder->id,
  248. 'ordered_quantity' => 20,
  249. 'order_number' => 'ORD-2024-001',
  250. ]);
  251. }
  252. public function test_update_spare_part_order_redirects_to_parent_url_from_nav_context(): void
  253. {
  254. $sparePartOrder = SparePartOrder::factory()->ordered()->create();
  255. $response = $this->actingAs($this->adminUser)
  256. ->withSession([
  257. 'navigation' => [
  258. 'spare-part-order-update-token' => [
  259. 'updated_at' => time(),
  260. 'stack' => [
  261. route('spare_part_orders.index'),
  262. route('spare_part_orders.show', $sparePartOrder),
  263. ],
  264. ],
  265. ],
  266. ])
  267. ->put(route('spare_part_orders.update', $sparePartOrder), [
  268. 'nav' => 'spare-part-order-update-token',
  269. 'spare_part_id' => $sparePartOrder->spare_part_id,
  270. 'status' => SparePartOrder::STATUS_ORDERED,
  271. 'ordered_quantity' => 21,
  272. ]);
  273. $response->assertRedirect(route('spare_part_orders.index'));
  274. }
  275. public function test_manager_can_update_spare_part_order(): void
  276. {
  277. $sparePartOrder = SparePartOrder::factory()->ordered()->create();
  278. $response = $this->actingAs($this->managerUser)
  279. ->put(route('spare_part_orders.update', $sparePartOrder), [
  280. 'spare_part_id' => $sparePartOrder->spare_part_id,
  281. 'status' => SparePartOrder::STATUS_ORDERED,
  282. 'ordered_quantity' => 15,
  283. ]);
  284. $response->assertRedirect();
  285. $response->assertSessionHas('success');
  286. }
  287. public function test_guest_cannot_update_spare_part_order(): void
  288. {
  289. $sparePartOrder = SparePartOrder::factory()->create();
  290. $response = $this->put(route('spare_part_orders.update', $sparePartOrder), []);
  291. $response->assertRedirect(route('login'));
  292. }
  293. // ==================== Destroy ====================
  294. public function test_admin_can_delete_spare_part_order_without_active_reservations(): void
  295. {
  296. $sparePartOrder = SparePartOrder::factory()->create();
  297. $response = $this->actingAs($this->adminUser)
  298. ->delete(route('spare_part_orders.destroy', $sparePartOrder));
  299. $response->assertRedirect(route('spare_part_orders.index'));
  300. $response->assertSessionHas('success');
  301. $this->assertSoftDeleted('spare_part_orders', ['id' => $sparePartOrder->id]);
  302. }
  303. public function test_admin_cannot_delete_spare_part_order_with_active_reservations(): void
  304. {
  305. $sparePartOrder = SparePartOrder::factory()->inStock()->create();
  306. Reservation::factory()->create([
  307. 'spare_part_order_id' => $sparePartOrder->id,
  308. 'spare_part_id' => $sparePartOrder->spare_part_id,
  309. 'status' => Reservation::STATUS_ACTIVE,
  310. ]);
  311. $response = $this->actingAs($this->adminUser)
  312. ->delete(route('spare_part_orders.destroy', $sparePartOrder));
  313. $this->assertRedirectsToShowWithGeneratedNav($response, $sparePartOrder);
  314. $response->assertSessionHas('error');
  315. $this->assertDatabaseHas('spare_part_orders', ['id' => $sparePartOrder->id, 'deleted_at' => null]);
  316. }
  317. public function test_manager_cannot_delete_spare_part_order(): void
  318. {
  319. $sparePartOrder = SparePartOrder::factory()->create();
  320. $response = $this->actingAs($this->managerUser)
  321. ->delete(route('spare_part_orders.destroy', $sparePartOrder));
  322. $response->assertStatus(403);
  323. }
  324. public function test_guest_cannot_delete_spare_part_order(): void
  325. {
  326. $sparePartOrder = SparePartOrder::factory()->create();
  327. $response = $this->delete(route('spare_part_orders.destroy', $sparePartOrder));
  328. $response->assertRedirect(route('login'));
  329. }
  330. // ==================== SetInStock ====================
  331. public function test_admin_can_set_order_in_stock(): void
  332. {
  333. $sparePartOrder = SparePartOrder::factory()->ordered()->create();
  334. $response = $this->actingAs($this->adminUser)
  335. ->withSession([
  336. 'navigation' => [
  337. 'set-in-stock-nav-token' => [
  338. 'updated_at' => time(),
  339. 'stack' => [
  340. route('spare_part_orders.index'),
  341. route('spare_part_orders.show', $sparePartOrder),
  342. ],
  343. ],
  344. ],
  345. ])
  346. ->post(route('spare_part_orders.set_in_stock', [
  347. 'sparePartOrder' => $sparePartOrder,
  348. 'nav' => 'set-in-stock-nav-token',
  349. ]));
  350. $response->assertRedirect(route('spare_part_orders.show', [
  351. 'sparePartOrder' => $sparePartOrder,
  352. 'nav' => 'set-in-stock-nav-token',
  353. ]));
  354. $response->assertSessionHas('success');
  355. $this->assertDatabaseHas('spare_part_orders', [
  356. 'id' => $sparePartOrder->id,
  357. 'status' => SparePartOrder::STATUS_IN_STOCK,
  358. ]);
  359. }
  360. public function test_manager_can_set_order_in_stock(): void
  361. {
  362. $sparePartOrder = SparePartOrder::factory()->ordered()->create();
  363. $response = $this->actingAs($this->managerUser)
  364. ->withSession([
  365. 'navigation' => [
  366. 'set-in-stock-manager-token' => [
  367. 'updated_at' => time(),
  368. 'stack' => [
  369. route('spare_part_orders.index'),
  370. route('spare_part_orders.show', $sparePartOrder),
  371. ],
  372. ],
  373. ],
  374. ])
  375. ->post(route('spare_part_orders.set_in_stock', [
  376. 'sparePartOrder' => $sparePartOrder,
  377. 'nav' => 'set-in-stock-manager-token',
  378. ]));
  379. $response->assertRedirect(route('spare_part_orders.show', [
  380. 'sparePartOrder' => $sparePartOrder,
  381. 'nav' => 'set-in-stock-manager-token',
  382. ]));
  383. $response->assertSessionHas('success');
  384. }
  385. public function test_guest_cannot_set_order_in_stock(): void
  386. {
  387. $sparePartOrder = SparePartOrder::factory()->create();
  388. $response = $this->post(route('spare_part_orders.set_in_stock', $sparePartOrder));
  389. $response->assertRedirect(route('login'));
  390. }
  391. public function test_admin_can_set_whole_order_in_stock_by_order_number(): void
  392. {
  393. $first = SparePartOrder::factory()->ordered()->create([
  394. 'order_number' => 'SP-BULK-100',
  395. ]);
  396. $second = SparePartOrder::factory()->ordered()->create([
  397. 'order_number' => 'SP-BULK-100',
  398. ]);
  399. $sameNumberInStock = SparePartOrder::factory()->inStock()->create([
  400. 'order_number' => 'SP-BULK-100',
  401. ]);
  402. $other = SparePartOrder::factory()->ordered()->create([
  403. 'order_number' => 'SP-BULK-200',
  404. ]);
  405. $response = $this->actingAs($this->adminUser)
  406. ->post(route('spare_part_orders.set_order_in_stock'), [
  407. 'bulk_order_number' => 'SP-BULK-100',
  408. ]);
  409. $response->assertRedirect(route('spare_part_orders.index'));
  410. $response->assertSessionHas('success');
  411. $this->assertDatabaseHas('spare_part_orders', [
  412. 'id' => $first->id,
  413. 'status' => SparePartOrder::STATUS_IN_STOCK,
  414. ]);
  415. $this->assertDatabaseHas('spare_part_orders', [
  416. 'id' => $second->id,
  417. 'status' => SparePartOrder::STATUS_IN_STOCK,
  418. ]);
  419. $this->assertDatabaseHas('spare_part_orders', [
  420. 'id' => $sameNumberInStock->id,
  421. 'status' => SparePartOrder::STATUS_IN_STOCK,
  422. ]);
  423. $this->assertDatabaseHas('spare_part_orders', [
  424. 'id' => $other->id,
  425. 'status' => SparePartOrder::STATUS_ORDERED,
  426. ]);
  427. }
  428. public function test_bulk_set_order_in_stock_validates_selected_number_has_ordered_rows(): void
  429. {
  430. SparePartOrder::factory()->inStock()->create([
  431. 'order_number' => 'SP-NOT-ORDERED',
  432. ]);
  433. $response = $this->from(route('spare_part_orders.index'))
  434. ->actingAs($this->adminUser)
  435. ->post(route('spare_part_orders.set_order_in_stock'), [
  436. 'bulk_order_number' => 'SP-NOT-ORDERED',
  437. ]);
  438. $response->assertRedirect(route('spare_part_orders.index'));
  439. $response->assertSessionHasErrors('bulk_order_number');
  440. }
  441. // ==================== Ship ====================
  442. public function test_admin_can_ship_spare_part_order(): void
  443. {
  444. $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(20)->create();
  445. $response = $this->actingAs($this->adminUser)
  446. ->post(route('spare_part_orders.ship', $sparePartOrder), [
  447. 'quantity' => 5,
  448. 'note' => 'Тестовая отгрузка',
  449. ]);
  450. $this->assertRedirectsToShowWithGeneratedNav($response, $sparePartOrder);
  451. $response->assertSessionHas('success');
  452. $this->assertDatabaseHas('spare_part_orders', [
  453. 'id' => $sparePartOrder->id,
  454. 'available_qty' => 15,
  455. ]);
  456. }
  457. public function test_ship_fails_if_quantity_exceeds_available(): void
  458. {
  459. $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(3)->create();
  460. $response = $this->actingAs($this->adminUser)
  461. ->post(route('spare_part_orders.ship', $sparePartOrder), [
  462. 'quantity' => 10,
  463. 'note' => 'Попытка отгрузить больше чем есть',
  464. ]);
  465. $this->assertRedirectsToShowWithGeneratedNav($response, $sparePartOrder);
  466. $response->assertSessionHas('error');
  467. $this->assertDatabaseHas('spare_part_orders', [
  468. 'id' => $sparePartOrder->id,
  469. 'available_qty' => 3,
  470. ]);
  471. }
  472. public function test_ship_validates_required_quantity(): void
  473. {
  474. $sparePartOrder = SparePartOrder::factory()->inStock()->create();
  475. $response = $this->actingAs($this->adminUser)
  476. ->post(route('spare_part_orders.ship', $sparePartOrder), [
  477. 'note' => 'Без количества',
  478. ]);
  479. $response->assertSessionHasErrors('quantity');
  480. }
  481. public function test_manager_can_ship_spare_part_order(): void
  482. {
  483. $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(10)->create();
  484. $response = $this->actingAs($this->managerUser)
  485. ->post(route('spare_part_orders.ship', $sparePartOrder), [
  486. 'quantity' => 2,
  487. 'note' => 'Отгрузка менеджером',
  488. ]);
  489. $this->assertRedirectsToShowWithGeneratedNav($response, $sparePartOrder);
  490. $response->assertSessionHas('success');
  491. }
  492. public function test_guest_cannot_ship_spare_part_order(): void
  493. {
  494. $sparePartOrder = SparePartOrder::factory()->create();
  495. $response = $this->post(route('spare_part_orders.ship', $sparePartOrder), [
  496. 'quantity' => 1,
  497. 'note' => 'Test',
  498. ]);
  499. $response->assertRedirect(route('login'));
  500. }
  501. // ==================== Correct (Inventory) ====================
  502. public function test_admin_can_correct_inventory(): void
  503. {
  504. $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(10)->create();
  505. $response = $this->actingAs($this->adminUser)
  506. ->post(route('spare_part_orders.correct', $sparePartOrder), [
  507. 'new_quantity' => 8,
  508. 'reason' => 'Инвентаризация — обнаружена недостача',
  509. ]);
  510. $this->assertRedirectsToShowWithGeneratedNav($response, $sparePartOrder);
  511. $response->assertSessionHas('success');
  512. $this->assertDatabaseHas('spare_part_orders', [
  513. 'id' => $sparePartOrder->id,
  514. 'available_qty' => 8,
  515. ]);
  516. }
  517. public function test_correct_fails_if_quantity_unchanged(): void
  518. {
  519. $sparePartOrder = SparePartOrder::factory()->inStock()->withQuantity(10)->create();
  520. $response = $this->actingAs($this->adminUser)
  521. ->post(route('spare_part_orders.correct', $sparePartOrder), [
  522. 'new_quantity' => 10,
  523. 'reason' => 'Без изменений',
  524. ]);
  525. $this->assertRedirectsToShowWithGeneratedNav($response, $sparePartOrder);
  526. $response->assertSessionHas('error');
  527. }
  528. public function test_manager_cannot_correct_inventory(): void
  529. {
  530. $sparePartOrder = SparePartOrder::factory()->inStock()->create();
  531. $response = $this->actingAs($this->managerUser)
  532. ->post(route('spare_part_orders.correct', $sparePartOrder), [
  533. 'new_quantity' => 5,
  534. 'reason' => 'Test',
  535. ]);
  536. $response->assertStatus(403);
  537. }
  538. public function test_guest_cannot_correct_inventory(): void
  539. {
  540. $sparePartOrder = SparePartOrder::factory()->create();
  541. $response = $this->post(route('spare_part_orders.correct', $sparePartOrder), [
  542. 'new_quantity' => 5,
  543. 'reason' => 'Test',
  544. ]);
  545. $response->assertRedirect(route('login'));
  546. }
  547. }