mirror of
https://github.com/werkraum-media/thuecat.git
synced 2024-12-04 19:16:13 +01:00
Filter and sort opening hours (#83)
Opening hours are filtered. Opening hours from the past are no longer available. Opening hours are sorted. Newer opening hours are shown last. Relates: #10185
This commit is contained in:
parent
4cb1cf1438
commit
672f78a5dc
15 changed files with 501 additions and 279 deletions
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WerkraumMedia\ThueCat\Domain\Import\Entity;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use WerkraumMedia\ThueCat\Domain\Import\EntityMapper\PropertyValues;
|
||||
use WerkraumMedia\ThueCat\Domain\Import\Entity\Properties\Address;
|
||||
use WerkraumMedia\ThueCat\Domain\Import\Entity\Properties\ForeignReference;
|
||||
|
@ -30,6 +31,7 @@ use WerkraumMedia\ThueCat\Domain\Import\Entity\Properties\Geo;
|
|||
use WerkraumMedia\ThueCat\Domain\Import\Entity\Properties\OpeningHour;
|
||||
use WerkraumMedia\ThueCat\Domain\Import\Entity\Shared\ContainedInPlace;
|
||||
use WerkraumMedia\ThueCat\Domain\Import\Entity\Shared\Organization;
|
||||
use WerkraumMedia\ThueCat\Service\DateBasedFilter;
|
||||
|
||||
class Place extends Base
|
||||
{
|
||||
|
@ -146,6 +148,28 @@ class Place extends Base
|
|||
return $this->accessibilitySpecification;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OpeningHour[]
|
||||
*/
|
||||
public function getOpeningHoursSpecification(): array
|
||||
{
|
||||
return GeneralUtility::makeInstance(DateBasedFilter::class)
|
||||
->filterOutPreviousDates(
|
||||
$this->openingHours,
|
||||
function (OpeningHour $hour): ?\DateTimeImmutable {
|
||||
return $hour->getValidThrough();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ForeignReference[]
|
||||
*/
|
||||
public function getParkingFacilityNearBy(): array
|
||||
{
|
||||
return $this->parkingFacilitiesNearBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal for mapping via Symfony component.
|
||||
*/
|
||||
|
@ -162,15 +186,6 @@ class Place extends Base
|
|||
$this->geo = $geo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OpeningHour[]
|
||||
* @internal for mapping via Symfony component.
|
||||
*/
|
||||
public function getOpeningHoursSpecification(): array
|
||||
{
|
||||
return $this->openingHours;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal for mapping via Symfony component.
|
||||
*/
|
||||
|
@ -186,15 +201,6 @@ class Place extends Base
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal for mapping via Symfony component.
|
||||
* @return ForeignReference[]
|
||||
*/
|
||||
public function getParkingFacilityNearBy(): array
|
||||
{
|
||||
return $this->parkingFacilitiesNearBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal for mapping via Symfony component.
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,8 @@ declare(strict_types=1);
|
|||
namespace WerkraumMedia\ThueCat\Domain\Model\Frontend;
|
||||
|
||||
use TYPO3\CMS\Core\Type\TypeInterface;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use WerkraumMedia\ThueCat\Service\DateBasedFilter;
|
||||
|
||||
/**
|
||||
* @implements \Iterator<int, OpeningHour>
|
||||
|
@ -48,10 +50,29 @@ class OpeningHours implements TypeInterface, \Iterator, \Countable
|
|||
public function __construct(string $serialized)
|
||||
{
|
||||
$this->serialized = $serialized;
|
||||
$this->array = array_map(
|
||||
$this->array = $this->createArray($serialized);
|
||||
}
|
||||
|
||||
private function createArray(string $serialized): array
|
||||
{
|
||||
$array = array_map(
|
||||
[OpeningHour::class, 'createFromArray'],
|
||||
json_decode($serialized, true) ?? []
|
||||
);
|
||||
|
||||
$array = GeneralUtility::makeInstance(DateBasedFilter::class)
|
||||
->filterOutPreviousDates(
|
||||
$array,
|
||||
function (OpeningHour $hour): ?\DateTimeImmutable {
|
||||
return $hour->getThrough();
|
||||
}
|
||||
);
|
||||
|
||||
usort($array, function (OpeningHour $hourA, OpeningHour $hourB) {
|
||||
return $hourA->getFrom() <=> $hourB->getFrom();
|
||||
});
|
||||
|
||||
return array_values($array);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
|
|
57
Classes/Service/DateBasedFilter.php
Normal file
57
Classes/Service/DateBasedFilter.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Service;
|
||||
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
|
||||
class DateBasedFilter
|
||||
{
|
||||
/**
|
||||
* @var Context
|
||||
*/
|
||||
private $context;
|
||||
|
||||
public function __construct(
|
||||
Context $context
|
||||
) {
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all objects where the date is prior the reference date.
|
||||
*
|
||||
* The reference date is now.
|
||||
*/
|
||||
public function filterOutPreviousDates(
|
||||
array $listToFilter,
|
||||
callable $provideDate
|
||||
): array {
|
||||
$referenceDate = $this->context->getPropertyFromAspect('date', 'full');
|
||||
|
||||
return array_filter($listToFilter, function($elementToFilter) use ($referenceDate, $provideDate) {
|
||||
$objectDate = $provideDate($elementToFilter);
|
||||
return $objectDate === null || $objectDate >= $referenceDate;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@ services:
|
|||
resource: '../Classes/Frontend/DataProcessing/*'
|
||||
public: true
|
||||
|
||||
WerkraumMedia\ThueCat\Service\DateBasedFilter:
|
||||
public: true
|
||||
|
||||
'cache.thuecat_fetchdata':
|
||||
class: 'TYPO3\CMS\Core\Cache\Frontend\FrontendInterface'
|
||||
factory:
|
||||
|
|
|
@ -15,6 +15,13 @@ Features
|
|||
|
||||
* Import author of media. This allows to either render the license author or the author.
|
||||
|
||||
* Filter and sort opening hours.
|
||||
Filter out opening hours from the past, they are not available to the template anymore.
|
||||
Sort opening hours from early to later based on their end timing.
|
||||
|
||||
This should improve the UX of website visitors.
|
||||
It is not possible yet to sort opening hours by hand within the thuecat backend.
|
||||
|
||||
Fixes
|
||||
-----
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dataset>
|
||||
<tx_thuecat_tourist_attraction>
|
||||
<uid>1</uid>
|
||||
<pid>3</pid>
|
||||
<title>Erste Attraktion</title>
|
||||
<description>Die Beschreibung der Attraktion</description>
|
||||
</tx_thuecat_tourist_attraction>
|
||||
</dataset>
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
{
|
||||
"@context": {
|
||||
"cdb": "https://thuecat.org/ontology/cdb/1.0/",
|
||||
"dachkg": "https://thuecat.org/ontology/dachkg/1.0/",
|
||||
"dbo": "http://dbpedia.org/ontology/",
|
||||
"dsv": "http://ontologies.sti-innsbruck.at/dsv/",
|
||||
"foaf": "http://xmlns.com/foaf/0.1/",
|
||||
"owl": "http://www.w3.org/2002/07/owl#",
|
||||
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
||||
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
|
||||
"schema": "http://schema.org/",
|
||||
"sh": "http://www.w3.org/ns/shacl#",
|
||||
"thuecat": "https://thuecat.org/ontology/thuecat/1.0/",
|
||||
"ttgds": "https://thuecat.org/ontology/ttgds/1.0/",
|
||||
"xsd": "http://www.w3.org/2001/XMLSchema#"
|
||||
},
|
||||
"@graph": [
|
||||
{
|
||||
"@id": "https://thuecat.org/resources/835224016581-dara",
|
||||
"@type": [
|
||||
"schema:Place",
|
||||
"schema:Thing",
|
||||
"schema:TouristAttraction",
|
||||
"ttgds:PointOfInterest",
|
||||
"thuecat:Building",
|
||||
"thuecat:ReligiousBuilding",
|
||||
"thuecat:Cathedral",
|
||||
"thuecat:CatholicChurch",
|
||||
"thuecat:Dome"
|
||||
],
|
||||
"thuecat:contentResponsible": {
|
||||
"@id": "https://thuecat.org/resources/018132452787-ngbe"
|
||||
},
|
||||
"schema:availableLanguage": [
|
||||
{
|
||||
"@type": "thuecat:Language",
|
||||
"@value": "thuecat:German"
|
||||
},
|
||||
{
|
||||
"@type": "thuecat:Language",
|
||||
"@value": "thuecat:English"
|
||||
}
|
||||
],
|
||||
"schema:name": [
|
||||
{
|
||||
"@language": "de",
|
||||
"@value": "Dom St. Marien"
|
||||
},
|
||||
{
|
||||
"@language": "en",
|
||||
"@value": "Cathedral of St. Mary"
|
||||
}
|
||||
],
|
||||
"schema:openingHoursSpecification": [
|
||||
{
|
||||
"@id": "genid-7bb7d92bd6624bdf84634c86e8acdbb4-b4",
|
||||
"@type": [
|
||||
"schema:Intangible",
|
||||
"schema:StructuredValue",
|
||||
"schema:Thing",
|
||||
"schema:OpeningHoursSpecification"
|
||||
],
|
||||
"schema:closes": {
|
||||
"@type": "schema:Time",
|
||||
"@value": "18:00:00"
|
||||
},
|
||||
"schema:dayOfWeek": [
|
||||
{
|
||||
"@type": "schema:DayOfWeek",
|
||||
"@value": "schema:Wednesday"
|
||||
}
|
||||
],
|
||||
"schema:opens": {
|
||||
"@type": "schema:Time",
|
||||
"@value": "09:30:00"
|
||||
},
|
||||
"schema:validFrom": {
|
||||
"@type": "schema:Date",
|
||||
"@value": "2021-05-01"
|
||||
},
|
||||
"schema:validThrough": {
|
||||
"@type": "schema:Date",
|
||||
"@value": "2021-10-31"
|
||||
}
|
||||
},
|
||||
{
|
||||
"@id": "genid-7bb7d92bd6624bdf84634c86e8acdbb4-b7",
|
||||
"@type": [
|
||||
"schema:Intangible",
|
||||
"schema:StructuredValue",
|
||||
"schema:Thing",
|
||||
"schema:OpeningHoursSpecification"
|
||||
],
|
||||
"schema:closes": {
|
||||
"@type": "schema:Time",
|
||||
"@value": "17:00:00"
|
||||
},
|
||||
"schema:dayOfWeek": {
|
||||
"@type": "schema:DayOfWeek",
|
||||
"@value": "schema:Sunday"
|
||||
},
|
||||
"schema:opens": {
|
||||
"@type": "schema:Time",
|
||||
"@value": "13:00:00"
|
||||
},
|
||||
"schema:validFrom": {
|
||||
"@type": "schema:Date",
|
||||
"@value": "2050-11-01"
|
||||
},
|
||||
"schema:validThrough": {
|
||||
"@type": "schema:Date",
|
||||
"@value": "2050-04-30"
|
||||
}
|
||||
}
|
||||
],
|
||||
"schema:url": {
|
||||
"@type": "schema:URL",
|
||||
"@value": "http://www.dom-erfurt.de"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dataset>
|
||||
<pages>
|
||||
<uid>1</uid>
|
||||
<pid>0</pid>
|
||||
<tstamp>1613400587</tstamp>
|
||||
<crdate>1613400558</crdate>
|
||||
<cruser_id>1</cruser_id>
|
||||
<doktype>4</doktype>
|
||||
<title>Rootpage</title>
|
||||
<is_siteroot>1</is_siteroot>
|
||||
</pages>
|
||||
<pages>
|
||||
<uid>10</uid>
|
||||
<pid>1</pid>
|
||||
<tstamp>1613400587</tstamp>
|
||||
<crdate>1613400558</crdate>
|
||||
<cruser_id>1</cruser_id>
|
||||
<doktype>254</doktype>
|
||||
<title>Storage folder</title>
|
||||
</pages>
|
||||
|
||||
<sys_language>
|
||||
<uid>1</uid>
|
||||
<pid>0</pid>
|
||||
<title>English</title>
|
||||
<flag>en-us-gb</flag>
|
||||
<language_isocode>en</language_isocode>
|
||||
</sys_language>
|
||||
|
||||
<sys_language>
|
||||
<uid>2</uid>
|
||||
<pid>0</pid>
|
||||
<title>French</title>
|
||||
<flag>fr</flag>
|
||||
<language_isocode>fr</language_isocode>
|
||||
</sys_language>
|
||||
|
||||
<tx_thuecat_import_configuration>
|
||||
<uid>1</uid>
|
||||
<pid>0</pid>
|
||||
<tstamp>1613400587</tstamp>
|
||||
<crdate>1613400558</crdate>
|
||||
<cruser_id>1</cruser_id>
|
||||
<disable>0</disable>
|
||||
<title>The tourist attraction</title>
|
||||
<type>static</type>
|
||||
<configuration><![CDATA[<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<T3FlexForms>
|
||||
<data>
|
||||
<sheet index="sDEF">
|
||||
<language index="lDEF">
|
||||
<field index="storagePid">
|
||||
<value index="vDEF">10</value>
|
||||
</field>
|
||||
<field index="urls">
|
||||
<el index="el">
|
||||
<field index="602a89f54d694654233086">
|
||||
<value index="url">
|
||||
<el>
|
||||
<field index="url">
|
||||
<value index="vDEF">https://thuecat.org/resources/opening-hours-to-filter</value>
|
||||
</field>
|
||||
</el>
|
||||
</value>
|
||||
<value index="_TOGGLE">0</value>
|
||||
</field>
|
||||
</el>
|
||||
</field>
|
||||
</language>
|
||||
</sheet>
|
||||
</data>
|
||||
</T3FlexForms>
|
||||
]]></configuration>
|
||||
</tx_thuecat_import_configuration>
|
||||
</dataset>
|
|
@ -0,0 +1,4 @@
|
|||
"tx_thuecat_tourist_attraction",,,,,,,,
|
||||
,"uid","pid","sys_language_uid","l18n_parent","l10n_source","remote_id","title","opening_hours"
|
||||
,1,10,0,0,0,"https://thuecat.org/resources/835224016581-dara","Dom St. Marien","[{""opens"":""13:00:00"",""closes"":""17:00:00"",""from"":{""date"":""2050-11-01 00:00:00.000000"",""timezone_type"":3,""timezone"":""UTC""},""through"":{""date"":""2050-04-30 00:00:00.000000"",""timezone_type"":3,""timezone"":""UTC""},""daysOfWeek"":[""Sunday""]}]"
|
||||
,2,10,1,1,1,"https://thuecat.org/resources/835224016581-dara","Cathedral of St. Mary","[{""opens"":""13:00:00"",""closes"":""17:00:00"",""from"":{""date"":""2050-11-01 00:00:00.000000"",""timezone_type"":3,""timezone"":""UTC""},""through"":{""date"":""2050-04-30 00:00:00.000000"",""timezone_type"":3,""timezone"":""UTC""},""daysOfWeek"":[""Sunday""]}]"
|
|
File diff suppressed because one or more lines are too long
|
@ -26,9 +26,6 @@ namespace WerkraumMedia\ThueCat\Tests\Functional;
|
|||
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
|
||||
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @covers \
|
||||
*/
|
||||
class FrontendTest extends FunctionalTestCase
|
||||
{
|
||||
protected $coreExtensionsToLoad = [
|
||||
|
@ -83,23 +80,6 @@ class FrontendTest extends FunctionalTestCase
|
|||
self::assertStringContainsString('example@example.com', (string)$result->getBody());
|
||||
self::assertStringContainsString('(0)30 23125 000', (string)$result->getBody());
|
||||
|
||||
self::assertStringContainsString('Montag:', (string)$result->getBody());
|
||||
self::assertStringContainsString('09:30:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Dienstag:', (string)$result->getBody());
|
||||
self::assertStringContainsString('09:30:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Mittwoch:', (string)$result->getBody());
|
||||
self::assertStringContainsString('09:30:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Donnerstag:', (string)$result->getBody());
|
||||
self::assertStringContainsString('09:30:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Freitag:', (string)$result->getBody());
|
||||
self::assertStringContainsString('09:30:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Samstag:', (string)$result->getBody());
|
||||
self::assertStringContainsString('09:30:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Sonntag:', (string)$result->getBody());
|
||||
self::assertStringContainsString('13:00:00 - 17:00:00', (string)$result->getBody());
|
||||
self::assertStringContainsString('Feiertags:', (string)$result->getBody());
|
||||
self::assertStringContainsString('13:00:00 - 17:00:00', (string)$result->getBody());
|
||||
|
||||
self::assertStringContainsString('Führungen', (string)$result->getBody());
|
||||
self::assertStringContainsString('(Führung)', (string)$result->getBody());
|
||||
self::assertStringContainsString('Immer samstags, um 11:15 Uhr findet eine öffentliche Führung durch das Museum statt. Dauer etwa 90 Minuten', (string)$result->getBody());
|
||||
|
@ -443,4 +423,142 @@ class FrontendTest extends FunctionalTestCase
|
|||
'"Parkgebühr" is not rendered before "Verkostung"'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function openingHoursAreFilteredByThough(): void
|
||||
{
|
||||
$this->importDataSet('EXT:thuecat/Tests/Functional/Fixtures/Frontend/TouristAttractionsOpeningHours.xml');
|
||||
|
||||
$hidden = new \DateTimeImmutable('yesterday');
|
||||
$available = new \DateTimeImmutable('tomorrow');
|
||||
|
||||
$this->getConnectionPool()
|
||||
->getConnectionForTable('tx_thuecat_tourist_attraction')
|
||||
->update(
|
||||
'tx_thuecat_tourist_attraction',
|
||||
['opening_hours' => json_encode([
|
||||
[
|
||||
'closes' => '17:00:00',
|
||||
'opens' => '13:00:00',
|
||||
'daysOfWeek' => ['Sunday'],
|
||||
'from' => [
|
||||
'date' => $hidden->modify('-1 day')->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
'through' => [
|
||||
'date' => $hidden->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
],
|
||||
[
|
||||
'closes' => '17:00:00',
|
||||
'opens' => '13:00:00',
|
||||
'daysOfWeek' => ['Sunday'],
|
||||
'from' => [
|
||||
'date' => $available->modify('-1 day')->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
'through' => [
|
||||
'date' => $available->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
],
|
||||
])],
|
||||
['uid' => 1]
|
||||
);
|
||||
|
||||
$request = new InternalRequest();
|
||||
$request = $request->withPageId(2);
|
||||
|
||||
$result = (string)$this->executeFrontendRequest($request)->getBody();
|
||||
|
||||
self::assertStringNotContainsString($hidden->modify('-1 day')->format('d.m.Y'), $result);
|
||||
self::assertStringNotContainsString($hidden->format('d.m.Y'), $result);
|
||||
self::assertStringContainsString($available->modify('-1 day')->format('d.m.Y'), $result);
|
||||
self::assertStringContainsString($available->format('d.m.Y'), $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function openingHoursAreSortedByFrom(): void
|
||||
{
|
||||
$this->importDataSet('EXT:thuecat/Tests/Functional/Fixtures/Frontend/TouristAttractionsOpeningHours.xml');
|
||||
|
||||
$fromFirstOpening = new \DateTimeImmutable('today');
|
||||
$fromSecondOpening = new \DateTimeImmutable('+2 days');
|
||||
$fromThirdOpening = new \DateTimeImmutable('+7 days');
|
||||
|
||||
$this->getConnectionPool()
|
||||
->getConnectionForTable('tx_thuecat_tourist_attraction')
|
||||
->update(
|
||||
'tx_thuecat_tourist_attraction',
|
||||
['opening_hours' => json_encode([
|
||||
[
|
||||
'closes' => '17:00:00',
|
||||
'opens' => '13:00:00',
|
||||
'daysOfWeek' => ['Sunday'],
|
||||
'from' => [
|
||||
'date' => $fromThirdOpening->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
'through' => [
|
||||
'date' => $fromThirdOpening->modify('+1 day')->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
],
|
||||
[
|
||||
'closes' => '17:00:00',
|
||||
'opens' => '13:00:00',
|
||||
'daysOfWeek' => ['Sunday'],
|
||||
'from' => [
|
||||
'date' => $fromFirstOpening->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
'through' => [
|
||||
'date' => $fromFirstOpening->modify('+1 day')->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
],
|
||||
[
|
||||
'closes' => '17:00:00',
|
||||
'opens' => '13:00:00',
|
||||
'daysOfWeek' => ['Sunday'],
|
||||
'from' => [
|
||||
'date' => $fromSecondOpening->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
'through' => [
|
||||
'date' => $fromSecondOpening->modify('+1 day')->format('Y-m-d') . ' 00:00:00.000000',
|
||||
'timezone' => 'UTC',
|
||||
'timezone_type' => 3,
|
||||
],
|
||||
],
|
||||
])],
|
||||
['uid' => 1]
|
||||
);
|
||||
|
||||
$request = new InternalRequest();
|
||||
$request = $request->withPageId(2);
|
||||
|
||||
$result = (string)$this->executeFrontendRequest($request)->getBody();
|
||||
|
||||
$positionFirstHour = mb_strpos($result, $fromFirstOpening->format('d.m.Y'));
|
||||
$positionSecondHour = mb_strpos($result, $fromSecondOpening->format('d.m.Y'));
|
||||
$positionThirdHour = mb_strpos($result, $fromThirdOpening->format('d.m.Y'));
|
||||
|
||||
self::assertLessThan($positionThirdHour, $positionSecondHour, 'Third hour does not come after second hour.');
|
||||
self::assertLessThan($positionSecondHour, $positionFirstHour, 'Second hour does not come after first hour.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,107 +68,6 @@ class PlaceInfosTest extends TestCase
|
|||
self::assertSame([], $result->getOpeningHoursSpecification());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function mapsIncomingOpeningHoursSpecificaton(): void
|
||||
{
|
||||
$subject = new EntityMapper();
|
||||
|
||||
$result = $subject->mapDataToEntity([
|
||||
'schema:openingHoursSpecification' => [
|
||||
0 => [
|
||||
'schema:closes' => [
|
||||
'@type' => 'schema:Time',
|
||||
'@value' => '18:00:00',
|
||||
],
|
||||
'schema:dayOfWeek' => [
|
||||
0 => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Saturday',
|
||||
],
|
||||
1 => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Friday',
|
||||
],
|
||||
2 => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Thursday',
|
||||
],
|
||||
3 => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Tuesday',
|
||||
],
|
||||
4 => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Monday',
|
||||
],
|
||||
5 => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Wednesday',
|
||||
],
|
||||
],
|
||||
'schema:opens' => [
|
||||
'@type' => 'schema:Time',
|
||||
'@value' => '09:30:00',
|
||||
],
|
||||
'schema:validFrom' => [
|
||||
'@type' => 'schema:Date',
|
||||
'@value' => '2021-05-01',
|
||||
],
|
||||
'schema:validThrough' => [
|
||||
'@type' => 'schema:Date',
|
||||
'@value' => '2021-10-31',
|
||||
],
|
||||
],
|
||||
1 => [
|
||||
'schema:closes' => [
|
||||
'@type' => 'schema:Time',
|
||||
'@value' => '18:00:00',
|
||||
],
|
||||
'schema:dayOfWeek' => [
|
||||
'@type' => 'schema:DayOfWeek',
|
||||
'@value' => 'schema:Sunday',
|
||||
],
|
||||
'schema:opens' => [
|
||||
'@type' => 'schema:Time',
|
||||
'@value' => '13:00:00',
|
||||
],
|
||||
'schema:validFrom' => [
|
||||
'@type' => 'schema:Date',
|
||||
'@value' => '2021-05-01',
|
||||
],
|
||||
'schema:validThrough' => [
|
||||
'@type' => 'schema:Date',
|
||||
'@value' => '2021-10-31',
|
||||
],
|
||||
],
|
||||
],
|
||||
], Place::class, [
|
||||
JsonDecode::ACTIVE_LANGUAGE => 'de',
|
||||
]);
|
||||
|
||||
self::assertInstanceOf(Place::class, $result);
|
||||
self::assertCount(2, $result->getOpeningHoursSpecification());
|
||||
self::assertSame('18:00:00', $result->getOpeningHoursSpecification()[0]->getCloses()->format('H:i:s'));
|
||||
self::assertSame('09:30:00', $result->getOpeningHoursSpecification()[0]->getOpens()->format('H:i:s'));
|
||||
self::assertSame('2021-05-01', $result->getOpeningHoursSpecification()[0]->getValidFrom()->format('Y-m-d'));
|
||||
self::assertSame('2021-10-31', $result->getOpeningHoursSpecification()[0]->getValidThrough()->format('Y-m-d'));
|
||||
self::assertSame([
|
||||
'Saturday',
|
||||
'Friday',
|
||||
'Thursday',
|
||||
'Tuesday',
|
||||
'Monday',
|
||||
'Wednesday',
|
||||
], $result->getOpeningHoursSpecification()[0]->getDaysOfWeek());
|
||||
self::assertSame('18:00:00', $result->getOpeningHoursSpecification()[1]->getCloses()->format('H:i:s'));
|
||||
self::assertSame('13:00:00', $result->getOpeningHoursSpecification()[1]->getOpens()->format('H:i:s'));
|
||||
self::assertSame('2021-05-01', $result->getOpeningHoursSpecification()[1]->getValidFrom()->format('Y-m-d'));
|
||||
self::assertSame('2021-10-31', $result->getOpeningHoursSpecification()[1]->getValidThrough()->format('Y-m-d'));
|
||||
self::assertSame(['Sunday'], $result->getOpeningHoursSpecification()[1]->getDaysOfWeek());
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
|
|
|
@ -215,6 +215,21 @@ class ImportTest extends TestCase
|
|||
$this->assertCSVDataSet('EXT:thuecat/Tests/Functional/Fixtures/Import/ImportsTouristAttractionsWithRelations.csv');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function importsTouristAttractionsWithFilteredOpeningHours(): void
|
||||
{
|
||||
$this->importDataSet(__DIR__ . '/Fixtures/Import/ImportsTouristAttractionWithFilteredOpeningHours.xml');
|
||||
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/opening-hours-to-filter.json');
|
||||
GuzzleClientFaker::appendResponseFromFile(__DIR__ . '/Fixtures/Import/Guzzle/thuecat.org/resources/018132452787-ngbe.json');
|
||||
|
||||
$configuration = $this->get(ImportConfigurationRepository::class)->findByUid(1);
|
||||
$this->get(Importer::class)->importConfiguration($configuration);
|
||||
|
||||
$this->assertCSVDataSet('EXT:thuecat/Tests/Functional/Fixtures/Import/ImportsTouristAttractionsWithFilteredOpeningHours.csv');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WerkraumMedia\ThueCat\Tests\Unit\Domain\Model\Frontend;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use WerkraumMedia\ThueCat\Domain\Model\Frontend\OpeningHours;
|
||||
|
||||
/**
|
||||
* @covers \WerkraumMedia\ThueCat\Domain\Model\Frontend\OpeningHours
|
||||
*
|
||||
* @uses \WerkraumMedia\ThueCat\Domain\Model\Frontend\OpeningHour
|
||||
*
|
||||
* @testdox Frontend model for offers
|
||||
*/
|
||||
class OpeningHoursTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function canBeCreated(): void
|
||||
{
|
||||
$subject = new OpeningHours('{}');
|
||||
|
||||
self::assertInstanceOf(OpeningHours::class, $subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function isCountable(): void
|
||||
{
|
||||
$subject = new OpeningHours('{}');
|
||||
|
||||
self::assertInstanceOf(\Countable::class, $subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function isIterator(): void
|
||||
{
|
||||
$subject = new OpeningHours('{}');
|
||||
|
||||
self::assertInstanceOf(\Iterator::class, $subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @dataProvider forCount
|
||||
* @testdox returns $expected for count
|
||||
*/
|
||||
public function returnsExpectedCount(string $serialized, int $expected): void
|
||||
{
|
||||
$subject = new OpeningHours($serialized);
|
||||
|
||||
self::assertCount($expected, $subject);
|
||||
}
|
||||
|
||||
public function forCount(): array
|
||||
{
|
||||
return [
|
||||
'zero' => [
|
||||
'serialized' => '{}',
|
||||
'expected' => 0,
|
||||
],
|
||||
'one' => [
|
||||
'serialized' => json_encode([
|
||||
[
|
||||
],
|
||||
]),
|
||||
'expected' => 1,
|
||||
],
|
||||
'five' => [
|
||||
'serialized' => json_encode([
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
]),
|
||||
'expected' => 5,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -349,18 +349,13 @@ parameters:
|
|||
count: 1
|
||||
path: Configuration/TCA/tx_thuecat_town.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method format\\(\\) on DateTimeImmutable\\|null\\.$#"
|
||||
count: 4
|
||||
path: Tests/Functional/Import/EntityMapping/PlaceInfosTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method findByUid\\(\\) on mixed\\.$#"
|
||||
count: 8
|
||||
count: 9
|
||||
path: Tests/Functional/ImportTest.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method importConfiguration\\(\\) on mixed\\.$#"
|
||||
count: 8
|
||||
count: 9
|
||||
path: Tests/Functional/ImportTest.php
|
||||
|
||||
|
|
Loading…
Reference in a new issue