diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5063eb9..df71e4a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -70,3 +70,49 @@ jobs:
run: "composer update --no-progress"
- name: "Run the tests"
run: "composer ci:tests:unit"
+
+ functional-tests:
+ name: Functional Tests
+ runs-on: ubuntu-22.04
+ needs: [ code-quality ]
+ strategy:
+ matrix:
+ php-version:
+ - '8.2'
+ - '8.3'
+ env:
+ DB_DATABASE: typo3
+ DB_USER: root
+ DB_PASSWORD: root
+ DB_HOST: 127.0.0.1
+
+ steps:
+ - name: "Checkout"
+ uses: actions/checkout@v4
+ - name: "Install PHP"
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: "${{ matrix.php-version }}"
+ coverage: none
+ tools: composer:v2.6
+ - name: "Show Composer version"
+ run: composer --version
+ - name: "Show the Composer configuration"
+ run: composer config --global --list
+ - name: "Cache dependencies installed with composer"
+ uses: actions/cache@v4
+ with:
+ key: "php${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }}"
+ path: ~/.cache/composer
+ restore-keys: "php${{ matrix.php-version }}-composer-\n"
+ - name: "Install Composer dependencies"
+ run: "composer update --no-progress"
+ - name: "Start MySQL"
+ run: "sudo /etc/init.d/mysql start"
+ - name: "Run the tests"
+ run: |
+ export typo3DatabaseName="$DB_DATABASE";
+ export typo3DatabaseHost="$DB_HOST";
+ export typo3DatabaseUsername="$DB_USER";
+ export typo3DatabasePassword="$DB_PASSWORD";
+ composer ci:tests:functional
diff --git a/Classes/Domain/Model/PublishedItem.php b/Classes/Domain/Model/PublishedItem.php
index df77fb3..0967e12 100755
--- a/Classes/Domain/Model/PublishedItem.php
+++ b/Classes/Domain/Model/PublishedItem.php
@@ -968,7 +968,7 @@ public function getComposers(): string
return Collection::wrap($this->containedWorks->toArray())->
map( function($work) { return self::getWorkComposerName($work); } )->
unique()->
- join(';');
+ join('; ');
}
protected static function getComposerName(GndPerson $composer): string
diff --git a/Tests/Functional/Domain/Model/PublishedItemTest.php b/Tests/Functional/Domain/Model/PublishedItemTest.php
new file mode 100644
index 0000000..d2cc768
--- /dev/null
+++ b/Tests/Functional/Domain/Model/PublishedItemTest.php
@@ -0,0 +1,141 @@
+
+ */
+class PublishedItemTest extends FunctionalTestCase
+{
+ /**
+ * @var \Slub\PublisherDb\Domain\Model\PublishedItem
+ */
+ protected ?PublishedItem $subject = null;
+
+ /**
+ * @var \Slub\DmNorm\Domain\Model\GndPerson
+ */
+ protected ?GndPerson $composer1 = null;
+
+ /**
+ * @var \Slub\DmNorm\Domain\Model\GndPerson
+ */
+ protected ?GndPerson $composer2 = null;
+
+ /**
+ * @var \Slub\DmNorm\Domain\Model\GndWork
+ */
+ protected ?GndWork $work1 = null;
+
+ /**
+ * @var \Slub\DmNorm\Domain\Model\GndWork
+ */
+ protected ?GndWork $work2 = null;
+
+ /**
+ * @var string
+ */
+ protected string $nameComposer1 = 'Composer 1';
+
+ /**
+ * @var string
+ */
+ protected string $nameComposer2 = 'Composer 2';
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+ $this->subject = new PublishedItem();
+
+ $this->composer1 = new GndPerson();
+ $this->composer2 = new GndPerson();
+ $this->composer1->setName($this->nameComposer1);
+ $this->composer2->setName($this->nameComposer2);
+
+ $this->work1 = new GndWork();
+ $this->work2 = new GndWork();
+ $this->work1->setFirstComposer($this->composer1);
+ $this->work2->setFirstComposer($this->composer2);
+ }
+
+ protected function tearDown(): void
+ {
+ parent::tearDown();
+ }
+
+ /**
+ * @test
+ */
+ public function publishedItemWithOneComposerReturnsComposer()
+ {
+ $this->subject->addFirstComposer($this->composer1);
+
+ self::assertSame(
+ $this->nameComposer1,
+ $this->subject->getComposers()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function publishedItemWithManyComposersReturnsComposers()
+ {
+ $this->subject->addFirstComposer($this->composer1);
+ $this->subject->addFirstComposer($this->composer2);
+ $namesString = implode('; ', [$this->nameComposer1, $this->nameComposer2]);
+
+ self::assertSame(
+ $namesString,
+ $this->subject->getComposers()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function publishedItemWithoutComposersReturnsOneWorkComposer()
+ {
+ $this->subject->addContainedWork($this->work1);
+
+ self::assertSame(
+ $this->nameComposer1,
+ $this->subject->getComposers()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function publishedItemWithoutComposerReturnsManyWorkComposers()
+ {
+ $this->subject->addContainedWork($this->work1);
+ $this->subject->addContainedWork($this->work2);
+ $namesString = implode('; ', [$this->nameComposer1, $this->nameComposer2]);
+
+ self::assertSame(
+ $namesString,
+ $this->subject->getComposers()
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function publishedItemWithoutComposerWithoutWorkcomposersReturnsString()
+ {
+ self::assertSame(
+ '',
+ $this->subject->getComposers()
+ );
+ }
+
+}
diff --git a/composer.json b/composer.json
index 73a53db..107dd39 100755
--- a/composer.json
+++ b/composer.json
@@ -47,8 +47,9 @@
"ci": [ "@ci:php", "@ci:tests" ],
"ci:php": [ "@ci:php:stan" ],
"ci:php:stan": [ "phpstan analyse Classes" ],
- "ci:tests": [ "@ci:tests:unit" ],
- "ci:tests:unit": [ "phpunit -c config/UnitTests.xml" ]
+ "ci:tests": [ "@ci:tests:unit", "@ci:tests:functional" ],
+ "ci:tests:unit": [ "phpunit -c config/UnitTests.xml" ],
+ "ci:tests:functional": [ "phpunit -c config/FunctionalTests.xml" ]
},
"extra": {
"typo3/cms": {
diff --git a/config/FunctionalTests.xml b/config/FunctionalTests.xml
new file mode 100644
index 0000000..8fbde7e
--- /dev/null
+++ b/config/FunctionalTests.xml
@@ -0,0 +1,29 @@
+
+
+
+
+ ../Tests/Functional
+
+
+
+
+
+
+
+
+
+
diff --git a/config/UnitTests.xml b/config/UnitTests.xml
index a644f4f..81d74fd 100644
--- a/config/UnitTests.xml
+++ b/config/UnitTests.xml
@@ -8,7 +8,6 @@
colors="true"
failOnRisky="true"
failOnWarning="true"
- requireCoverageMetadata="true"
>
@@ -16,12 +15,6 @@
-
-