From da05c5adb7eb244b399e7b0cba1aa9992617fae9 Mon Sep 17 00:00:00 2001 From: Jeppe B <2jepp9350@gmail.com> Date: Mon, 1 Jun 2026 16:31:06 +0200 Subject: [PATCH] Restore selected orders API coverage --- .../nginx/app/tests/Api/OrdersApiTest.php | 227 ++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 services/nginx/app/tests/Api/OrdersApiTest.php diff --git a/services/nginx/app/tests/Api/OrdersApiTest.php b/services/nginx/app/tests/Api/OrdersApiTest.php new file mode 100644 index 00000000..6e65d063 --- /dev/null +++ b/services/nginx/app/tests/Api/OrdersApiTest.php @@ -0,0 +1,227 @@ +createDepartment(['name' => 'Orders List Visible']); + $hiddenDepartment = api_fixtures()->createDepartment(['name' => 'Orders List Hidden']); + $visibleCustomer = api_fixtures()->createUser(['display_name' => 'Orders List Visible Customer']); + $hiddenCustomer = api_fixtures()->createUser(['display_name' => 'Orders List Hidden Customer']); + $cashier = api_fixtures()->createUser(['display_name' => 'Orders List Cashier']); + + $visibleOrder = api_fixtures()->createOrder([ + 'customer_id' => $visibleCustomer['customer_number'], + 'cashier_id' => $cashier['id'], + 'department_id' => $visibleDepartment['id'], + 'reference' => 'VISIBLE-ORDER', + 'reg_1' => 'VISIBLE1', + ]); + $hiddenOrder = api_fixtures()->createOrder([ + 'customer_id' => $hiddenCustomer['customer_number'], + 'cashier_id' => $cashier['id'], + 'department_id' => $hiddenDepartment['id'], + 'reference' => 'HIDDEN-ORDER', + 'reg_1' => 'HIDDEN1', + ]); + + $session = api_fixtures()->createUserSession([ + 'list_orders', + 'department_access_' . $visibleDepartment['id'], + ]); + + $response = api_client()->get('/orders', $session['headers']); + + $response + ->assertStatus(200) + ->assertEnvelope() + ->assertSuccess(); + + $orderIds = array_map( + static fn(array $order): int => (int)($order['id'] ?? 0), + is_array($response->data()) ? $response->data() : [] + ); + + expect($orderIds) + ->toContain($visibleOrder['id']) + ->not->toContain($hiddenOrder['id']); +}); + +it('returns auth and permission failures when order listing is not allowed', function (): void { + api_test_covers('GET /orders', 'auth'); + + api_client()->get('/orders') + ->assertStatus(400) + ->assertEnvelope() + ->assertSuccess(false) + ->assertMessage('Invalid session'); + + $session = api_fixtures()->createUserSession([]); + + api_client()->get('/orders', $session['headers']) + ->assertStatus(403) + ->assertEnvelope() + ->assertSuccess(false) + ->assertMissingPermissions(['list_own_orders', 'list_orders']); +}); + +it('creates orders through the orders endpoint', function (): void { + api_test_covers('POST /orders', 'happy'); + + $customer = api_fixtures()->createUser(['display_name' => 'Order Create Customer']); + $department = api_fixtures()->createDepartment(['name' => 'Order Create Department']); + $session = api_fixtures()->createUserSession(['add_order']); + + $response = api_client()->post('/orders', [ + 'customer_id' => $customer['customer_number'], + 'department_id' => $department['id'], + 'reference' => 'ORDER-CREATE', + 'notes' => 'Created through HTTP', + 'reg_1' => ' create-123 ', + 'safety_seal' => 'SEAL-CREATE', + ], $session['headers']); + + $response + ->assertStatus(200) + ->assertEnvelope() + ->assertSuccess(); + + $orderId = (int)($response->data()['id'] ?? 0); + expect($orderId)->toBeGreaterThan(0); + + $row = api_fixtures()->fetchRowById('orders', $orderId); + + expect($row)->not->toBeNull(); + expect($row['reference'] ?? null)->toBe('ORDER-CREATE'); + expect($row['reg_1'] ?? null)->toBe('CREATE123'); + expect($row['safety_seal'] ?? null)->toBe('SEAL-CREATE'); + + api_fixtures()->cleanupDeleteById('orders', $orderId); +}); + +it('rejects invalid order creation requests', function (): void { + api_test_covers('POST /orders', 'failure'); + + $customer = api_fixtures()->createUser(); + $department = api_fixtures()->createDepartment(); + $session = api_fixtures()->createUserSession(['add_order']); + + api_client()->post('/orders', [ + 'customer_id' => $customer['customer_number'], + 'department_id' => $department['id'], + 'notes' => 'Missing reference', + 'reg_1' => 'MISSREF', + ], $session['headers']) + ->assertStatus(400) + ->assertEnvelope() + ->assertSuccess(false) + ->assertMessage('Reference is required'); +}); + +it('updates orders through the primary and legacy endpoints', function (): void { + api_test_covers('PUT /orders', 'happy'); + api_test_covers('PUT /order', 'happy'); + + $department = api_fixtures()->createDepartment(['name' => 'Order Update Department']); + $customer = api_fixtures()->createUser(['display_name' => 'Order Update Customer']); + $cashier = api_fixtures()->createUser(['display_name' => 'Order Update Cashier']); + $order = api_fixtures()->createOrder([ + 'customer_id' => $customer['customer_number'], + 'cashier_id' => $cashier['id'], + 'department_id' => $department['id'], + 'reference' => 'BEFORE-UPDATE', + 'notes' => 'Before update', + 'reg_1' => 'BEFORE1', + ]); + $session = api_fixtures()->createUserSession(['edit_order']); + + api_client()->put('/orders', [ + 'id' => $order['id'], + 'reference' => 'AFTER-UPDATE', + 'notes' => 'After update', + 'reg_1' => ' after-123 ', + ], $session['headers']) + ->assertStatus(200) + ->assertEnvelope() + ->assertSuccess() + ->assertMessage('Order updated successfully'); + + api_client()->put('/order', [ + 'id' => $order['id'], + 'field' => 'reg_2', + 'value' => ' legacy-456 ', + ], $session['headers']) + ->assertStatus(200) + ->assertEnvelope() + ->assertSuccess() + ->assertMessage('Order updated successfully'); + + $row = api_fixtures()->fetchRowById('orders', (int)$order['id']); + + expect($row)->not->toBeNull(); + expect($row['reference'] ?? null)->toBe('AFTER-UPDATE'); + expect($row['notes'] ?? null)->toBe('After update'); + expect($row['reg_1'] ?? null)->toBe('AFTER123'); + expect($row['reg_2'] ?? null)->toBe('LEGACY456'); +}); + +it('rejects invalid order update requests', function (): void { + api_test_covers('PUT /orders', 'failure'); + api_test_covers('PUT /order', 'failure'); + + $session = api_fixtures()->createUserSession(['edit_order']); + + foreach (['/orders', '/order'] as $endpoint) { + api_client()->put($endpoint, [ + 'notes' => 'Missing id', + ], $session['headers']) + ->assertStatus(400) + ->assertEnvelope() + ->assertSuccess(false) + ->assertMessage('ID is required'); + } +}); + +it('deletes orders through the orders endpoint', function (): void { + api_test_covers('DELETE /orders', 'happy'); + + $department = api_fixtures()->createDepartment(['name' => 'Order Delete Department']); + $customer = api_fixtures()->createUser(['display_name' => 'Order Delete Customer']); + $cashier = api_fixtures()->createUser(['display_name' => 'Order Delete Cashier']); + $order = api_fixtures()->createOrder([ + 'customer_id' => $customer['customer_number'], + 'cashier_id' => $cashier['id'], + 'department_id' => $department['id'], + ]); + $session = api_fixtures()->createUserSession([ + 'delete_order', + 'department_access_' . $department['id'], + ]); + + api_client()->delete('/orders', [ + 'id' => $order['id'], + ], $session['headers']) + ->assertStatus(200) + ->assertEnvelope() + ->assertSuccess() + ->assertMessage('Order deleted successfully'); + + $row = api_fixtures()->fetchRowById('orders', (int)$order['id']); + expect($row)->not->toBeNull(); + expect($row['deleted_at'] ?? null)->not->toBeNull(); +}); + +it('rejects invalid order delete requests', function (): void { + api_test_covers('DELETE /orders', 'failure'); + + $session = api_fixtures()->createUserSession(['delete_order']); + + api_client()->delete('/orders', [], $session['headers']) + ->assertStatus(400) + ->assertEnvelope() + ->assertSuccess(false) + ->assertMessage('ID is required'); +});