Make limited backoffice employees regular employees
This commit is contained in:
@@ -12,6 +12,18 @@ class limited_backoffice_service
|
||||
public const PERMISSION_MANAGE_PRICES = 'limited_backoffice_prices_manage';
|
||||
public const PERMISSION_MANAGE_EMPLOYEES = 'limited_backoffice_employees_manage';
|
||||
|
||||
private const PERMISSION_PUBLIC_EMPLOYEE_DATA = 'employee_public_data';
|
||||
|
||||
/**
|
||||
* Permissions required for managed employees to sign in and appear in the employee login picker.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private const MANAGED_EMPLOYEE_BASE_PERMISSIONS = [
|
||||
'user',
|
||||
self::PERMISSION_PUBLIC_EMPLOYEE_DATA,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array<string, array{label:string,description:string,permissions:array<int,string>}>
|
||||
*/
|
||||
@@ -255,15 +267,19 @@ class limited_backoffice_service
|
||||
/**
|
||||
* @return array<int, array{key:string,label:string,description:string,permission_groups:array<int,array{key:string,capabilities:array<int,string>}>}>
|
||||
*/
|
||||
public function rolePresets(): array
|
||||
public function rolePresets(?users_o $manager = null): array
|
||||
{
|
||||
$roles = [];
|
||||
foreach (self::ROLE_PRESETS as $key => $preset) {
|
||||
$permissions = $manager === null
|
||||
? $preset['permissions']
|
||||
: $this->effectiveRolePermissionsForManager($manager, $key, false);
|
||||
|
||||
$roles[] = [
|
||||
'key' => $key,
|
||||
'label' => $preset['label'],
|
||||
'description' => $preset['description'],
|
||||
'permission_groups' => $this->rolePermissionGroups($preset['permissions']),
|
||||
'permission_groups' => $this->rolePermissionGroups($permissions),
|
||||
];
|
||||
}
|
||||
return $roles;
|
||||
@@ -677,7 +693,7 @@ class limited_backoffice_service
|
||||
|
||||
try {
|
||||
if ($active) {
|
||||
$this->replaceGroupPermissions($managedGroupId, $this->permissionsForRoleAndDepartments($roleKey, $newDepartmentIds));
|
||||
$this->replaceGroupPermissions($managedGroupId, $this->permissionsForRoleAndDepartments($manager, $roleKey, $newDepartmentIds));
|
||||
}
|
||||
|
||||
$userUpdates = [];
|
||||
@@ -1226,18 +1242,40 @@ class limited_backoffice_service
|
||||
$groupId = (int)$this->mysqli()->insert_id;
|
||||
$statement->close();
|
||||
|
||||
$this->replaceGroupPermissions($groupId, $this->permissionsForRoleAndDepartments($roleKey, $departmentIds));
|
||||
$this->replaceGroupPermissions($groupId, $this->permissionsForRoleAndDepartments($manager, $roleKey, $departmentIds));
|
||||
|
||||
return $groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function effectiveRolePermissionsForManager(users_o $manager, string $roleKey, bool $includePublicVisibility): array
|
||||
{
|
||||
$permissions = $includePublicVisibility ? self::MANAGED_EMPLOYEE_BASE_PERMISSIONS : ['user'];
|
||||
|
||||
foreach (self::ROLE_PRESETS[$roleKey]['permissions'] ?? [] as $permission) {
|
||||
if (in_array($permission, self::MANAGED_EMPLOYEE_BASE_PERMISSIONS, true)) {
|
||||
$permissions[] = $permission;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($manager->hasPermission($permission)) {
|
||||
$permissions[] = $permission;
|
||||
}
|
||||
}
|
||||
|
||||
sort($permissions);
|
||||
return array_values(array_unique($permissions));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, int> $departmentIds
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function permissionsForRoleAndDepartments(string $roleKey, array $departmentIds): array
|
||||
private function permissionsForRoleAndDepartments(users_o $manager, string $roleKey, array $departmentIds): array
|
||||
{
|
||||
$permissions = self::ROLE_PRESETS[$roleKey]['permissions'] ?? [];
|
||||
$permissions = $this->effectiveRolePermissionsForManager($manager, $roleKey, true);
|
||||
foreach ($departmentIds as $departmentId) {
|
||||
$permissions[] = 'department_access_' . $departmentId;
|
||||
}
|
||||
@@ -1356,6 +1394,7 @@ class limited_backoffice_service
|
||||
{
|
||||
return [
|
||||
'id' => (int)$row['user_id'],
|
||||
'user_id' => (int)$row['user_id'],
|
||||
'customer_number' => (int)$row['customer_number'],
|
||||
'display_name' => (string)($row['display_name'] ?? ''),
|
||||
'email' => $row['email'] === null ? null : (string)$row['email'],
|
||||
|
||||
@@ -1077,9 +1077,65 @@ class users_o extends db
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>> $users
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
public function markLimitedBackofficeManagedUsers(array $users): array
|
||||
{
|
||||
$userIds = [];
|
||||
foreach ($users as $user) {
|
||||
$userId = (int)($user['id'] ?? 0);
|
||||
if ($userId > 0) {
|
||||
$userIds[$userId] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($userIds === []) {
|
||||
return $users;
|
||||
}
|
||||
|
||||
global $db;
|
||||
$rows = $db->fetch_all($db->query(
|
||||
'SELECT `user_id` FROM `limited_backoffice_employees` WHERE `user_id` IN (' .
|
||||
implode(',', array_map('intval', array_keys($userIds))) .
|
||||
')'
|
||||
));
|
||||
|
||||
$managedUserIds = [];
|
||||
foreach ($rows as $row) {
|
||||
$managedUserIds[(int)$row['user_id']] = true;
|
||||
}
|
||||
|
||||
foreach ($users as $key => $user) {
|
||||
$users[$key]['limited_backoffice_managed'] = isset($managedUserIds[(int)($user['id'] ?? 0)]);
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
public function isLimitedBackofficeManagedUser(int $userId): bool
|
||||
{
|
||||
if ($userId <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
global $db;
|
||||
$result = $db->query(
|
||||
'SELECT `user_id` FROM `limited_backoffice_employees` WHERE `user_id` = ' . (int)$userId . ' LIMIT 1'
|
||||
);
|
||||
|
||||
return $result !== false && $result->num_rows > 0;
|
||||
}
|
||||
|
||||
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
|
||||
if ((bool)($value['limited_backoffice_managed'] ?? false) || (int)($value['customer_number'] ?? -1) === 0) {
|
||||
$listObjectsWithPaginationIfSet[$key]['customer_name'] = $value['display_name'] ?? null;
|
||||
continue;
|
||||
}
|
||||
|
||||
$listObjectsWithPaginationIfSet[$key]['customer_name'] = $this->getCustomerNameById($value['id']);
|
||||
}
|
||||
return $listObjectsWithPaginationIfSet;
|
||||
|
||||
@@ -45,10 +45,10 @@ class limitedBackofficeRoute
|
||||
]);
|
||||
|
||||
$this->get('/limited-backoffice/roles', function () {
|
||||
$this->withLimitedBackoffice(function (limited_backoffice_service $service): array {
|
||||
$this->withLimitedBackoffice(function (limited_backoffice_service $service, $user): array {
|
||||
$this->requirePermission(limited_backoffice_service::PERMISSION_ACCESS);
|
||||
$this->requirePermission(limited_backoffice_service::PERMISSION_MANAGE_EMPLOYEES);
|
||||
return $service->rolePresets();
|
||||
return $service->rolePresets($user);
|
||||
});
|
||||
}, [
|
||||
limited_backoffice_service::PERMISSION_ACCESS => 'Access the limited backoffice',
|
||||
|
||||
@@ -27,19 +27,28 @@ class usersRoute
|
||||
(new logs_o())->add('users', 'global', 1, $user->id, 'LIST_USERS', 'Successfully listed users');
|
||||
// Return the list of users
|
||||
$users_o = new users_o();
|
||||
$response->success(
|
||||
$users_o->parseUsers(
|
||||
$users_o
|
||||
->setSearchableFields([
|
||||
// The fields that can be searched. This would otherwise make it possible to get secret information from the database, simply by searching for it and getting the result count back
|
||||
'id',
|
||||
'customer_number',
|
||||
'group_id',
|
||||
'display_name',
|
||||
])
|
||||
->listObjectsWithPaginationIfSet()
|
||||
)
|
||||
$limitedEmployeeListMode = $this->limitedBackofficeEmployeeListMode($users_o);
|
||||
$users = $users_o
|
||||
->setSearchableFields([
|
||||
// The fields that can be searched. This would otherwise make it possible to get secret information from the database, simply by searching for it and getting the result count back
|
||||
'id',
|
||||
'customer_number',
|
||||
'group_id',
|
||||
'display_name',
|
||||
])
|
||||
->listObjectsWithPaginationIfSet(
|
||||
null,
|
||||
$limitedEmployeeListMode['filters'],
|
||||
[],
|
||||
$limitedEmployeeListMode['additional_where']
|
||||
);
|
||||
if ($limitedEmployeeListMode['enabled']) {
|
||||
$users = $users_o->markLimitedBackofficeManagedUsers($users);
|
||||
}
|
||||
$users = $users_o->parseUsers(
|
||||
$users
|
||||
);
|
||||
$response->success($users);
|
||||
} else {
|
||||
// Log the incident
|
||||
(new logs_o())->add('users', 'global', 1, 0, 'LIST_USERS', 'No user found, or invalid session');
|
||||
@@ -153,6 +162,23 @@ class usersRoute
|
||||
if (!isset($data['display_name']) || $data['display_name'] === 'null' || $data['display_name'] === '') {
|
||||
$data['display_name'] = null;
|
||||
}
|
||||
$targetUser = (new users_o())->getUserById((int)$data['id']);
|
||||
if (!$targetUser->exists()) {
|
||||
$response->error('User not found', 404);
|
||||
}
|
||||
|
||||
if ((new users_o())->isLimitedBackofficeManagedUser((int)$data['id'])) {
|
||||
$currentCustomerNumber = (string)$targetUser->customer_number->value();
|
||||
if ((string)$data['customer_number'] !== $currentCustomerNumber) {
|
||||
$response->error('Limited backoffice managed users cannot change customer number.', 403);
|
||||
}
|
||||
|
||||
if ($data['role'] !== null && (int)$data['role'] !== (int)$targetUser->group_id->value()) {
|
||||
$response->error('Limited backoffice managed users cannot change role.', 403);
|
||||
}
|
||||
|
||||
$data['role'] = null;
|
||||
}
|
||||
// If the role is set, require the edit_user_role permission
|
||||
if ($data['role']) {
|
||||
$this->requirePermission('edit_user_role');
|
||||
@@ -207,4 +233,44 @@ class usersRoute
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{enabled:bool,filters:string|null,additional_where:string|null}
|
||||
*/
|
||||
private function limitedBackofficeEmployeeListMode(users_o $users): array
|
||||
{
|
||||
$enabled = strtolower((string)($this->fromQuery('include_limited_backoffice_employees') ?? 'false')) === 'true';
|
||||
$filters = $this->fromQuery('filters');
|
||||
|
||||
if (!$enabled || $filters === null || $filters === '') {
|
||||
return [
|
||||
'enabled' => false,
|
||||
'filters' => null,
|
||||
'additional_where' => null,
|
||||
];
|
||||
}
|
||||
|
||||
$filterArray = $users->filter_string_to_array($filters);
|
||||
$customerNumberFilter = $filterArray['customer_number'] ?? null;
|
||||
$isEmployeeFilter = $customerNumberFilter === '0'
|
||||
|| $customerNumberFilter === 0
|
||||
|| (is_array($customerNumberFilter) && in_array('0', $customerNumberFilter, true));
|
||||
|
||||
if (!$isEmployeeFilter) {
|
||||
return [
|
||||
'enabled' => false,
|
||||
'filters' => $filters,
|
||||
'additional_where' => null,
|
||||
];
|
||||
}
|
||||
|
||||
unset($filterArray['customer_number']);
|
||||
$activeLimitedEmployeeSubquery = 'SELECT `user_id` FROM `limited_backoffice_employees` WHERE `deactivated_at` IS NULL';
|
||||
|
||||
return [
|
||||
'enabled' => true,
|
||||
'filters' => $filterArray === [] ? null : $users->array_to_filters($filterArray),
|
||||
'additional_where' => '(`customer_number` = 0 OR `id` IN (' . $activeLimitedEmployeeSubquery . '))',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,34 @@ function limited_backoffice_manager_session(array $departmentIds, array $extraPe
|
||||
return api_fixtures()->createUserSession(array_values(array_unique(array_merge($permissions, $extraPermissions))));
|
||||
}
|
||||
|
||||
function limited_backoffice_all_role_permissions(): array
|
||||
{
|
||||
return [
|
||||
'user',
|
||||
'permissions_list_own',
|
||||
'list_orders',
|
||||
'add_order',
|
||||
'edit_order',
|
||||
'delete_order',
|
||||
'list_order_items',
|
||||
'add_order_items',
|
||||
'edit_order_items',
|
||||
'delete_order_items',
|
||||
'charge_order',
|
||||
'list_bookings',
|
||||
'list_own_bookings',
|
||||
'edit_bookings',
|
||||
'add_booking',
|
||||
'complete_bookings',
|
||||
'resend_booking_confirmations',
|
||||
'department_timebookings_entries_get',
|
||||
'department_timebookings_entries_post',
|
||||
'department_timebookings_entries_put',
|
||||
'statistics_orders_new',
|
||||
'statistics_bookings_new',
|
||||
];
|
||||
}
|
||||
|
||||
function limited_backoffice_price_insert(int $departmentId, int $productId, int $price): void
|
||||
{
|
||||
$statement = api_test_runtime()->db()->prepare(
|
||||
@@ -495,7 +523,7 @@ it('creates updates lists and deactivates scoped employees without exposing raw
|
||||
expect((int)$usersDeletedAtColumn->num_rows)->toBe(0);
|
||||
|
||||
$department = api_fixtures()->createDepartment(['name' => 'Limited Employee Department']);
|
||||
$session = limited_backoffice_manager_session([(int)$department['id']]);
|
||||
$session = limited_backoffice_manager_session([(int)$department['id']], limited_backoffice_all_role_permissions());
|
||||
|
||||
$roles = api_client()->get('/limited-backoffice/roles', $session['headers']);
|
||||
$roles
|
||||
@@ -571,6 +599,7 @@ it('creates updates lists and deactivates scoped employees without exposing raw
|
||||
$employeeId = (int)($created->data()['id'] ?? 0);
|
||||
expect($employeeId)->toBeGreaterThan(0);
|
||||
limited_backoffice_cleanup_created_employee($employeeId);
|
||||
expect($created->data()['user_id'] ?? null)->toBe($employeeId);
|
||||
expect($created->data()['email'] ?? null)->toBe('limited-cashier@example.test');
|
||||
expect($created->data()['phone_country_code'] ?? null)->toBe(45);
|
||||
expect($created->data()['phone'] ?? null)->toBe(12345678);
|
||||
@@ -587,9 +616,14 @@ it('creates updates lists and deactivates scoped employees without exposing raw
|
||||
$permissions = array_column($permissionRows, 'permission');
|
||||
expect($permissions)
|
||||
->toContain('department_access_' . (int)$department['id'])
|
||||
->toContain('employee_public_data')
|
||||
->toContain('add_order')
|
||||
->not->toContain('superuser');
|
||||
|
||||
$publicEmployees = api_client()->get('/public/employees');
|
||||
$publicEmployeeIds = array_map('intval', array_column($publicEmployees->data(), 'id'));
|
||||
expect($publicEmployeeIds)->toContain($employeeId);
|
||||
|
||||
$updated = api_client()->put('/limited-backoffice/employees/' . $employeeId, [
|
||||
'display_name' => 'Limited Lead',
|
||||
'email' => 'limited-lead@example.test',
|
||||
@@ -620,6 +654,7 @@ it('creates updates lists and deactivates scoped employees without exposing raw
|
||||
}
|
||||
}
|
||||
expect($listedEmployee)->not->toBeNull();
|
||||
expect($listedEmployee['user_id'] ?? null)->toBe($employeeId);
|
||||
expect($listedEmployee['email'] ?? null)->toBe('limited-lead@example.test');
|
||||
expect($listedEmployee['phone_country_code'] ?? null)->toBe(358);
|
||||
expect($listedEmployee['phone'] ?? null)->toBe(87654321);
|
||||
@@ -637,6 +672,9 @@ it('creates updates lists and deactivates scoped employees without exposing raw
|
||||
expect(array_key_exists('password', $userRow ?? []))->toBeTrue();
|
||||
expect($userRow['password'])->toBeNull();
|
||||
expect((int)($userRow['group_id'] ?? -1))->toBe(0);
|
||||
$publicEmployeesAfterDeactivation = api_client()->get('/public/employees');
|
||||
$publicEmployeeIdsAfterDeactivation = array_map('intval', array_column($publicEmployeesAfterDeactivation->data(), 'id'));
|
||||
expect($publicEmployeeIdsAfterDeactivation)->not->toContain($employeeId);
|
||||
$employeeRow = api_test_runtime()->queryOne(
|
||||
'SELECT `deactivated_at` FROM `limited_backoffice_employees` WHERE `user_id` = ' . $employeeId . ' LIMIT 1'
|
||||
);
|
||||
@@ -644,6 +682,155 @@ it('creates updates lists and deactivates scoped employees without exposing raw
|
||||
});
|
||||
});
|
||||
|
||||
it('caps limited employee permissions to the manager permissions and selected departments', function (): void {
|
||||
api_test_covers('POST /limited-backoffice/employees', 'auth');
|
||||
api_test_covers('GET /limited-backoffice/roles', 'auth');
|
||||
|
||||
$department = api_fixtures()->createDepartment(['name' => 'Limited Permission Cap']);
|
||||
$session = limited_backoffice_manager_session([(int)$department['id']], [
|
||||
'list_orders',
|
||||
]);
|
||||
|
||||
$roles = api_client()->get('/limited-backoffice/roles', $session['headers']);
|
||||
$rolesByKey = array_column($roles->data(), null, 'key');
|
||||
$operationsLeadGroups = array_column($rolesByKey['operations_lead']['permission_groups'] ?? [], 'capabilities', 'key');
|
||||
expect($operationsLeadGroups['account'] ?? null)->toBe(['sign_in']);
|
||||
expect($operationsLeadGroups['orders'] ?? null)->toBe(['view_orders']);
|
||||
expect($roles->body)->not->toContain('create_orders');
|
||||
expect($roles->body)->not->toContain('view_order_statistics');
|
||||
|
||||
$created = api_client()->post('/limited-backoffice/employees', [
|
||||
'display_name' => 'Limited Capped Lead',
|
||||
'email' => 'limited-capped@example.test',
|
||||
'password' => 'Secret123!',
|
||||
'role_key' => 'operations_lead',
|
||||
'department_ids' => [(int)$department['id']],
|
||||
], $session['headers']);
|
||||
$created
|
||||
->assertStatus(200)
|
||||
->assertEnvelope()
|
||||
->assertSuccess();
|
||||
|
||||
$employeeId = (int)($created->data()['id'] ?? 0);
|
||||
expect($employeeId)->toBeGreaterThan(0);
|
||||
limited_backoffice_cleanup_created_employee($employeeId);
|
||||
|
||||
$groupRow = api_test_runtime()->queryOne(
|
||||
'SELECT `managed_group_id` FROM `limited_backoffice_employees` WHERE `user_id` = ' . $employeeId . ' LIMIT 1'
|
||||
);
|
||||
$groupId = (int)($groupRow['managed_group_id'] ?? 0);
|
||||
$permissionRows = api_test_runtime()->db()->query(
|
||||
'SELECT `permission` FROM `groups_permissions` WHERE `group_id` = ' . $groupId
|
||||
)->fetch_all(MYSQLI_ASSOC);
|
||||
$permissions = array_column($permissionRows, 'permission');
|
||||
|
||||
expect($permissions)
|
||||
->toContain('user')
|
||||
->toContain('employee_public_data')
|
||||
->toContain('list_orders')
|
||||
->toContain('department_access_' . (int)$department['id'])
|
||||
->not->toContain('add_order')
|
||||
->not->toContain('delete_order')
|
||||
->not->toContain('statistics_orders_new')
|
||||
->not->toContain(limited_backoffice_service::PERMISSION_MANAGE_EMPLOYEES);
|
||||
});
|
||||
|
||||
it('includes limited employees in the regular employee list and protects raw user edits', function (): void {
|
||||
api_test_covers('GET /users', 'limited backoffice employee list');
|
||||
api_test_covers('PUT /users', 'limited backoffice guard');
|
||||
|
||||
$department = api_fixtures()->createDepartment(['name' => 'Limited Regular List']);
|
||||
$managerSession = limited_backoffice_manager_session([(int)$department['id']], [
|
||||
'permissions_list_own',
|
||||
]);
|
||||
|
||||
$regularEmployee = api_fixtures()->createUser([
|
||||
'customer_number' => 0,
|
||||
'display_name' => 'Regular Backoffice Employee',
|
||||
], ['employee_public_data']);
|
||||
|
||||
$created = api_client()->post('/limited-backoffice/employees', [
|
||||
'display_name' => 'Limited Listed Employee',
|
||||
'email' => 'limited-listed@example.test',
|
||||
'password' => 'Secret123!',
|
||||
'role_key' => 'viewer',
|
||||
'department_ids' => [(int)$department['id']],
|
||||
], $managerSession['headers']);
|
||||
$created
|
||||
->assertStatus(200)
|
||||
->assertEnvelope()
|
||||
->assertSuccess();
|
||||
|
||||
$employeeId = (int)($created->data()['id'] ?? 0);
|
||||
expect($employeeId)->toBeGreaterThan(0);
|
||||
limited_backoffice_cleanup_created_employee($employeeId);
|
||||
|
||||
$adminSession = api_fixtures()->createUserSession([
|
||||
'list_users',
|
||||
'edit_user',
|
||||
]);
|
||||
|
||||
$withoutLimited = api_client()->get('/users?page=1&limit=50&filters=customer_number:0', $adminSession['headers']);
|
||||
$withoutLimitedIds = array_map('intval', array_column($withoutLimited->data(), 'id'));
|
||||
expect($withoutLimitedIds)->toContain((int)$regularEmployee['id']);
|
||||
expect($withoutLimitedIds)->not->toContain($employeeId);
|
||||
|
||||
$withLimited = api_client()->get(
|
||||
'/users?page=1&limit=50&filters=customer_number:0&include_limited_backoffice_employees=true',
|
||||
$adminSession['headers']
|
||||
);
|
||||
$usersById = array_column($withLimited->data(), null, 'id');
|
||||
expect(array_keys($usersById))->toContain((int)$regularEmployee['id']);
|
||||
expect(array_keys($usersById))->toContain($employeeId);
|
||||
expect($usersById[$employeeId]['limited_backoffice_managed'] ?? null)->toBeTrue();
|
||||
expect($usersById[(int)$regularEmployee['id']]['limited_backoffice_managed'] ?? null)->toBeFalse();
|
||||
|
||||
$userRow = api_test_runtime()->queryOne(
|
||||
'SELECT `customer_number`, `group_id` FROM `users` WHERE `id` = ' . $employeeId . ' LIMIT 1'
|
||||
);
|
||||
$customerNumber = (int)($userRow['customer_number'] ?? 0);
|
||||
$groupId = (int)($userRow['group_id'] ?? 0);
|
||||
|
||||
api_client()->put('/users', [
|
||||
'id' => $employeeId,
|
||||
'customer_number' => $customerNumber + 1,
|
||||
'role' => $groupId,
|
||||
'display_name' => 'Blocked Customer Change',
|
||||
], $adminSession['headers'])
|
||||
->assertStatus(403)
|
||||
->assertEnvelope()
|
||||
->assertSuccess(false)
|
||||
->assertMessage('Limited backoffice managed users cannot change customer number.');
|
||||
|
||||
api_client()->put('/users', [
|
||||
'id' => $employeeId,
|
||||
'customer_number' => $customerNumber,
|
||||
'role' => 0,
|
||||
'display_name' => 'Blocked Role Change',
|
||||
], $adminSession['headers'])
|
||||
->assertStatus(403)
|
||||
->assertEnvelope()
|
||||
->assertSuccess(false)
|
||||
->assertMessage('Limited backoffice managed users cannot change role.');
|
||||
|
||||
api_client()->put('/users', [
|
||||
'id' => $employeeId,
|
||||
'customer_number' => $customerNumber,
|
||||
'role' => $groupId,
|
||||
'display_name' => 'Edited Limited Listed Employee',
|
||||
], $adminSession['headers'])
|
||||
->assertStatus(200)
|
||||
->assertEnvelope()
|
||||
->assertSuccess();
|
||||
|
||||
$updatedUserRow = api_test_runtime()->queryOne(
|
||||
'SELECT `customer_number`, `group_id`, `display_name` FROM `users` WHERE `id` = ' . $employeeId . ' LIMIT 1'
|
||||
);
|
||||
expect((int)($updatedUserRow['customer_number'] ?? 0))->toBe($customerNumber);
|
||||
expect((int)($updatedUserRow['group_id'] ?? 0))->toBe($groupId);
|
||||
expect($updatedUserRow['display_name'] ?? null)->toBe('Edited Limited Listed Employee');
|
||||
});
|
||||
|
||||
it('accepts employees without optional phone details', function (): void {
|
||||
api_test_covers('POST /limited-backoffice/employees', 'happy');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user