diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 313284a..d23e48b 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -14,3 +14,6 @@ jobs:
- name: Test CGL
run: ./vendor/bin/phpcs
+
+ - name: Execute PHPUnit Tests
+ run: ./vendor/bin/phpunit
diff --git a/Tests/Unit/Domain/Model/PageviewTest.php b/Tests/Unit/Domain/Model/PageviewTest.php
new file mode 100644
index 0000000..87f5b1c
--- /dev/null
+++ b/Tests/Unit/Domain/Model/PageviewTest.php
@@ -0,0 +1,169 @@
+
+ *
+ * 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 DanielSiepmann\Tracking\Domain\Model\Pageview;
+use PHPUnit\Framework\TestCase;
+use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
+
+/**
+ * @covers DanielSiepmann\Tracking\Domain\Model\Pageview
+ */
+class PageviewTest extends TestCase
+{
+ /**
+ * @test
+ */
+ public function canBeCreated()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $subject = new Pageview(
+ 0,
+ $language->reveal(),
+ new \DateTimeImmutable(),
+ 0,
+ '',
+ ''
+ );
+
+ static::assertInstanceOf(Pageview::class, $subject);
+ }
+
+ /**
+ * @test
+ */
+ public function returnsPageUid()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $subject = new Pageview(
+ 500,
+ $language->reveal(),
+ new \DateTimeImmutable(),
+ 0,
+ '',
+ ''
+ );
+
+ static::assertSame(500, $subject->getPageUid());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsLanguage()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $subject = new Pageview(
+ 0,
+ $language->reveal(),
+ new \DateTimeImmutable(),
+ 0,
+ '',
+ ''
+ );
+
+ static::assertSame($language->reveal(), $subject->getLanguage());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsCrdate()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+ $crdate = new \DateTimeImmutable();
+
+ $subject = new Pageview(
+ 0,
+ $language->reveal(),
+ $crdate,
+ 0,
+ '',
+ ''
+ );
+
+ static::assertSame($crdate, $subject->getCrdate());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsPageType()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $subject = new Pageview(
+ 0,
+ $language->reveal(),
+ new \DateTimeImmutable(),
+ 999,
+ '',
+ ''
+ );
+
+ static::assertSame(999, $subject->getPageType());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsUrl()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $subject = new Pageview(
+ 0,
+ $language->reveal(),
+ new \DateTimeImmutable(),
+ 0,
+ 'https://example.com/path.html',
+ ''
+ );
+
+ static::assertSame('https://example.com/path.html', $subject->getUrl());
+ }
+
+ /**
+ * @test
+ */
+ public function returnsUserAgent()
+ {
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $subject = new Pageview(
+ 0,
+ $language->reveal(),
+ new \DateTimeImmutable(),
+ 0,
+ '',
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
+ );
+
+ static::assertSame(
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
+ $subject->getUserAgent()
+ );
+ }
+}
diff --git a/Tests/Unit/Domain/Pageview/FactoryTest.php b/Tests/Unit/Domain/Pageview/FactoryTest.php
new file mode 100644
index 0000000..0c97d35
--- /dev/null
+++ b/Tests/Unit/Domain/Pageview/FactoryTest.php
@@ -0,0 +1,196 @@
+
+ *
+ * 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 DanielSiepmann\Tracking\Domain\Model\Pageview;
+use DanielSiepmann\Tracking\Domain\Pageview\Factory;
+use PHPUnit\Framework\TestCase;
+use Psr\Http\Message\ServerRequestInterface;
+use TYPO3\CMS\Core\Routing\PageArguments;
+use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
+
+/**
+ * @covers DanielSiepmann\Tracking\Domain\Pageview\Factory
+ */
+class FactoryTest extends TestCase
+{
+ /**
+ * @test
+ */
+ public function returnsPageview()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertInstanceOf(Pageview::class, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function returnedPageviewContainsUserAgent()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0'
+ ]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertSame(
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
+ $result->getUserAgent()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function returnedPageviewContainsUri()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('https://example.com/path?query=params&some=more#anchor');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertSame(
+ 'https://example.com/path?query=params&some=more#anchor',
+ $result->getUrl()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function returnedPageviewContainsPageType()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(50);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertSame(
+ 50,
+ $result->getPageType()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function returnedPageviewContainsDateTime()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertInstanceOf(\DateTimeImmutable::class, $result->getCrdate());
+ }
+
+ /**
+ * @test
+ */
+ public function returnedPageviewContainsLanguage()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertInstanceOf(SiteLanguage::class, $result->getLanguage());
+ }
+
+ /**
+ * @test
+ */
+ public function returnedPageviewContainsPageId()
+ {
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $result = Factory::fromRequest($request->reveal());
+ static::assertSame(
+ 10,
+ $result->getPageUid()
+ );
+ }
+}
diff --git a/Tests/Unit/Domain/Repository/PageviewTest.php b/Tests/Unit/Domain/Repository/PageviewTest.php
new file mode 100644
index 0000000..bd07858
--- /dev/null
+++ b/Tests/Unit/Domain/Repository/PageviewTest.php
@@ -0,0 +1,72 @@
+
+ *
+ * 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 DanielSiepmann\Tracking\Domain\Model\Pageview as Model;
+use DanielSiepmann\Tracking\Domain\Repository\Pageview;
+use PHPUnit\Framework\TestCase;
+use TYPO3\CMS\Core\Database\Connection;
+use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
+
+/**
+ * @covers DanielSiepmann\Tracking\Domain\Repository\Pageview
+ */
+class PageviewTest extends TestCase
+{
+ /**
+ * @test
+ */
+ public function modelCanBeAdded()
+ {
+ $connection = $this->prophesize(Connection::class);
+
+ $dateTime = $this->prophesize(\DateTimeImmutable::class);
+ $dateTime->format('U')->willReturn(1582660189);
+
+ $language = $this->prophesize(SiteLanguage::class);
+ $language->getLanguageId()->willReturn(2);
+
+ $model = $this->prophesize(Model::class);
+ $model->getPageUid()->willReturn(10);
+ $model->getCrdate()->willReturn($dateTime->reveal());
+ $model->getPageType()->willReturn(999);
+ $model->getLanguage()->willReturn($language->reveal());
+ $model->getUrl()->willReturn('https://example.com/path.html');
+ $model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
+
+ $connection->insert(
+ 'tx_tracking_pageview',
+ [
+ 'pid' => 10,
+ 'crdate' => 1582660189,
+ 'tstamp' => 1582660189,
+ 'type' => 999,
+ 'sys_language_uid' => 2,
+ 'url' => 'https://example.com/path.html',
+ 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0',
+ ]
+ )->willReturn(1)->shouldBeCalledTimes(1);
+
+ $subject = new Pageview($connection->reveal());
+ $subject->add($model->reveal());
+ }
+}
diff --git a/Tests/Unit/Middleware/PageviewTest.php b/Tests/Unit/Middleware/PageviewTest.php
new file mode 100644
index 0000000..5f88677
--- /dev/null
+++ b/Tests/Unit/Middleware/PageviewTest.php
@@ -0,0 +1,95 @@
+
+ *
+ * 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 DanielSiepmann\Tracking\Domain\Model\Pageview as Model;
+use DanielSiepmann\Tracking\Domain\Repository\Pageview as Repository;
+use DanielSiepmann\Tracking\Middleware\Pageview;
+use PHPUnit\Framework\TestCase;
+use Prophecy\Argument;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Routing\PageArguments;
+use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
+
+/**
+ * @covers DanielSiepmann\Tracking\Middleware\Pageview
+ */
+class PageviewTest extends TestCase
+{
+ /**
+ * @test
+ */
+ public function doesNotAddBlacklistedRequest()
+ {
+ $repository = $this->prophesize(Repository::class);
+ $context = $this->prophesize(Context::class);
+ $rule = 'false';
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $response = $this->prophesize(ResponseInterface::class);
+ $handler = $this->prophesize(RequestHandlerInterface::class);
+
+ $handler->handle($request->reveal())->willReturn($response->reveal());
+ $repository->add()->shouldNotBeCalled();
+
+ $subject = new Pageview($repository->reveal(), $context->reveal(), $rule);
+ $result = $subject->process($request->reveal(), $handler->reveal());
+
+ static::assertInstanceOf(ResponseInterface::class, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function addsPageviewToRepository()
+ {
+ $repository = $this->prophesize(Repository::class);
+ $context = $this->prophesize(Context::class);
+ $rule = 'true';
+
+ $routing = $this->prophesize(PageArguments::class);
+ $routing->getPageId()->willReturn(10);
+ $routing->getPageType()->willReturn(0);
+
+ $language = $this->prophesize(SiteLanguage::class);
+
+ $request = $this->prophesize(ServerRequestInterface::class);
+ $request->getAttribute('routing')->willReturn($routing->reveal());
+ $request->getAttribute('language')->willReturn($language->reveal());
+ $request->getUri()->willReturn('');
+ $request->getHeader('User-Agent')->willReturn([]);
+
+ $response = $this->prophesize(ResponseInterface::class);
+ $handler = $this->prophesize(RequestHandlerInterface::class);
+
+ $handler->handle($request->reveal())->willReturn($response->reveal());
+ $repository->add(Argument::type(Model::class))->shouldBeCalledtimes(1);
+
+ $subject = new Pageview($repository->reveal(), $context->reveal(), $rule);
+ $result = $subject->process($request->reveal(), $handler->reveal());
+
+ static::assertInstanceOf(ResponseInterface::class, $result);
+ }
+}
diff --git a/composer.json b/composer.json
index ee05abe..32ef533 100644
--- a/composer.json
+++ b/composer.json
@@ -14,6 +14,11 @@
"DanielSiepmann\\Tracking\\": "Classes/"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "DanielSiepmann\\Tracking\\Tests\\": "Tests/"
+ }
+ },
"require": {
"doctrine/dbal": "^2.10",
"php": "^7.3.0",
@@ -43,6 +48,7 @@
]
},
"require-dev": {
- "squizlabs/php_codesniffer": "^3.5"
+ "squizlabs/php_codesniffer": "^3.5",
+ "phpunit/phpunit": "^9.0"
}
}
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 0fe8bf8..936068c 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -3,6 +3,7 @@
This project coding standard
Classes/
+ Tests/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..4ae4c2d
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,26 @@
+
+
+
+
+ Tests/Unit/
+
+
+
+
+
+ Classes
+
+
+