feat: streamlined role-revocation logic
This commit is contained in:
@@ -48,6 +48,59 @@ class ResponseParserTest extends TestCase
|
||||
$this->assertTrue($response->isTeamer());
|
||||
}
|
||||
|
||||
/**
|
||||
* BusPro always returns the full attribute tree and expresses the roles a person holds
|
||||
* through the "auswahl" flag, so a revoked role arrives as a selection set to False,
|
||||
* never as a missing group. The demotion path in BpnAuthenticator relies on that: it
|
||||
* treats "no roles" as a revocation only when attribute groups are present.
|
||||
*/
|
||||
public function testParseCrmAttributesOfAUserHoldingEveryRole(): void
|
||||
{
|
||||
$parser = $this->getParserInstance();
|
||||
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $this->loadFixture('crm_attributes_granted.xml'));
|
||||
|
||||
$this->assertInstanceOf(CrmAttributesResponse::class, $response);
|
||||
$this->assertTrue($response->isTeamer());
|
||||
$this->assertTrue($response->isAdmin());
|
||||
$this->assertTrue($response->isManager());
|
||||
$this->assertTrue($response->isHouseManager());
|
||||
$this->assertSame(['DKS'], $response->getHotelCodes());
|
||||
|
||||
// "Preisrechner Admin" is matched by id, never by its label
|
||||
$this->assertCount(3, $response->getAttributeGroups());
|
||||
}
|
||||
|
||||
public function testParseCrmAttributesOfAUserWhoseRolesWereRevoked(): void
|
||||
{
|
||||
$parser = $this->getParserInstance();
|
||||
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $this->loadFixture('crm_attributes_revoked.xml'));
|
||||
|
||||
$this->assertInstanceOf(CrmAttributesResponse::class, $response);
|
||||
$this->assertFalse($response->isTeamer());
|
||||
$this->assertFalse($response->isAdmin());
|
||||
$this->assertFalse($response->isManager());
|
||||
$this->assertFalse($response->isHouseManager());
|
||||
$this->assertSame([], $response->getHotelCodes());
|
||||
|
||||
// the groups still arrive, so this is a revocation and not a degraded response
|
||||
$this->assertCount(3, $response->getAttributeGroups());
|
||||
}
|
||||
|
||||
public function testParseCrmAttributesOfAnEmptyResponse(): void
|
||||
{
|
||||
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>SelektionCRM</art><idadresse>141747</idadresse><idperson>224526</idperson><selektionsmerkmale></selektionsmerkmale></ergebnis>';
|
||||
|
||||
$parser = $this->getParserInstance();
|
||||
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $content);
|
||||
|
||||
// indistinguishable from a revocation by the roles alone, which is why the empty
|
||||
// group set is what the demotion path checks
|
||||
$this->assertInstanceOf(CrmAttributesResponse::class, $response);
|
||||
$this->assertFalse($response->isTeamer());
|
||||
$this->assertSame([], $response->getAttributeGroups());
|
||||
$this->assertSame([], $response->toArray());
|
||||
}
|
||||
|
||||
public function testParseSuccessfulProfileUpdateResponseWithoutAddressData(): void
|
||||
{
|
||||
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>Adressdaten_Ändern</art><idadresse>141747</idadresse><idperson>224526</idperson><änderung>True</änderung></ergebnis>';
|
||||
@@ -106,6 +159,11 @@ class ResponseParserTest extends TestCase
|
||||
$this->assertEquals('Gaststätte', $hotel->getType());
|
||||
}
|
||||
|
||||
private function loadFixture(string $filename): string
|
||||
{
|
||||
return file_get_contents(__DIR__.'/../Resources/'.$filename);
|
||||
}
|
||||
|
||||
private function getParserInstance(): ResponseParser
|
||||
{
|
||||
return new ResponseParser([
|
||||
|
||||
Reference in New Issue
Block a user