From e8a44c555a19d50c5ecc41df1630fc8b2eec8695 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 14 Sep 2021 14:39:28 +0200 Subject: [PATCH] Sort offers by type (#52) That ensures grouped output of related offers. Offers are not sorted in any way and might end up in entry, parking, entry, etc. Sorting ensures all of same type are rendered one after the other, entry, entry, parking. Sorting is done by alphabet on the technical enum value. --- Classes/Domain/Model/Frontend/Offers.php | 12 ++-- .../TouristAttractionWithOfferTypes.xml | 10 ++++ Tests/Functional/FrontendTest.php | 58 +++++++++++++++---- 3 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 Tests/Functional/Fixtures/Frontend/TouristAttractionWithOfferTypes.xml diff --git a/Classes/Domain/Model/Frontend/Offers.php b/Classes/Domain/Model/Frontend/Offers.php index da11c6d..1e30c81 100644 --- a/Classes/Domain/Model/Frontend/Offers.php +++ b/Classes/Domain/Model/Frontend/Offers.php @@ -48,10 +48,14 @@ class Offers implements TypeInterface, \Iterator, \Countable public function __construct(string $serialized) { $this->serialized = $serialized; - $this->array = array_map( - [Offer::class, 'createFromArray'], - json_decode($serialized, true) - ); + $array = json_decode($serialized, true); + if (is_array($array)) { + $array = array_map([Offer::class, 'createFromArray'], $array); + usort($array, function (Offer $offerA, Offer $offerB) { + return $offerA->getType() <=> $offerB->getType(); + }); + $this->array = $array; + } } public function __toString(): string diff --git a/Tests/Functional/Fixtures/Frontend/TouristAttractionWithOfferTypes.xml b/Tests/Functional/Fixtures/Frontend/TouristAttractionWithOfferTypes.xml new file mode 100644 index 0000000..26422a2 --- /dev/null +++ b/Tests/Functional/Fixtures/Frontend/TouristAttractionWithOfferTypes.xml @@ -0,0 +1,10 @@ + + + + 1 + 3 + Attraktion mit Angebotstypen + [{"description":"","prices":[{"currency":"EUR","description":"","price":8,"rule":"PerGroup","title":"Schulklassen"}],"title":"Führungen","type":"GuidedTourOffer"},{"description":"","prices":[{"currency":"EUR","description":"","price":8,"rule":"PerGroup","title":"Schulklassen"}],"title":"Verkostung","type":"Tasting"},{"description":"","prices":[{"currency":"EUR","description":"","price":8,"rule":"PerGroup","title":"Schulklassen"}],"title":"Eintritt 1","type":"EntryOffer"},{"description":"","prices":[{"currency":"EUR","description":"","price":8,"rule":"PerGroup","title":"Schulklassen"}],"title":"Eintritt 2","type":"EntryOffer"},{"description":"","prices":[{"currency":"EUR","description":"","price":8,"rule":"PerGroup","title":"Schulklassen"}],"title":"Parkgebühr","type":"ParkingFee"}] + + + diff --git a/Tests/Functional/FrontendTest.php b/Tests/Functional/FrontendTest.php index f4808e5..fe6b084 100644 --- a/Tests/Functional/FrontendTest.php +++ b/Tests/Functional/FrontendTest.php @@ -373,20 +373,58 @@ class FrontendTest extends FunctionalTestCase self::assertStringContainsString('Attraktion mit Preisen', (string)$result->getBody()); - self::assertLessThan( - mb_strpos((string)$result->getBody(), 'Familienkarte A'), + self::assertGreaterThan( mb_strpos((string)$result->getBody(), 'Erwachsene'), - '"Familienkarte A" is rendered before "Erwachsene"' - ); - self::assertLessThan( - mb_strpos((string)$result->getBody(), 'Familienkarte B'), mb_strpos((string)$result->getBody(), 'Familienkarte A'), - '"Familienkarte B" is rendered before "Familienkarte A"' + '"Erwachsene" is not rendered before "Familienkarte A"' ); - self::assertLessThan( - mb_strpos((string)$result->getBody(), 'Schulklassen'), + self::assertGreaterThan( + mb_strpos((string)$result->getBody(), 'Familienkarte A'), mb_strpos((string)$result->getBody(), 'Familienkarte B'), - '"Schulklassen" is rendered before "Familienkarte B"' + '"Familienkarte A" is not rendered before "Familienkarte B"' + ); + self::assertGreaterThan( + mb_strpos((string)$result->getBody(), 'Familienkarte B'), + mb_strpos((string)$result->getBody(), 'Schulklassen'), + '"Familienkarte B" is not rendered before "Schulklassen"' + ); + } + + /** + * @test + */ + public function offersAreSortedByType(): void + { + $this->importDataSet('EXT:thuecat/Tests/Functional/Fixtures/Frontend/TouristAttractionWithOfferTypes.xml'); + + $request = new InternalRequest(); + $request = $request->withPageId(2); + + $result = $this->executeFrontendRequest($request); + + self::assertSame(200, $result->getStatusCode()); + + self::assertStringContainsString('Attraktion mit Angebotstypen', (string)$result->getBody()); + + self::assertGreaterThan( + mb_strpos((string)$result->getBody(), 'Eintritt 1'), + mb_strpos((string)$result->getBody(), 'Eintritt 2'), + '"Eintritt 1" is not rendered before "Eintritt 2"' + ); + self::assertGreaterThan( + mb_strpos((string)$result->getBody(), 'Eintritt 2'), + mb_strpos((string)$result->getBody(), 'Führungen'), + '"Eintritt 2" is not rendered before "Führungen"' + ); + self::assertGreaterThan( + mb_strpos((string)$result->getBody(), 'Führungen'), + mb_strpos((string)$result->getBody(), 'Parkgebühr'), + '"Führungen" is not rendered before "Parkgebühr"' + ); + self::assertGreaterThan( + mb_strpos((string)$result->getBody(), 'Parkgebühr'), + mb_strpos((string)$result->getBody(), 'Verkostung'), + '"Parkgebühr" is not rendered before "Verkostung"' ); } }