feat: add employee-only supervisor role nominated by crm selection 1487

This commit is contained in:
fromme committed 2026-10-05 17:06:37 +02:00
1 parent 5f95492a7f
commit 93512b8345
6 files changed
+49 -1

No files matched your search

@@ -24,6 +24,7 @@ Symfony roles:
| `1478` | `ROLE_GROUPS_ADMIN` |
| `1483` | `ROLE_CUSTOMER_EXPERT` |
| `1484` | `ROLE_TEAM_ADMIN` (not consumed here — exported through `/api/userinfo` for myep-team) |
| `1487` | `ROLE_SUPERVISOR` (not consumed here — exported through `/api/userinfo` for ephub) |
| label `Hausleitung {CODE}` | `ROLE_HOUSE_MANAGER` + hotel code `{CODE}` |
| nothing matched | `ROLE_CUSTOMER` |
@@ -45,7 +46,7 @@ filtered before anything is stored:
| --- | --- | --- |
| `ROLE_TEAMER` | granted | granted |
| `ROLE_HOUSE_MANAGER` | nominated | nominated |
| `ROLE_ADMIN`, `ROLE_TEAM_ADMIN`, `ROLE_MANAGER`, `ROLE_GROUPS_ADMIN`, `ROLE_GROUPS_MANAGER`, `ROLE_CUSTOMER_EXPERT` (`Role::EMPLOYEE_ONLY`) | **ignored** | nominated |
| `ROLE_ADMIN`, `ROLE_TEAM_ADMIN`, `ROLE_MANAGER`, `ROLE_GROUPS_ADMIN`, `ROLE_GROUPS_MANAGER`, `ROLE_CUSTOMER_EXPERT`, `ROLE_SUPERVISOR` (`Role::EMPLOYEE_ONLY`) | **ignored** | nominated |
- **Staff address**: the login email's domain is listed in `employee_email_domains`
(`config/services.yaml`, exact match, never a suffix). Such an account also gets
@@ -41,6 +41,7 @@ class CrmAttributesResponseParser
1478 => Role::GROUPS_ADMIN,
1483 => Role::CUSTOMER_EXPERT,
1484 => Role::TEAM_ADMIN,
1487 => Role::SUPERVISOR,
];
/**
+5
View File
@@ -46,6 +46,7 @@ final class Role
public const GROUPS_MANAGER = 'ROLE_GROUPS_MANAGER';
public const CUSTOMER_EXPERT = 'ROLE_CUSTOMER_EXPERT';
public const EMPLOYEE = 'ROLE_EMPLOYEE';
public const SUPERVISOR = 'ROLE_SUPERVISOR';
/**
* Appended to an administrative role to mark it as claimed by the CRM but not yet approved.
@@ -72,6 +73,7 @@ final class Role
self::GROUPS_MANAGER,
self::CUSTOMER_EXPERT,
self::EMPLOYEE,
self::SUPERVISOR,
];
/**
@@ -102,6 +104,7 @@ final class Role
self::GROUPS_ADMIN,
self::GROUPS_MANAGER,
self::CUSTOMER_EXPERT,
self::SUPERVISOR,
];
/**
@@ -121,6 +124,7 @@ final class Role
self::GROUPS_ADMIN,
self::GROUPS_MANAGER,
self::CUSTOMER_EXPERT,
self::SUPERVISOR,
];
/**
@@ -333,6 +337,7 @@ final class Role
self::GROUPS_MANAGER => 'GRO-Expert:in',
self::CUSTOMER_EXPERT => 'KO-Expert:in',
self::EMPLOYEE => 'Mitarbeiter:in',
self::SUPERVISOR => 'Leitung',
];
foreach (self::ADMINISTRATIVE as $role) {
@@ -67,6 +67,24 @@ class CrmAttributesResponseParserTest extends TestCase
self::assertNotContains('ROLE_TEAM_ADMIN', $roles);
}
/**
* ROLE_SUPERVISOR is not consumed here either — it is exported through /api/userinfo for
* ephub.
*/
public function testParseAssignsSupervisorRoleWhenSelected(): void
{
$roles = $this->parseRoles($this->selectionXml(1487, true));
self::assertContains('ROLE_SUPERVISOR', $roles);
}
public function testParseAssignsNoSupervisorRoleWhenNotSelected(): void
{
$roles = $this->parseRoles($this->selectionXml(1487, false));
self::assertNotContains('ROLE_SUPERVISOR', $roles);
}
public function testParseAssignsNoCustomerExpertRoleWhenNotSelected(): void
{
$roles = $this->parseRoles($this->selectionXml(1483, false));
@@ -102,6 +102,20 @@ class UserinfoControllerTest extends TestCase
self::assertSame([Role::EMPLOYEE, Role::TEAM_ADMIN], $claims['roles']);
}
/**
* Same for ephub, which reads ROLE_SUPERVISOR out of this claim.
*/
public function testSupervisorIsExportedOnceApproved(): void
{
$claims = $this->claims(['ROLE_OAUTH2_ROLES'], [
Role::USER,
Role::EMPLOYEE,
Role::SUPERVISOR,
]);
self::assertSame([Role::EMPLOYEE, Role::SUPERVISOR], $claims['roles']);
}
public function testUpstreamFailureIsReportedRatherThanAnswered(): void
{
$accountClient = $this->createStub(AccountClient::class);
+9
View File
@@ -44,6 +44,15 @@ class RoleTest extends TestCase
self::assertSame([Role::EMPLOYEE, Role::CUSTOMER_EXPERT], $roles);
}
public function testSupervisorClaimOnlyProducesANomination(): void
{
$roles = Role::sync([], [Role::EMPLOYEE, Role::SUPERVISOR]);
self::assertSame([Role::EMPLOYEE, Role::pending(Role::SUPERVISOR)], $roles);
self::assertSame([Role::SUPERVISOR => 'Leitung'], Role::nominatedFrom($roles));
self::assertSame([Role::EMPLOYEE, Role::SUPERVISOR], Role::approve($roles, Role::SUPERVISOR));
}
public function testApprovedRoleSurvivesTheNextSyncAndIsNotMarkedAgain(): void
{
$roles = Role::sync([Role::TEAMER, Role::HOUSE_MANAGER], [Role::HOUSE_MANAGER, Role::TEAMER]);