diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..2cd720b --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,24 @@ +# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC +name: Tests + +on: + push: + branches: [main, master, "feature/**"] + pull_request: + +jobs: + phpunit: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ["8.3", "8.4"] + name: PHPUnit (PHP ${{ matrix.php }}) + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + - run: composer install --no-interaction --no-progress + - run: vendor/bin/phpunit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cff2af8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC +/vendor/ +/composer.lock +/.phpunit.cache/ diff --git a/composer.json b/composer.json index 07d5514..fe0e734 100644 --- a/composer.json +++ b/composer.json @@ -13,9 +13,13 @@ "php": ">=8.2", "symfony/framework-bundle": "^7.0", "symfony/messenger": "^7.0", + "symfony/uid": "^7.0", "doctrine/orm": "^3.0", "doctrine/doctrine-bundle": "^2.0" }, + "require-dev": { + "phpunit/phpunit": "^12.0" + }, "autoload": { "psr-4": { "Dmstr\\SymfonyJobQueue\\": "src/" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8086794 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +# file generated with AI assistance: Claude Code - 2026-06-13 23:14:54 UTC +# CLI-only test runner for this bundle — no MySQL/FPM required. +# Usage (on host): +# docker compose run --rm php +# Runs `composer install` then PHPUnit against tests/. +services: + php: + build: + dockerfile_inline: | + FROM php:8.4-cli-alpine + COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + working_dir: /repo + volumes: + - .:/repo + command: sh -c "composer install --no-interaction --no-progress && vendor/bin/phpunit" diff --git a/phpunit.dist.xml b/phpunit.dist.xml new file mode 100644 index 0000000..9dc4142 --- /dev/null +++ b/phpunit.dist.xml @@ -0,0 +1,18 @@ + + + + + + tests + + + + + src + + + diff --git a/tests/Entity/JobTest.php b/tests/Entity/JobTest.php new file mode 100644 index 0000000..85f610b --- /dev/null +++ b/tests/Entity/JobTest.php @@ -0,0 +1,75 @@ +getId()), 'id must be a valid UUID'); + self::assertSame('pending', $job->getStatus()); + self::assertSame(0, $job->getProgress()); + self::assertSame([], $job->getInputData()); + self::assertNull($job->getResultData()); + self::assertNull($job->getErrorMessage()); + self::assertNull($job->getStartedAt()); + self::assertNull($job->getCompletedAt()); + self::assertInstanceOf(\DateTimeImmutable::class, $job->getCreatedAt()); + self::assertInstanceOf(\DateTimeImmutable::class, $job->getUpdatedAt()); + } + + public function testEachJobGetsAUniqueId(): void + { + self::assertNotSame((new Job())->getId(), (new Job())->getId()); + } + + public function testFluentSettersUpdateState(): void + { + $job = new Job(); + $started = new \DateTimeImmutable('2026-01-01 10:00:00'); + $completed = new \DateTimeImmutable('2026-01-01 10:05:00'); + + $result = $job + ->setType('ref_project_scan') + ->setStatus('completed') + ->setInputData(['apiConfiguration' => ['uuid' => '5302d197']]) + ->setResultData(['imported' => 42]) + ->setErrorMessage('none') + ->setProgress(100) + ->setStartedAt($started) + ->setCompletedAt($completed); + + self::assertSame($job, $result, 'setters must be fluent'); + self::assertSame('ref_project_scan', $job->getType()); + self::assertSame('completed', $job->getStatus()); + self::assertSame(['apiConfiguration' => ['uuid' => '5302d197']], $job->getInputData()); + self::assertSame(['imported' => 42], $job->getResultData()); + self::assertSame('none', $job->getErrorMessage()); + self::assertSame(100, $job->getProgress()); + self::assertSame($started, $job->getStartedAt()); + self::assertSame($completed, $job->getCompletedAt()); + } + + public function testOnPreUpdateRefreshesUpdatedAt(): void + { + $job = new Job(); + $job->onPreUpdate(); + + self::assertInstanceOf(\DateTimeImmutable::class, $job->getUpdatedAt()); + self::assertGreaterThanOrEqual($job->getCreatedAt(), $job->getUpdatedAt()); + } +} diff --git a/tests/Message/JobMessageTest.php b/tests/Message/JobMessageTest.php new file mode 100644 index 0000000..e80687a --- /dev/null +++ b/tests/Message/JobMessageTest.php @@ -0,0 +1,26 @@ +getJobId()); + } + + public function testDistinctMessagesKeepTheirOwnId(): void + { + self::assertSame('a', (new JobMessage('a'))->getJobId()); + self::assertSame('b', (new JobMessage('b'))->getJobId()); + } +}