Files
api/services/nginx/app/tests/Api/DepartmentsApiTest.php
T

325 lines
10 KiB
PHP

<?php
declare(strict_types=1);
usesApiSuite();
it('lists only visible departments and can return a single department with the slack webhook', function (): void {
api_test_covers('GET /departments', 'happy');
$session = api_fixtures()->createUserSession([
'list_departments',
'view_slack_webhook',
]);
$visibleDepartment = api_fixtures()->createDepartment([
'name' => 'Visible Department',
'visible' => 1,
]);
$hiddenDepartment = api_fixtures()->createDepartment([
'name' => 'Hidden Department',
'visible' => 0,
]);
$archivedDepartment = api_fixtures()->createDepartment([
'name' => 'Archived Department',
'visible' => 1,
'archived' => 1,
]);
$webhookDepartment = api_fixtures()->createDepartment([
'name' => 'Webhook Department',
'slack_webhook' => 'https://hooks.slack.test/example',
'visible' => 1,
]);
$listResponse = api_client()->get('/departments', $session['headers']);
$listResponse
->assertStatus(200)
->assertEnvelope()
->assertSuccess();
$departmentIds = array_map(
static fn(array $department): int => (int)($department['id'] ?? 0),
is_array($listResponse->data()) ? $listResponse->data() : []
);
expect($departmentIds)
->toContain($visibleDepartment['id'])
->toContain($webhookDepartment['id'])
->not->toContain($hiddenDepartment['id'])
->not->toContain($archivedDepartment['id']);
$singleResponse = api_client()->get('/departments?id=' . $webhookDepartment['id'], $session['headers']);
$singleResponse
->assertStatus(200)
->assertEnvelope()
->assertSuccess();
expect($singleResponse->data())
->toBeArray()
->toHaveKey('id', $webhookDepartment['id'])
->toHaveKey('slack_webhook', 'https://hooks.slack.test/example');
});
it('allows superusers to filter archived departments', function (): void {
api_test_covers('GET /departments', 'happy');
$session = api_fixtures()->createUserSession([
'list_departments',
'superuser_fetch_department',
]);
$activeDepartment = api_fixtures()->createDepartment([
'name' => 'Active Department',
'visible' => 1,
'archived' => 0,
]);
$archivedDepartment = api_fixtures()->createDepartment([
'name' => 'Archived Department',
'visible' => 1,
'archived' => 1,
]);
$response = api_client()->get('/departments?filters=archived:1', $session['headers']);
$response
->assertStatus(200)
->assertEnvelope()
->assertSuccess();
$departmentIds = array_map(
static fn(array $department): int => (int)($department['id'] ?? 0),
is_array($response->data()) ? $response->data() : []
);
expect($departmentIds)
->toContain($archivedDepartment['id'])
->not->toContain($activeDepartment['id']);
foreach ($response->data() as $department) {
expect((bool)($department['archived'] ?? false))->toBeTrue();
}
});
it('does not allow regular department listings to reveal archived departments through filters', function (): void {
api_test_covers('GET /departments', 'auth');
$session = api_fixtures()->createUserSession(['list_departments']);
$activeDepartment = api_fixtures()->createDepartment([
'name' => 'Regular Active Department',
'visible' => 1,
'archived' => 0,
]);
$archivedDepartment = api_fixtures()->createDepartment([
'name' => 'Regular Archived Department',
'visible' => 1,
'archived' => 1,
]);
$response = api_client()->get('/departments?filters=archived:1', $session['headers']);
$response
->assertStatus(200)
->assertEnvelope()
->assertSuccess();
$departmentIds = array_map(
static fn(array $department): int => (int)($department['id'] ?? 0),
is_array($response->data()) ? $response->data() : []
);
expect($departmentIds)
->toContain($activeDepartment['id'])
->not->toContain($archivedDepartment['id']);
$response = api_client()->get('/departments?filters[name]=NOT%20NULL%2Carchived:1', $session['headers']);
$response
->assertStatus(200)
->assertEnvelope()
->assertSuccess();
$departmentIds = array_map(
static fn(array $department): int => (int)($department['id'] ?? 0),
is_array($response->data()) ? $response->data() : []
);
expect($departmentIds)->not->toContain($archivedDepartment['id']);
});
it('rejects department listing when the permission is missing', function (): void {
api_test_covers('GET /departments', 'auth');
$session = api_fixtures()->createUserSession([]);
$response = api_client()->get('/departments', $session['headers']);
$response
->assertStatus(403)
->assertEnvelope()
->assertSuccess(false)
->assertMissingPermissions(['list_departments']);
});
it('creates departments through the real endpoint', function (): void {
api_test_covers('POST /departments', 'happy');
$session = api_fixtures()->createUserSession(['add_department']);
$name = 'Created Department ' . uniqid('', false);
$response = api_client()->post('/departments', [
'name' => $name,
'description' => 'Created by API test',
], $session['headers']);
$response
->assertStatus(200)
->assertEnvelope()
->assertSuccess()
->assertMessage('Department added successfully');
$createdRow = api_test_runtime()->queryOne(
"SELECT * FROM departments WHERE name = '" . api_test_runtime()->db()->real_escape_string($name) . "' ORDER BY id DESC LIMIT 1"
);
expect($createdRow)->not->toBeNull();
api_fixtures()->cleanupDeleteById('departments', (int)$createdRow['id']);
});
it('rejects invalid department create requests', function (): void {
api_test_covers('POST /departments', 'failure');
$authorizedSession = api_fixtures()->createUserSession(['add_department']);
$missingDescription = api_client()->post('/departments', [
'name' => 'Broken Department',
], $authorizedSession['headers']);
$missingDescription
->assertStatus(400)
->assertEnvelope()
->assertSuccess(false)
->assertMessage('Description is required');
$unauthorizedSession = api_fixtures()->createUserSession([]);
$missingPermission = api_client()->post('/departments', [
'name' => 'No Permission Department',
'description' => 'Should fail',
], $unauthorizedSession['headers']);
$missingPermission
->assertStatus(403)
->assertEnvelope()
->assertSuccess(false)
->assertMissingPermissions(['add_department']);
});
it('updates departments through the real endpoint', function (): void {
api_test_covers('PUT /departments', 'happy');
$session = api_fixtures()->createUserSession(['edit_department']);
$department = api_fixtures()->createDepartment([
'name' => 'Original Department',
'description' => 'Original description',
'order_priority' => 1,
]);
$response = api_client()->put('/departments', [
'id' => $department['id'],
'name' => 'Updated Department',
'description' => 'Updated description',
'order_priority' => 5,
'archived' => true,
'custom_pricing_only' => true,
], $session['headers']);
$response
->assertStatus(200)
->assertEnvelope()
->assertSuccess()
->assertMessage('Department updated successfully');
$row = api_fixtures()->fetchRowById('departments', (int)$department['id']);
expect($row)->not->toBeNull();
expect($row['name'] ?? null)->toBe('Updated Department');
expect($row['description'] ?? null)->toBe('Updated description');
expect((int)($row['order_priority'] ?? 0))->toBe(5);
expect((int)($row['archived'] ?? 0))->toBe(1);
expect((int)($row['custom_pricing_only'] ?? 0))->toBe(1);
});
it('rejects invalid department update requests', function (): void {
api_test_covers('PUT /departments', 'failure');
$authorizedSession = api_fixtures()->createUserSession(['edit_department']);
$missingId = api_client()->put('/departments', [
'name' => 'Missing ID',
], $authorizedSession['headers']);
$missingId
->assertStatus(400)
->assertEnvelope()
->assertSuccess(false)
->assertMessage('Missing required parameters: id');
$unauthorizedSession = api_fixtures()->createUserSession([]);
$missingPermission = api_client()->put('/departments', [
'id' => 123,
'name' => 'No Permission',
], $unauthorizedSession['headers']);
$missingPermission
->assertStatus(403)
->assertEnvelope()
->assertSuccess(false)
->assertMissingPermissions(['edit_department']);
});
it('lists department categories for a department', function (): void {
api_test_covers('GET /departments/categories', 'happy');
$session = api_fixtures()->createUserSession(['list_department_categories']);
$department = api_fixtures()->createDepartment();
$category = api_fixtures()->createCategory([
'name' => 'Department Category',
]);
api_fixtures()->linkDepartmentCategory((int)$department['id'], (int)$category['id']);
$response = api_client()->get('/departments/categories?id=' . $department['id'], $session['headers']);
$response
->assertStatus(200)
->assertEnvelope()
->assertSuccess();
expect($response->data())
->toBeArray()
->toHaveCount(1)
->and($response->data()[0]['department_id'] ?? null)->toBe($department['id'])
->and($response->data()[0]['category']['id'] ?? null)->toBe($category['id']);
});
it('rejects invalid department category requests', function (): void {
api_test_covers('GET /departments/categories', 'failure');
$authorizedSession = api_fixtures()->createUserSession(['list_department_categories']);
$missingId = api_client()->get('/departments/categories', $authorizedSession['headers']);
$missingId
->assertStatus(400)
->assertEnvelope()
->assertSuccess(false)
->assertMessage('Missing required parameters: id');
$unauthorizedSession = api_fixtures()->createUserSession([]);
$missingPermission = api_client()->get('/departments/categories?id=1', $unauthorizedSession['headers']);
$missingPermission
->assertStatus(403)
->assertEnvelope()
->assertSuccess(false)
->assertMissingPermissions(['list_department_categories']);
});