179 lines
6.3 KiB
PHP
179 lines
6.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
usesApiSuite();
|
|
|
|
function daily_report_product_from_overview(array $overview, int $productId): array
|
|
{
|
|
foreach (($overview['products'] ?? []) as $product) {
|
|
if ((int)($product['product_id'] ?? 0) === $productId) {
|
|
return $product;
|
|
}
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
it('stores clears and permission-gates department daily report product targets', function (): void {
|
|
api_test_covers('PUT /departments/daily-reports/product-targets', 'happy');
|
|
api_test_covers('GET /departments/daily-reports/overview', 'happy');
|
|
|
|
$department = api_fixtures()->createDepartment([
|
|
'name' => 'Daily Report Product Target ' . uniqid('', false),
|
|
]);
|
|
$departmentId = (int)$department['id'];
|
|
$editorPermissions = [
|
|
'list_department_daily_reports',
|
|
'list_bookings',
|
|
'set_department_daily_report_product_targets',
|
|
'department_access_' . $departmentId,
|
|
];
|
|
$editorSession = api_fixtures()->createUserSession($editorPermissions);
|
|
$viewerSession = api_fixtures()->createUserSession([
|
|
'list_department_daily_reports',
|
|
'list_bookings',
|
|
'department_access_' . $departmentId,
|
|
]);
|
|
|
|
try {
|
|
$saveResponse = api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => 47.55,
|
|
], $editorSession['headers']);
|
|
|
|
$saveResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
expect($saveResponse->data())->toMatchArray([
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => 47.6,
|
|
]);
|
|
|
|
$overviewResponse = api_client()->get(
|
|
'/departments/daily-reports/overview?date=2026-07-06&department_ids=' . $departmentId,
|
|
$editorSession['headers']
|
|
);
|
|
|
|
$overviewResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
$editorProduct = daily_report_product_from_overview($overviewResponse->data(), 24);
|
|
expect($editorProduct['target_percentage'])->toBe(47.6);
|
|
expect($editorProduct['target_department_id'])->toBe($departmentId);
|
|
|
|
$viewerOverviewResponse = api_client()->get(
|
|
'/departments/daily-reports/overview?date=2026-07-06&department_ids=' . $departmentId,
|
|
$viewerSession['headers']
|
|
);
|
|
|
|
$viewerOverviewResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
$viewerProduct = daily_report_product_from_overview($viewerOverviewResponse->data(), 24);
|
|
expect($viewerProduct['target_percentage'])->toBeNull();
|
|
expect($viewerProduct['target_department_id'])->toBeNull();
|
|
|
|
$clearResponse = api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => null,
|
|
], $editorSession['headers']);
|
|
|
|
$clearResponse
|
|
->assertStatus(200)
|
|
->assertEnvelope()
|
|
->assertSuccess();
|
|
|
|
expect($clearResponse->data())->toMatchArray([
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => null,
|
|
]);
|
|
|
|
$clearedOverviewResponse = api_client()->get(
|
|
'/departments/daily-reports/overview?date=2026-07-06&department_ids=' . $departmentId,
|
|
$editorSession['headers']
|
|
);
|
|
|
|
$clearedProduct = daily_report_product_from_overview($clearedOverviewResponse->data(), 24);
|
|
expect($clearedProduct['target_percentage'])->toBeNull();
|
|
expect($clearedProduct['target_department_id'])->toBeNull();
|
|
} finally {
|
|
api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => null,
|
|
], $editorSession['headers']);
|
|
}
|
|
});
|
|
|
|
it('rejects product target updates without permission access or valid input', function (): void {
|
|
api_test_covers('PUT /departments/daily-reports/product-targets', 'auth');
|
|
api_test_covers('PUT /departments/daily-reports/product-targets', 'failure');
|
|
|
|
$department = api_fixtures()->createDepartment();
|
|
$departmentId = (int)$department['id'];
|
|
|
|
$missingPermissionSession = api_fixtures()->createUserSession([
|
|
'department_access_' . $departmentId,
|
|
]);
|
|
|
|
api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => 50,
|
|
], $missingPermissionSession['headers'])
|
|
->assertStatus(403)
|
|
->assertEnvelope()
|
|
->assertSuccess(false)
|
|
->assertMissingPermissions(['set_department_daily_report_product_targets']);
|
|
|
|
$missingDepartmentAccessSession = api_fixtures()->createUserSession([
|
|
'set_department_daily_report_product_targets',
|
|
]);
|
|
|
|
api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => 50,
|
|
], $missingDepartmentAccessSession['headers'])
|
|
->assertStatus(403)
|
|
->assertEnvelope()
|
|
->assertSuccess(false)
|
|
->assertMissingPermissions(['department_access_' . $departmentId]);
|
|
|
|
$editorSession = api_fixtures()->createUserSession([
|
|
'set_department_daily_report_product_targets',
|
|
'department_access_' . $departmentId,
|
|
]);
|
|
|
|
api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 999999,
|
|
'target_percentage' => 50,
|
|
], $editorSession['headers'])
|
|
->assertStatus(400)
|
|
->assertEnvelope()
|
|
->assertSuccess(false)
|
|
->assertMessage('Invalid daily report product_id');
|
|
|
|
api_client()->put('/departments/daily-reports/product-targets', [
|
|
'department_id' => $departmentId,
|
|
'product_id' => 24,
|
|
'target_percentage' => 101,
|
|
], $editorSession['headers'])
|
|
->assertStatus(400)
|
|
->assertEnvelope()
|
|
->assertSuccess(false)
|
|
->assertMessage('Parameter target_percentage must be between 0 and 100');
|
|
});
|