mirror of
https://github.com/werkraum-media/calendar.git
synced 2024-11-21 09:36:10 +01:00
calendar logic
Provide data structure for month, weeks and days. Provide controller to open month, week and day. Relates: #7887
This commit is contained in:
parent
10d6e94c4d
commit
98762332f5
23 changed files with 1782 additions and 1 deletions
163
.github/workflows/ci.yaml
vendored
Normal file
163
.github/workflows/ci.yaml
vendored
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
name: CI
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
check-composer:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Validate composer.json
|
||||||
|
run: composer validate
|
||||||
|
|
||||||
|
php-linting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-version:
|
||||||
|
- 7.3
|
||||||
|
- 7.4
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: "${{ matrix.php-version }}"
|
||||||
|
|
||||||
|
- name: PHP lint
|
||||||
|
run: "find *.php Classes Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l"
|
||||||
|
|
||||||
|
check-dependencies:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [check-composer]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Keep composer at 1.x
|
||||||
|
run: sudo composer selfupdate --1
|
||||||
|
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --prefer-dist --no-progress --no-suggest --no-plugins
|
||||||
|
|
||||||
|
- name: Missing composer requirements
|
||||||
|
run: ./vendor/bin/composer-require-checker check
|
||||||
|
|
||||||
|
xml-linting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [check-composer]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install xmllint
|
||||||
|
run: sudo apt-get install libxml2-utils
|
||||||
|
|
||||||
|
- name: Keep composer at 1.x
|
||||||
|
run: sudo composer selfupdate --1
|
||||||
|
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --prefer-dist --no-progress --no-suggest
|
||||||
|
|
||||||
|
- name: PHPUnit configuration file
|
||||||
|
run: xmllint --schema vendor/phpunit/phpunit/phpunit.xsd --noout phpunit.xml.dist
|
||||||
|
|
||||||
|
- name: PHPCodeSniffer configuration file
|
||||||
|
run: xmllint --schema vendor/squizlabs/php_codesniffer/phpcs.xsd --noout phpcs.xml.dist
|
||||||
|
|
||||||
|
- name: Fetch schema for xliff
|
||||||
|
run: wget https://docs.oasis-open.org/xliff/v1.2/os/xliff-core-1.2-strict.xsd --output-document=.Build/xliff-core-1.2-strict.xsd
|
||||||
|
|
||||||
|
- name: TYPO3 language files
|
||||||
|
run: xmllint --schema .Build/xliff-core-1.2-strict.xsd --noout $(find Resources -name '*.xlf')
|
||||||
|
|
||||||
|
coding-guideline:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- check-dependencies
|
||||||
|
- xml-linting
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Keep composer at 1.x
|
||||||
|
run: sudo composer selfupdate --1
|
||||||
|
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --prefer-dist --no-progress --no-suggest
|
||||||
|
|
||||||
|
- name: Coding Guideline
|
||||||
|
run: ./vendor/bin/phpcs
|
||||||
|
|
||||||
|
tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- check-dependencies
|
||||||
|
- xml-linting
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-version:
|
||||||
|
- 7.3
|
||||||
|
- 7.4
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: "${{ matrix.php-version }}"
|
||||||
|
|
||||||
|
- name: Keep composer at 1.x
|
||||||
|
run: sudo composer selfupdate --1
|
||||||
|
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||||
|
|
||||||
|
- uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-composer-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: composer install --prefer-dist --no-progress --no-suggest
|
||||||
|
|
||||||
|
- name: PHPUnit Tests
|
||||||
|
run: ./vendor/bin/phpunit --testdox
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/.Build/
|
/.Build/
|
||||||
/vendor/
|
/vendor/
|
||||||
|
/composer.lock
|
||||||
|
|
115
Classes/Controller/Frontend/CalendarController.php
Normal file
115
Classes/Controller/Frontend/CalendarController.php
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Controller\Frontend;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 TYPO3\CMS\Extbase\Annotation as Extbase;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||||
|
use TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Day;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Month;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Week;
|
||||||
|
|
||||||
|
class CalendarController extends ActionController
|
||||||
|
{
|
||||||
|
public function initializeMonthAction()
|
||||||
|
{
|
||||||
|
if ($this->request->hasArgument('month') === false) {
|
||||||
|
$this->request->setArguments([
|
||||||
|
'month' => [
|
||||||
|
'month' => date('m'),
|
||||||
|
'year' => date('Y'),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->arguments->getArgument('month')
|
||||||
|
->getPropertyMappingConfiguration()
|
||||||
|
->allowAllProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Extbase\IgnoreValidation("month")
|
||||||
|
*/
|
||||||
|
public function monthAction(Month $month)
|
||||||
|
{
|
||||||
|
$this->view->assignMultiple([
|
||||||
|
'month' => $month,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initializeWeekAction()
|
||||||
|
{
|
||||||
|
if ($this->request->hasArgument('week') === false) {
|
||||||
|
$this->request->setArguments([
|
||||||
|
'week' => [
|
||||||
|
'week' => date('W'),
|
||||||
|
'year' => date('Y'),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->arguments->getArgument('week')
|
||||||
|
->getPropertyMappingConfiguration()
|
||||||
|
->allowAllProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Extbase\IgnoreValidation("week")
|
||||||
|
*/
|
||||||
|
public function weekAction(Week $week)
|
||||||
|
{
|
||||||
|
$this->view->assignMultiple([
|
||||||
|
'week' => $week,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initializeDayAction()
|
||||||
|
{
|
||||||
|
if ($this->request->hasArgument('day') === false) {
|
||||||
|
$this->request->setArguments([
|
||||||
|
'day' => new \DateTimeImmutable(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$propertyMappingConfiguration = $this->arguments->getArgument('day')
|
||||||
|
->getPropertyMappingConfiguration();
|
||||||
|
|
||||||
|
$propertyMappingConfiguration->allowAllProperties();
|
||||||
|
$propertyMappingConfiguration
|
||||||
|
->forProperty('day')
|
||||||
|
->setTypeConverterOption(
|
||||||
|
DateTimeConverter::class,
|
||||||
|
DateTimeConverter::CONFIGURATION_DATE_FORMAT,
|
||||||
|
'Y-m-d'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Extbase\IgnoreValidation("day")
|
||||||
|
*/
|
||||||
|
public function dayAction(Day $day)
|
||||||
|
{
|
||||||
|
$this->view->assignMultiple([
|
||||||
|
'day' => $day,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
89
Classes/Domain/Model/Day.php
Normal file
89
Classes/Domain/Model/Day.php
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||||
|
|
||||||
|
class Day
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \DateTimeImmutable
|
||||||
|
*/
|
||||||
|
private $day;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
private $foreignData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $initialized = false;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
\DateTime $day
|
||||||
|
) {
|
||||||
|
$this->periods = new ObjectStorage();
|
||||||
|
$this->day = \DateTimeImmutable::createFromMutable($day)->modify('midnight');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
$foreignData = $this->getForeignData();
|
||||||
|
if ($foreignData instanceof IsDayActive) {
|
||||||
|
return $foreignData->isActive($this->getDateTimeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getForeignData()
|
||||||
|
{
|
||||||
|
$this->initializeForeignData();
|
||||||
|
|
||||||
|
return $this->foreignData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDateTimeInstance(): \DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->day;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAsUrlArgument(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'day' => $this->day->format('Y-m-d'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function initializeForeignData(): void
|
||||||
|
{
|
||||||
|
if ($this->initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->foreignData = GeneralUtility::makeInstance(ForeignDataFactory::class)
|
||||||
|
->getData($this);
|
||||||
|
}
|
||||||
|
}
|
30
Classes/Domain/Model/ForeignDataFactory.php
Normal file
30
Classes/Domain/Model/ForeignDataFactory.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface ForeignDataFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function getData(Day $day);
|
||||||
|
}
|
27
Classes/Domain/Model/IsDayActive.php
Normal file
27
Classes/Domain/Model/IsDayActive.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface IsDayActive
|
||||||
|
{
|
||||||
|
public function isActive(\DateTimeImmutable $dateTime): bool;
|
||||||
|
}
|
129
Classes/Domain/Model/Month.php
Normal file
129
Classes/Domain/Model/Month.php
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||||
|
|
||||||
|
class Month
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $month;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $year;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Week[]
|
||||||
|
*/
|
||||||
|
private $weeks = [];
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
int $month,
|
||||||
|
int $year
|
||||||
|
) {
|
||||||
|
$this->month = $month;
|
||||||
|
$this->year = $year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
foreach ($this->getWeeks() as $week) {
|
||||||
|
if ($week->isActive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWeeks(): array
|
||||||
|
{
|
||||||
|
if ($this->weeks !== []) {
|
||||||
|
return $this->weeks;
|
||||||
|
}
|
||||||
|
|
||||||
|
$month = $this->getDateTimeInstance();
|
||||||
|
$lastDay = $month->modify('last day of this month')->modify('sunday this week');
|
||||||
|
$currentDay = $month->modify('monday this week');
|
||||||
|
|
||||||
|
while ($currentDay <= $lastDay) {
|
||||||
|
$this->weeks[] = new Week(
|
||||||
|
(int) $currentDay->format('W'),
|
||||||
|
(int) $currentDay->format('Y')
|
||||||
|
);
|
||||||
|
|
||||||
|
$currentDay = $currentDay->modify('+7 days');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->weeks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviousMonth(): Month
|
||||||
|
{
|
||||||
|
$previousMonth = $this->month - 1;
|
||||||
|
$previousYear = $this->year;
|
||||||
|
|
||||||
|
if ($previousMonth <= 0) {
|
||||||
|
$previousMonth = 12;
|
||||||
|
--$previousYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
$previousMonth,
|
||||||
|
$previousYear
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNextMonth(): Month
|
||||||
|
{
|
||||||
|
$nextMonth = $this->month + 1;
|
||||||
|
$nextYear = $this->year;
|
||||||
|
|
||||||
|
if ($nextMonth > 12) {
|
||||||
|
$nextMonth = 1;
|
||||||
|
++$nextYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
$nextMonth,
|
||||||
|
$nextYear
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAsUrlArgument(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'month' => $this->month,
|
||||||
|
'year' => $this->year,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDateTimeInstance(): \DateTimeImmutable
|
||||||
|
{
|
||||||
|
return new \DateTimeImmutable($this->year . '-' . $this->month . '-01');
|
||||||
|
}
|
||||||
|
}
|
30
Classes/Domain/Model/NullDataFactory.php
Normal file
30
Classes/Domain/Model/NullDataFactory.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class NullDataFactory implements ForeignDataFactory
|
||||||
|
{
|
||||||
|
public function getData(Day $day)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
118
Classes/Domain/Model/Week.php
Normal file
118
Classes/Domain/Model/Week.php
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Week
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $week;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $year;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Day[]
|
||||||
|
*/
|
||||||
|
private $days = [];
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
int $week,
|
||||||
|
int $year
|
||||||
|
) {
|
||||||
|
$this->week = $week;
|
||||||
|
$this->year = $year;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
foreach ($this->getDays() as $day) {
|
||||||
|
if ($day->isActive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDays(): array
|
||||||
|
{
|
||||||
|
if ($this->days !== []) {
|
||||||
|
return $this->days;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentDay = $this->getWeek()->modify('monday this week');
|
||||||
|
$endOfWeek = $currentDay->modify('sunday this week');
|
||||||
|
|
||||||
|
while ($currentDay <= $endOfWeek) {
|
||||||
|
$this->days[] = new Day(\DateTime::createFromImmutable($currentDay));
|
||||||
|
$currentDay = $currentDay->modify('+1 day');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->days;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviousWeek(): Week
|
||||||
|
{
|
||||||
|
$newDay = $this->getWeek()->modify('-1 week');
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
(int) $newDay->format('W'),
|
||||||
|
(int) $newDay->format('Y')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNextWeek(): Week
|
||||||
|
{
|
||||||
|
$newDay = $this->getWeek()->modify('+1 week');
|
||||||
|
|
||||||
|
return new self(
|
||||||
|
(int) $newDay->format('W'),
|
||||||
|
(int) $newDay->format('Y')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDateTimeInstance(): \DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->getWeek();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAsUrlArgument(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'week' => $this->week,
|
||||||
|
'year' => $this->year,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getWeek(): \DateTimeImmutable
|
||||||
|
{
|
||||||
|
$week = new \DateTimeImmutable();
|
||||||
|
$week = $week->setISODate($this->year, $this->week);
|
||||||
|
$week = $week->modify('thursday');
|
||||||
|
|
||||||
|
return $week;
|
||||||
|
}
|
||||||
|
}
|
8
Configuration/Services.yaml
Normal file
8
Configuration/Services.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
services:
|
||||||
|
_defaults:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
public: false
|
||||||
|
|
||||||
|
WerkraumMedia\Calendar\:
|
||||||
|
resource: '../Classes/*'
|
8
Resources/Private/Templates/Frontend/Calendar/Day.html
Normal file
8
Resources/Private/Templates/Frontend/Calendar/Day.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
|
||||||
|
data-namespace-typo3-fluid="true">
|
||||||
|
|
||||||
|
<h2>{day.dateTimeInstance -> f:format.date(format: 'd.m.Y')}</h2>
|
||||||
|
|
||||||
|
TODO: Show periods
|
||||||
|
Maybe remove and instead link to filtered list
|
||||||
|
</html>
|
42
Resources/Private/Templates/Frontend/Calendar/Month.html
Normal file
42
Resources/Private/Templates/Frontend/Calendar/Month.html
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
|
||||||
|
data-namespace-typo3-fluid="true">
|
||||||
|
|
||||||
|
<h2>{month.dateTimeInstance -> f:format.date(format: '%B %Y')}</h2>
|
||||||
|
|
||||||
|
<f:link.action action="month" controller="Frontend\Calendar" arguments="{month: month.previousMonth}">
|
||||||
|
Prev Month
|
||||||
|
</f:link.action>
|
||||||
|
<f:link.action action="month" controller="Frontend\Calendar" arguments="{month: month.nextMonth}">
|
||||||
|
Next Month
|
||||||
|
</f:link.action>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>KW</th>
|
||||||
|
<th>Mo</th>
|
||||||
|
<th>Di</th>
|
||||||
|
<th>Mi</th>
|
||||||
|
<th>Do</th>
|
||||||
|
<th>Fr</th>
|
||||||
|
<th>Sa</th>
|
||||||
|
<th>So</th>
|
||||||
|
</tr>
|
||||||
|
<f:for each="{month.weeks}" as="week">
|
||||||
|
<tr class="{f:if(condition: week.active, then: 'active', else: 'inactive')}">
|
||||||
|
<td>
|
||||||
|
<f:link.action action="week" controller="Frontend\Calendar" arguments="{week: week.asUrlArgument}">
|
||||||
|
{week.dateTimeInstance -> f:format.date(format: '%V')}
|
||||||
|
</f:link.action>
|
||||||
|
</td>
|
||||||
|
<f:for each="{week.days}" as="day">
|
||||||
|
<td class="{f:if(condition: day.active, then: 'active', else: 'inactive')}">
|
||||||
|
<f:link.action action="day" controller="Frontend\Calendar" arguments="{day: day.asUrlArgument}">
|
||||||
|
{day.dateTimeInstance -> f:format.date(format: 'd')}
|
||||||
|
</f:link.action>
|
||||||
|
</td>
|
||||||
|
</f:for>
|
||||||
|
</tr>
|
||||||
|
</f:for>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</html>
|
33
Resources/Private/Templates/Frontend/Calendar/Week.html
Normal file
33
Resources/Private/Templates/Frontend/Calendar/Week.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
|
||||||
|
data-namespace-typo3-fluid="true">
|
||||||
|
|
||||||
|
<h2>{week.dateTimeInstance -> f:format.date(format: '%V %Y')}</h2>
|
||||||
|
|
||||||
|
<f:link.action action="week" controller="Frontend\Calendar" arguments="{week: week.previousWeek}">
|
||||||
|
Prev Week
|
||||||
|
</f:link.action>
|
||||||
|
<f:link.action action="week" controller="Frontend\Calendar" arguments="{week: week.nextWeek}">
|
||||||
|
Next Week
|
||||||
|
</f:link.action>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Mo</th>
|
||||||
|
<th>Di</th>
|
||||||
|
<th>Mi</th>
|
||||||
|
<th>Do</th>
|
||||||
|
<th>Fr</th>
|
||||||
|
<th>Sa</th>
|
||||||
|
<th>So</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<f:for each="{week.days}" as="day">
|
||||||
|
<td class="{f:if(condition: day.active, then: 'active', else: 'inactive')}">
|
||||||
|
<f:link.action action="day" controller="Frontend\Calendar" arguments="{day: day.asUrlArgument}">
|
||||||
|
{day.dateTimeInstance -> f:format.date(format: 'd')}
|
||||||
|
</f:link.action>
|
||||||
|
</td>
|
||||||
|
</f:for>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</html>
|
33
Tests/ForcePropertyTrait.php
Normal file
33
Tests/ForcePropertyTrait.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Tests;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
trait ForcePropertyTrait
|
||||||
|
{
|
||||||
|
protected function forceProperty($subject, string $name, $value)
|
||||||
|
{
|
||||||
|
$objectReflection = new \ReflectionObject($subject);
|
||||||
|
$property = $objectReflection->getProperty($name);
|
||||||
|
$property->setAccessible(true);
|
||||||
|
$property->setValue($subject, $value);
|
||||||
|
}
|
||||||
|
}
|
275
Tests/Unit/Controller/Frontend/CalendarControllerTest.php
Normal file
275
Tests/Unit/Controller/Frontend/CalendarControllerTest.php
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Tests\Unit\Controller\Frontend;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 Prophecy\Argument as ProphetArgument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use Prophecy\Prophecy\ObjectProphecy;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Controller\Argument;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
|
||||||
|
use TYPO3\CMS\Extbase\Mvc\Web\Request;
|
||||||
|
use TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration;
|
||||||
|
use WerkraumMedia\Calendar\Controller\Frontend\CalendarController;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Day;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Month;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Week;
|
||||||
|
use WerkraumMedia\Calendar\Tests\ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers WerkraumMedia\Calendar\Controller\Frontend\CalendarController
|
||||||
|
* @testdox The calendar controller
|
||||||
|
*/
|
||||||
|
class CalendarControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
use ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function setsCurrentMonthAsDefaultArgument(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$arguments = $this->allowsMappingOfAllPropertiesForArgument('month')['arguments'];
|
||||||
|
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->hasArgument('month')->willReturn(false);
|
||||||
|
$request->setArguments([
|
||||||
|
'month' => [
|
||||||
|
'month' => date('m'),
|
||||||
|
'year' => date('Y'),
|
||||||
|
],
|
||||||
|
])->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'request', $request->reveal());
|
||||||
|
$this->forceProperty($subject, 'arguments', $arguments->reveal());
|
||||||
|
|
||||||
|
$subject->initializeMonthAction();
|
||||||
|
$request->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function allowsMonthToBeMapped(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$arguments = $this->allowsMappingOfAllPropertiesForArgument('month')['arguments'];
|
||||||
|
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->hasArgument('month')->willReturn(true);
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'request', $request->reveal());
|
||||||
|
$this->forceProperty($subject, 'arguments', $arguments->reveal());
|
||||||
|
|
||||||
|
$subject->initializeMonthAction();
|
||||||
|
$arguments->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function addsMonthToView(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$month = $this->prophesize(Month::class);
|
||||||
|
$view = $this->prophesize(ViewInterface::class);
|
||||||
|
$view->assignMultiple([
|
||||||
|
'month' => $month->reveal(),
|
||||||
|
])->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'view', $view->reveal());
|
||||||
|
|
||||||
|
$subject->monthAction($month->reveal());
|
||||||
|
$view->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function setsCurrentWeekAsDefaultArgument(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$arguments = $this->allowsMappingOfAllPropertiesForArgument('week')['arguments'];
|
||||||
|
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->hasArgument('week')->willReturn(false);
|
||||||
|
$request->setArguments([
|
||||||
|
'week' => [
|
||||||
|
'week' => date('W'),
|
||||||
|
'year' => date('Y'),
|
||||||
|
],
|
||||||
|
])->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'request', $request->reveal());
|
||||||
|
$this->forceProperty($subject, 'arguments', $arguments->reveal());
|
||||||
|
|
||||||
|
$subject->initializeWeekAction();
|
||||||
|
$request->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function allowsWeekToBeMapped(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$arguments = $this->allowsMappingOfAllPropertiesForArgument('week')['arguments'];
|
||||||
|
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->hasArgument('week')->willReturn(true);
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'request', $request->reveal());
|
||||||
|
$this->forceProperty($subject, 'arguments', $arguments->reveal());
|
||||||
|
|
||||||
|
$subject->initializeWeekAction();
|
||||||
|
$arguments->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function addsWeekToView(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$week = $this->prophesize(Week::class);
|
||||||
|
$view = $this->prophesize(ViewInterface::class);
|
||||||
|
$view->assignMultiple([
|
||||||
|
'week' => $week->reveal(),
|
||||||
|
])->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'view', $view->reveal());
|
||||||
|
|
||||||
|
$subject->weekAction($week->reveal());
|
||||||
|
$view->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function setsCurrentDayAsDefaultArgument(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$prophecies = $this->allowsMappingOfAllPropertiesForArgument('day');
|
||||||
|
$propertyConfiguration = $prophecies['propertyMappingConfiguration'];
|
||||||
|
$arguments = $prophecies['arguments'];
|
||||||
|
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->hasArgument('day')->willReturn(false);
|
||||||
|
$request->setArguments(ProphetArgument::that(function (array $arguments) {
|
||||||
|
return count($arguments) === 1
|
||||||
|
&& isset($arguments['day'])
|
||||||
|
&& $arguments['day'] instanceof \DateTimeImmutable
|
||||||
|
&& $arguments['day']->format('Y-m-d') === date('Y-m-d')
|
||||||
|
;
|
||||||
|
}))->shouldBeCalled();
|
||||||
|
|
||||||
|
$configuration = $this->prophesize(PropertyMappingConfiguration::class);
|
||||||
|
$configuration->setTypeConverterOption(
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'Y-m-d'
|
||||||
|
);
|
||||||
|
$propertyConfiguration->forProperty('day')->willReturn($configuration);
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'request', $request->reveal());
|
||||||
|
$this->forceProperty($subject, 'arguments', $arguments->reveal());
|
||||||
|
|
||||||
|
$subject->initializeDayAction();
|
||||||
|
$request->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function configuredMappingForDay(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$prophecies = $this->allowsMappingOfAllPropertiesForArgument('day');
|
||||||
|
$propertyConfiguration = $prophecies['propertyMappingConfiguration'];
|
||||||
|
$arguments = $prophecies['arguments'];
|
||||||
|
|
||||||
|
$request = $this->prophesize(Request::class);
|
||||||
|
$request->hasArgument('day')->willReturn(true);
|
||||||
|
|
||||||
|
$configuration = $this->prophesize(PropertyMappingConfiguration::class);
|
||||||
|
$configuration->setTypeConverterOption(
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'Y-m-d'
|
||||||
|
);
|
||||||
|
$propertyConfiguration->forProperty('day')->willReturn($configuration);
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'request', $request->reveal());
|
||||||
|
$this->forceProperty($subject, 'arguments', $arguments->reveal());
|
||||||
|
|
||||||
|
$subject->initializeDayAction();
|
||||||
|
$arguments->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function addsDayToView(): void
|
||||||
|
{
|
||||||
|
$subject = new CalendarController();
|
||||||
|
|
||||||
|
$day = $this->prophesize(Day::class);
|
||||||
|
$view = $this->prophesize(ViewInterface::class);
|
||||||
|
$view->assignMultiple([
|
||||||
|
'day' => $day->reveal(),
|
||||||
|
])->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'view', $view->reveal());
|
||||||
|
|
||||||
|
$subject->dayAction($day->reveal());
|
||||||
|
$view->checkProphecyMethodsPredictions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function allowsMappingOfAllPropertiesForArgument(string $argumentName): array
|
||||||
|
{
|
||||||
|
$propertyMappingConfiguration = $this->prophesize(PropertyMappingConfiguration::class);
|
||||||
|
$propertyMappingConfiguration->allowAllProperties()->shouldBeCalled();
|
||||||
|
|
||||||
|
$argument = $this->prophesize(Argument::class);
|
||||||
|
$argument->getPropertyMappingConfiguration()->willReturn($propertyMappingConfiguration);
|
||||||
|
|
||||||
|
$arguments = $this->prophesize(Arguments::class);
|
||||||
|
$arguments->getArgument($argumentName)->willReturn($argument->reveal());
|
||||||
|
|
||||||
|
return [
|
||||||
|
'propertyMappingConfiguration' => $propertyMappingConfiguration,
|
||||||
|
'argument' => $argument,
|
||||||
|
'arguments' => $arguments,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
144
Tests/Unit/Domain/Model/DayTest.php
Normal file
144
Tests/Unit/Domain/Model/DayTest.php
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 Prophecy\Argument;
|
||||||
|
use Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Day;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\ForeignDataFactory;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\IsDayActive;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\NullDataFactory;
|
||||||
|
use WerkraumMedia\Calendar\Tests\ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers WerkraumMedia\Calendar\Domain\Model\Day
|
||||||
|
* @testdox A day
|
||||||
|
*/
|
||||||
|
class DayTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
use ForcePropertyTrait;
|
||||||
|
|
||||||
|
public function tearDown(): void
|
||||||
|
{
|
||||||
|
GeneralUtility::purgeInstances();
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function canBeCreated(): void
|
||||||
|
{
|
||||||
|
$subject = new Day(
|
||||||
|
new \DateTime()
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertInstanceOf(Day::class, $subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function providesDateTimeInstance(): void
|
||||||
|
{
|
||||||
|
$dateTimeInstance = new \DateTime();
|
||||||
|
$subject = new Day(
|
||||||
|
$dateTimeInstance
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertInstanceOf(\DateTimeImmutable::class, $subject->getDateTimeInstance());
|
||||||
|
self::assertSame($dateTimeInstance->format('U'), $subject->getDateTimeInstance()->format('U'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function providedDateTimeInstanceHasMidnight(): void
|
||||||
|
{
|
||||||
|
$dateTimeInstance = new \DateTime();
|
||||||
|
$subject = new Day(
|
||||||
|
$dateTimeInstance
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertSame('00:00:00', $subject->getDateTimeInstance()->format('H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function providesItselfAsUrlArgument(): void
|
||||||
|
{
|
||||||
|
$subject = new Day(new \DateTime('2020-10-19'));
|
||||||
|
|
||||||
|
self::assertSame(['day' => '2020-10-19'], $subject->getAsUrlArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function isNotActiveIfNoForeignDataWithInterfaceExists(): void
|
||||||
|
{
|
||||||
|
$subject = new Day(new \DateTime('2020-10-19'));
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'initialized', true);
|
||||||
|
|
||||||
|
self::assertFalse($subject->isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function isNotActiveIfForeignDataIsNotActive(): void
|
||||||
|
{
|
||||||
|
$subject = new Day(new \DateTime('2020-10-19'));
|
||||||
|
|
||||||
|
$foreignData = $this->prophesize(IsDayActive::class);
|
||||||
|
$foreignData->isActive(Argument::any())->willReturn(false);
|
||||||
|
|
||||||
|
$this->forceProperty($subject, 'initialized', true);
|
||||||
|
$this->forceProperty($subject, 'foreignData', $foreignData->reveal());
|
||||||
|
|
||||||
|
self::assertFalse($subject->isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function initializesForeignDataViaFactory(): void
|
||||||
|
{
|
||||||
|
$subject = new Day(new \DateTime('2020-10-19'));
|
||||||
|
|
||||||
|
$foreignData = $this->prophesize(IsDayActive::class);
|
||||||
|
$foreignData->isActive(Argument::any())->willReturn(true);
|
||||||
|
|
||||||
|
$factory = $this->prophesize(ForeignDataFactory::class);
|
||||||
|
$factory->getData($subject)->willReturn($foreignData->reveal());
|
||||||
|
|
||||||
|
GeneralUtility::addInstance(ForeignDataFactory::class, $factory->reveal());
|
||||||
|
|
||||||
|
self::assertTrue($subject->isActive());
|
||||||
|
}
|
||||||
|
}
|
183
Tests/Unit/Domain/Model/MonthTest.php
Normal file
183
Tests/Unit/Domain/Model/MonthTest.php
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Month;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Week;
|
||||||
|
use WerkraumMedia\Calendar\Tests\ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers WerkraumMedia\Calendar\Domain\Model\Month
|
||||||
|
* @testdox A month
|
||||||
|
*/
|
||||||
|
class MonthTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
use ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function canBeCreated(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(1, 2020);
|
||||||
|
|
||||||
|
self::assertInstanceOf(Month::class, $subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsPreviousMonthForSameYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(2, 2020);
|
||||||
|
|
||||||
|
self::assertSame('01', $subject->getPreviousMonth()->getDateTimeInstance()->format('m'));
|
||||||
|
self::assertSame('2020', $subject->getPreviousMonth()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsPreviousMonthForPreviousYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(1, 2020);
|
||||||
|
|
||||||
|
self::assertSame('12', $subject->getPreviousMonth()->getDateTimeInstance()->format('m'));
|
||||||
|
self::assertSame('2019', $subject->getPreviousMonth()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNextMonthForSameYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(1, 2020);
|
||||||
|
|
||||||
|
self::assertSame('02', $subject->getNextMonth()->getDateTimeInstance()->format('m'));
|
||||||
|
self::assertSame('2020', $subject->getNextMonth()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNextMonthForNextYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(12, 2020);
|
||||||
|
|
||||||
|
self::assertSame('01', $subject->getNextMonth()->getDateTimeInstance()->format('m'));
|
||||||
|
self::assertSame('2021', $subject->getNextMonth()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsFiveWeeksForDecember2020(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(12, 2020);
|
||||||
|
$weeks = $subject->getWeeks();
|
||||||
|
|
||||||
|
self::assertCount(5, $weeks);
|
||||||
|
self::assertSame('2020-11-30', $weeks[0]->getDays()[0]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2021-01-03', $weeks[4]->getDays()[6]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsSixWeeksForNovember2020(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(11, 2020);
|
||||||
|
$weeks = $subject->getWeeks();
|
||||||
|
|
||||||
|
self::assertCount(6, $weeks);
|
||||||
|
self::assertSame('2020-10-26', $weeks[0]->getDays()[0]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-12-06', $weeks[5]->getDays()[6]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsSameWeeksOnSecondCall(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(11, 2020);
|
||||||
|
|
||||||
|
self::assertSame($subject->getWeeks(), $subject->getWeeks());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function providesDateTimeInstance(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(02, 2018);
|
||||||
|
|
||||||
|
self::assertSame('2018-02-01', $subject->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsAsUrlArguments(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(02, 2018);
|
||||||
|
|
||||||
|
self::assertSame([
|
||||||
|
'month' => 2,
|
||||||
|
'year' => 2018,
|
||||||
|
], $subject->getAsUrlArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNotActiveIfAllWeeksAreInactive(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(02, 2018);
|
||||||
|
|
||||||
|
$week = $this->prophesize(Week::class);
|
||||||
|
$week->isActive()->willReturn(false);
|
||||||
|
$weeks = [$week->reveal()];
|
||||||
|
$this->forceProperty($subject, 'weeks', $weeks);
|
||||||
|
|
||||||
|
self::assertFalse($subject->isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsActiveIfASingleWeekIsActive(): void
|
||||||
|
{
|
||||||
|
$subject = new Month(02, 2018);
|
||||||
|
|
||||||
|
$week = $this->prophesize(Week::class);
|
||||||
|
$week->isActive()->willReturn(true);
|
||||||
|
$week2 = $this->prophesize(Week::class);
|
||||||
|
$week2->isActive()->willReturn(false);
|
||||||
|
$weeks = [$week->reveal(), $week2->reveal()];
|
||||||
|
$this->forceProperty($subject, 'weeks', $weeks);
|
||||||
|
|
||||||
|
self::assertTrue($subject->isActive());
|
||||||
|
}
|
||||||
|
}
|
45
Tests/Unit/Domain/Model/NullDataFactoryTest.php
Normal file
45
Tests/Unit/Domain/Model/NullDataFactoryTest.php
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Day;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\NullDataFactory;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers WerkraumMedia\Calendar\Domain\Model\NullDataFactory
|
||||||
|
*/
|
||||||
|
class NullDataFactoryTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNull(): void
|
||||||
|
{
|
||||||
|
$subject = new NullDataFactory();
|
||||||
|
$day = $this->prophesize(Day::class);
|
||||||
|
self::assertNull($subject->getData($day->reveal()));
|
||||||
|
}
|
||||||
|
}
|
235
Tests/Unit/Domain/Model/WeekTest.php
Normal file
235
Tests/Unit/Domain/Model/WeekTest.php
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace WerkraumMedia\Calendar\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 Prophecy\PhpUnit\ProphecyTrait;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Day;
|
||||||
|
use WerkraumMedia\Calendar\Domain\Model\Week;
|
||||||
|
use WerkraumMedia\Calendar\Tests\ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers WerkraumMedia\Calendar\Domain\Model\Week
|
||||||
|
* @testdox A week
|
||||||
|
*/
|
||||||
|
class WeekTest extends TestCase
|
||||||
|
{
|
||||||
|
use ProphecyTrait;
|
||||||
|
use ForcePropertyTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function canBeCreated(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2020);
|
||||||
|
|
||||||
|
self::assertInstanceOf(Week::class, $subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsSevenDays(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2020);
|
||||||
|
|
||||||
|
self::assertCount(7, $subject->getDays());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsSameDaysOnSecondCall(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2020);
|
||||||
|
|
||||||
|
self::assertSame($subject->getDays(), $subject->getDays());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsDaysForWeek1(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2020);
|
||||||
|
$days = $subject->getDays();
|
||||||
|
|
||||||
|
self::assertSame('2019-12-30', $days[0]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2019-12-31', $days[1]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-01-01', $days[2]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-01-02', $days[3]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-01-03', $days[4]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-01-04', $days[5]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-01-05', $days[6]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsDaysForWeek53(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(53, 2020);
|
||||||
|
$days = $subject->getDays();
|
||||||
|
|
||||||
|
self::assertSame('2020-12-28', $days[0]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-12-29', $days[1]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-12-30', $days[2]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2020-12-31', $days[3]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2021-01-01', $days[4]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2021-01-02', $days[5]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
self::assertSame('2021-01-03', $days[6]->getDateTimeInstance()->format('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsPreviousWeekForSameYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(2, 2020);
|
||||||
|
|
||||||
|
self::assertSame('01', $subject->getPreviousWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2020', $subject->getPreviousWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsPreviousWeekForYearSwitchFrom2019To2018(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2019);
|
||||||
|
|
||||||
|
self::assertSame('52', $subject->getPreviousWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2018', $subject->getPreviousWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsPreviousWeekForYearSwitchFrom2018To2017(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2018);
|
||||||
|
|
||||||
|
self::assertSame('52', $subject->getPreviousWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2017', $subject->getPreviousWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsPreviousWeekForPreviousYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2021);
|
||||||
|
|
||||||
|
self::assertSame('53', $subject->getPreviousWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2020', $subject->getPreviousWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNextWeekForSameYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(1, 2020);
|
||||||
|
|
||||||
|
self::assertSame('02', $subject->getNextWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2020', $subject->getNextWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNextWeekForNextYear(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(53, 2020);
|
||||||
|
|
||||||
|
self::assertSame('01', $subject->getNextWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2021', $subject->getNextWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNextWeekForNextYearFrom2018To2019(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(52, 2018);
|
||||||
|
|
||||||
|
self::assertSame('01', $subject->getNextWeek()->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2019', $subject->getNextWeek()->getDateTimeInstance()->format('Y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function providesDateTimeInstance(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(52, 2018);
|
||||||
|
|
||||||
|
self::assertSame('52', $subject->getDateTimeInstance()->format('W'));
|
||||||
|
self::assertSame('2018-12-27 Thursday', $subject->getDateTimeInstance()->format('Y-m-d l'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function providesItselfAsUrlArgument(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(52, 2018);
|
||||||
|
|
||||||
|
self::assertSame([
|
||||||
|
'week' => 52,
|
||||||
|
'year' => 2018,
|
||||||
|
], $subject->getAsUrlArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsNotActiveIfAllDaysAreInactive(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(02, 2018);
|
||||||
|
|
||||||
|
$day = $this->prophesize(Day::class);
|
||||||
|
$day->isActive()->willReturn(false);
|
||||||
|
$days = [$day->reveal()];
|
||||||
|
$this->forceProperty($subject, 'days', $days);
|
||||||
|
|
||||||
|
self::assertFalse($subject->isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function returnsActiveIfASingleDayActive(): void
|
||||||
|
{
|
||||||
|
$subject = new Week(02, 2018);
|
||||||
|
|
||||||
|
$day = $this->prophesize(Day::class);
|
||||||
|
$day->isActive()->willReturn(true);
|
||||||
|
$day2 = $this->prophesize(Day::class);
|
||||||
|
$day2->isActive()->willReturn(false);
|
||||||
|
$days = [$day->reveal(), $day2->reveal()];
|
||||||
|
$this->forceProperty($subject, 'days', $days);
|
||||||
|
|
||||||
|
self::assertTrue($subject->isActive());
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
"sort-packages": true
|
"sort-packages": true
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"php": "^7.3.0 || ^7.4.0",
|
||||||
"typo3/cms-core": "^10.4",
|
"typo3/cms-core": "^10.4",
|
||||||
"typo3/cms-extbase": "^10.4"
|
"typo3/cms-extbase": "^10.4"
|
||||||
},
|
},
|
||||||
|
@ -28,8 +29,10 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"jangregor/phpstan-prophecy": "^0.6.2",
|
"jangregor/phpstan-prophecy": "^0.6.2",
|
||||||
|
"maglnet/composer-require-checker": "^2.1",
|
||||||
"phpspec/prophecy-phpunit": "^2.0",
|
"phpspec/prophecy-phpunit": "^2.0",
|
||||||
"phpunit/phpunit": "^9.4"
|
"phpunit/phpunit": "^9.4",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"typo3/cms": {
|
"typo3/cms": {
|
||||||
|
|
21
ext_emconf.php
Normal file
21
ext_emconf.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$EM_CONF['calendar'] = [
|
||||||
|
'title' => 'Calendar',
|
||||||
|
'description' => 'API for extensions to create calendar',
|
||||||
|
'category' => 'misc',
|
||||||
|
'author' => 'Daniel Siepmann',
|
||||||
|
'author_email' => 'coding@daniel-siepmann.de',
|
||||||
|
'author_company' => 'Codappix GmbH',
|
||||||
|
'state' => 'alpha',
|
||||||
|
'uploadfolder' => 0,
|
||||||
|
'clearCacheOnLoad' => 0,
|
||||||
|
'version' => '1.0.0',
|
||||||
|
'constraints' => [
|
||||||
|
'depends' => [
|
||||||
|
'typo3' => '*',
|
||||||
|
],
|
||||||
|
'conflicts' => [],
|
||||||
|
'suggests' => [],
|
||||||
|
],
|
||||||
|
];
|
19
phpcs.xml.dist
Normal file
19
phpcs.xml.dist
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset name="project">
|
||||||
|
<description>This project coding standard</description>
|
||||||
|
|
||||||
|
<file>Classes/</file>
|
||||||
|
<file>Tests/</file>
|
||||||
|
|
||||||
|
<!-- Set default settings -->
|
||||||
|
<arg value="sp"/>
|
||||||
|
<arg name="colors"/>
|
||||||
|
<arg name="encoding" value="utf-8" />
|
||||||
|
<arg name="extensions" value="php" />
|
||||||
|
|
||||||
|
<!-- Base rules -->
|
||||||
|
<rule ref="PSR12" />
|
||||||
|
<rule ref="Generic.Files.LineLength.TooLong">
|
||||||
|
<exclude-pattern>/Tests/*</exclude-pattern>
|
||||||
|
</rule>
|
||||||
|
</ruleset>
|
30
phpunit.xml.dist
Normal file
30
phpunit.xml.dist
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<phpunit
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||||
|
backupGlobals="false"
|
||||||
|
backupStaticAttributes="false"
|
||||||
|
colors="true"
|
||||||
|
convertErrorsToExceptions="true"
|
||||||
|
convertWarningsToExceptions="true"
|
||||||
|
forceCoversAnnotation="false"
|
||||||
|
processIsolation="false"
|
||||||
|
stopOnError="false"
|
||||||
|
stopOnFailure="false"
|
||||||
|
stopOnIncomplete="false"
|
||||||
|
stopOnSkipped="false"
|
||||||
|
verbose="false"
|
||||||
|
>
|
||||||
|
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="unit">
|
||||||
|
<directory>Tests/Unit/</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<coverage>
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">Classes</directory>
|
||||||
|
</include>
|
||||||
|
</coverage>
|
||||||
|
</phpunit>
|
Loading…
Reference in a new issue