203 lines
13 KiB
PHP
203 lines
13 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\BusProNet;
|
|
|
|
use App\BusProNet\ApiClient;
|
|
use App\BusProNet\Model\BaseDataResponse;
|
|
use App\BusProNet\Model\CrmAttributesResponse;
|
|
use App\BusProNet\Model\Hotel;
|
|
use App\BusProNet\Model\Pickup;
|
|
use App\BusProNet\Model\ProfileResponse;
|
|
use App\BusProNet\Model\ProfileUpdateResponse;
|
|
use App\BusProNet\ResponseParser;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class ResponseParserTest extends TestCase
|
|
{
|
|
public function testParseUnsuccessfulResponse(): void
|
|
{
|
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="HINWEIS"><nr>853</nr><text>ID, EMail oder Passwort falsch</text></satz></ergebnis>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_NOTIFICATION, $content);
|
|
|
|
$this->assertEquals(853, $response->getCode());
|
|
$this->assertEquals('ID, EMail oder Passwort falsch', $response->getMessage());
|
|
$this->assertFalse($response->isSuccessful());
|
|
}
|
|
|
|
public function testParseSuccessfulProfileResponse(): void
|
|
{
|
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>Adressdaten</art><idadresse>141747</idadresse><idperson>224526</idperson><adressdaten><name>Fromme</name><vorname>Björn</vorname><anrede>Herr</anrede><titel></titel><geschlecht>M</geschlecht><geburtsdatum>16.04.1972</geburtsdatum><nationalitaet>D</nationalitaet><anschrift><id>119447</id><strasse>Emilienstraße 57</strasse><plz>42853</plz><ort>Remscheid</ort><ortsteil></ortsteil><land>D</land></anschrift><kommunikation><telefonmobil></telefonmobil><email>[email protected]</email><newsletter>False</newsletter><telefonprivat>02191-4615837</telefonprivat></kommunikation></adressdaten></ergebnis>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $content);
|
|
|
|
$this->assertInstanceOf(ProfileResponse::class, $response);
|
|
}
|
|
|
|
public function testParseSuccessfulCrmAttributesResponse(): void
|
|
{
|
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>SelektionCRM</art><idadresse>141747</idadresse><idperson>224526</idperson><selektionsmerkmale><selektionsgruppe id="6" bezeichnung="Gruppen - Art (NUR direkt dem GR-Kunden zuordnen)"><selektion id="1156" bezeichnung="Gruppen-Buchungsportal" aenderbar="False" auswahl="True"></selektion></selektionsgruppe><selektionsgruppe id="10" bezeichnung="TEAM"><selektion id="1070" bezeichnung="E&P Teamer - allg. Merkmal" aenderbar="False" auswahl="True"></selektion></selektionsgruppe><selektionsgruppe id="83" bezeichnung="Interessen"><selektion id="1064" bezeichnung="Sportclub-Reisen" aenderbar="True" auswahl="False"></selektion><selektion id="1065" bezeichnung="Individual-Ferienwohnungen/Gasthöfe" aenderbar="True" auswahl="False"></selektion><selektion id="1066" bezeichnung="Kurztrips" aenderbar="True" auswahl="False"></selektion><selektion id="1067" bezeichnung="Eventreisen" aenderbar="True" auswahl="False"></selektion><selektion id="1068" bezeichnung="Gruppen-Angebote" aenderbar="True" auswahl="False"></selektion><selektion id="1069" bezeichnung="Firmen-Angebote" aenderbar="True" auswahl="False"></selektion></selektionsgruppe></selektionsmerkmale><crmaktionen><crmaktion id="428" code="18DDW40" bezeichnung="Deal Der Woche KW40-2018" aenderbar="False" auswahl="False"></crmaktion><crmaktion id="276" code="NOMAIL" bezeichnung="Ich möchte keine Werbung per Mail erhalten" aenderbar="True" auswahl="True"></crmaktion></crmaktionen></ergebnis>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $content);
|
|
|
|
$this->assertInstanceOf(CrmAttributesResponse::class, $response);
|
|
$this->assertCount(3, $response->getAttributeGroups());
|
|
$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());
|
|
}
|
|
|
|
/**
|
|
* The house of a "Hausleitung" selection comes from the configured id map, never from the
|
|
* label: an id that is not mapped grants nothing. That is also what keeps the houses
|
|
* commented out in bpn_crm_house_manager_ids from letting someone in who would then see
|
|
* no assignments and no dispositions at all.
|
|
*/
|
|
public function testParseCrmAttributesIgnoresAnUnmappedHouseManagerSelection(): void
|
|
{
|
|
$content = '<?xml version="1.0" encoding="utf-8"?><ergebnis><satz typ="KUNDENKONTO"></satz><art>SelektionCRM</art><idadresse>141747</idadresse><idperson>224526</idperson><selektionsmerkmale><selektionsgruppe id="10" bezeichnung="TEAM"><selektion id="1070" bezeichnung="E&P Teamer - allg. Merkmal" aenderbar="False" auswahl="True"></selektion><selektion id="9999" bezeichnung="Hausleitung XYZ" aenderbar="False" auswahl="True"></selektion></selektionsgruppe></selektionsmerkmale></ergebnis>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $content);
|
|
|
|
$this->assertInstanceOf(CrmAttributesResponse::class, $response);
|
|
$this->assertTrue($response->isTeamer());
|
|
$this->assertFalse($response->isHouseManager());
|
|
$this->assertSame([], $response->getHotelCodes());
|
|
}
|
|
|
|
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>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_CUSTOMER_DATA, $content);
|
|
|
|
$this->assertInstanceOf(ProfileUpdateResponse::class, $response);
|
|
$this->assertSame(141747, $response->getAddressId());
|
|
$this->assertSame(224526, $response->getPersonId());
|
|
$this->assertTrue($response->isUpdated());
|
|
}
|
|
|
|
public function testParseSuccessfulPickupsResponse(): void
|
|
{
|
|
$content = '<?xml version="1.0" encoding="utf-8" ?><zustiege><zustieg id="1" idbuspro="1" code="298"><ort>Karlsruhe</ort><strasse>A5 - Autohof Bruchsal</strasse><art>BUS</art><hausabholung>False</hausabholung><crsbuchbar>True</crsbuchbar><internetbuchbar>True</internetbuchbar></zustieg><zustieg id="2" idbuspro="2" code="2"><ort>Bonn</ort><strasse>Bahnhof</strasse><art>BUS</art><hausabholung>False</hausabholung><crsbuchbar>True</crsbuchbar><internetbuchbar>True</internetbuchbar></zustieg></zustiege>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_BASE_DATA_PICKUPS, $content);
|
|
|
|
$this->assertInstanceOf(BaseDataResponse::class, $response);
|
|
|
|
$pickups = $response->getItems();
|
|
$this->assertCount(2, $pickups);
|
|
|
|
$pickup = reset($pickups);
|
|
$this->assertInstanceOf(Pickup::class, $pickup);
|
|
$this->assertEquals(1, $pickup->getId());
|
|
$this->assertEquals(1, $pickup->getBusProId());
|
|
$this->assertEquals('298', $pickup->getCode());
|
|
$this->assertEquals('Karlsruhe', $pickup->getCity());
|
|
$this->assertEquals('A5 - Autohof Bruchsal', $pickup->getStreet());
|
|
}
|
|
|
|
public function testParseSuccessfulHotelsResponse(): void
|
|
{
|
|
$content = '<?xml version="1.0" encoding="utf-8" ?><hotels><hotel id="1" idbuspro="202003" code="HÖCHST"><name>Berggasthof Höchsten</name><ort>Musterort</ort><strasse>Musterstr. 123</strasse><telefon>03444/19100</telefon><art>Gaststätte</art><internetbuchbar>True</internetbuchbar></hotel><hotel id="2" idbuspro="202004" code="Z. LÖW"><name>Brauereigasthof Zum Löwen</name><ort>Musterort</ort><strasse>Musterstr. 123</strasse><telefon>03437/11133</telefon><art>Gaststätte</art><internetbuchbar>True</internetbuchbar><selektiongruppe id="1" idbuspro="1" bezeichnung="Reisearten 1"><selektion id="1" idbuspro="2" bezeichnung="Kurz-und Clubreisen" /><selektion id="2" idbuspro="7" bezeichnung="Musik und Theater" /><selektion id="3" idbuspro="12" bezeichnung="Flugreisen" /><selektion id="4" idbuspro="13" bezeichnung="Tagesfahrten" /><selektion id="5" idbuspro="1" bezeichnung="Städtereisen" /></selektiongruppe><selektiongruppe id="2" idbuspro="2" bezeichnung="Reisearten 2"><selektion id="1" idbuspro="18" bezeichnung="Adventreisen" /></selektiongruppe><selektiongruppe id="3" idbuspro="3" bezeichnung="Statistik 1"><selektion id="1" idbuspro="31" bezeichnung="Städtreisen" /><selektion id="2" idbuspro="32" bezeichnung="Kurz-und Clubreisen" /><selektion id="3" idbuspro="37" bezeichnung="Musik und Theater" /><selektion id="4" idbuspro="42" bezeichnung="Flugreisen" /><selektion id="5" idbuspro="43" bezeichnung="Tagesfahrten" /></selektiongruppe></hotel></hotels>';
|
|
|
|
$parser = $this->getParserInstance();
|
|
$response = $parser->parseXmlString(ApiClient::TYPE_BASE_DATA_HOTELS, $content);
|
|
|
|
$this->assertInstanceOf(BaseDataResponse::class, $response);
|
|
|
|
$hotels = $response->getItems();
|
|
$this->assertCount(2, $hotels);
|
|
|
|
$hotel = reset($hotels);
|
|
$this->assertInstanceOf(Hotel::class, $hotel);
|
|
$this->assertEquals(1, $hotel->getId());
|
|
$this->assertEquals(202003, $hotel->getBusProId());
|
|
$this->assertEquals('HÖCHST', $hotel->getCode());
|
|
$this->assertEquals('Berggasthof Höchsten', $hotel->getName());
|
|
$this->assertEquals('Musterort', $hotel->getCity());
|
|
$this->assertEquals('Musterstr. 123', $hotel->getStreet());
|
|
$this->assertEquals('03444/19100', $hotel->getPhone());
|
|
$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([
|
|
'bpn_crm_id_admin' => 1292,
|
|
'bpn_crm_id_manager' => 1293,
|
|
'bpn_crm_id_teamer' => 1070,
|
|
// Deliberately a small excerpt of the configured map: the fixtures only carry
|
|
// these three houses, and 1301 is here to be a mapped id no fixture selects.
|
|
'bpn_crm_house_manager_ids' => [
|
|
1299 => 'SSL',
|
|
1301 => 'MVK',
|
|
1304 => 'DKS',
|
|
1305 => 'DGS',
|
|
],
|
|
]);
|
|
}
|
|
}
|