2 Commits

Author SHA1 Message Date
eb6d5bfd9d Base64 tests 2025-11-03 22:05:44 +01:00
edd34e9240 All the tests 2025-11-03 21:30:40 +01:00
11 changed files with 348 additions and 254 deletions

View File

@@ -165,7 +165,6 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-uuid" /> <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/brevo-mailer" /> <excludeFolder url="file://$MODULE_DIR$/vendor/symfony/brevo-mailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" /> <excludeFolder url="file://$MODULE_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
<excludeFolder url="file://$MODULE_DIR$/vendor/brianium/paratest" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dama/doctrine-test-bundle" /> <excludeFolder url="file://$MODULE_DIR$/vendor/dama/doctrine-test-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" /> <excludeFolder url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" />
<excludeFolder url="file://$MODULE_DIR$/vendor/stof/doctrine-extensions-bundle" /> <excludeFolder url="file://$MODULE_DIR$/vendor/stof/doctrine-extensions-bundle" />

282
.idea/php.xml generated
View File

@@ -36,170 +36,168 @@
</component> </component>
<component name="PhpIncludePathManager"> <component name="PhpIncludePathManager">
<include_path> <include_path>
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/symfonycasts/sass-bundle" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/phpstan-safe-rule" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/safe" />
<path value="$PROJECT_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
<path value="$PROJECT_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
<path value="$PROJECT_DIR$/vendor/symfonycasts/verify-email-bundle" />
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/masterminds/html5" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/composer" /> <path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" /> <path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" /> <path value="$PROJECT_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
<path value="$PROJECT_DIR$/vendor/psr/cache" /> <path value="$PROJECT_DIR$/vendor/dama/doctrine-test-bundle" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" /> <path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
<path value="$PROJECT_DIR$/vendor/fidry/cpu-core-counter" />
<path value="$PROJECT_DIR$/vendor/twig/twig" />
<path value="$PROJECT_DIR$/vendor/twig/intl-extra" />
<path value="$PROJECT_DIR$/vendor/react/promise" />
<path value="$PROJECT_DIR$/vendor/react/stream" />
<path value="$PROJECT_DIR$/vendor/react/cache" />
<path value="$PROJECT_DIR$/vendor/react/event-loop" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/psr/http-client" /> <path value="$PROJECT_DIR$/vendor/psr/http-client" />
<path value="$PROJECT_DIR$/vendor/psr/container" /> <path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" /> <path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/clue/ndjson-react" /> <path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/psr/http-factory" /> <path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/psr/clock" /> <path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" /> <path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" /> <path value="$PROJECT_DIR$/vendor/symfony/cache" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-phpunit" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-symfony" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-doctrine" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan" />
<path value="$PROJECT_DIR$/vendor/jean85/pretty-package-versions" />
<path value="$PROJECT_DIR$/vendor/react/child-process" />
<path value="$PROJECT_DIR$/vendor/react/socket" />
<path value="$PROJECT_DIR$/vendor/react/dns" />
<path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
<path value="$PROJECT_DIR$/vendor/sentry/sentry" />
<path value="$PROJECT_DIR$/vendor/sentry/sentry-symfony" />
<path value="$PROJECT_DIR$/vendor/rector/rector" />
<path value="$PROJECT_DIR$/vendor/symfony/form" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
<path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
<path value="$PROJECT_DIR$/vendor/runtime/frankenphp-symfony" />
<path value="$PROJECT_DIR$/vendor/symfony/validator" /> <path value="$PROJECT_DIR$/vendor/symfony/validator" />
<path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
<path value="$PROJECT_DIR$/vendor/symfony/serializer" />
<path value="$PROJECT_DIR$/vendor/symfony/ux-turbo" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpdoc-parser" />
<path value="$PROJECT_DIR$/vendor/phpstan/extension-installer" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/asset-mapper" />
<path value="$PROJECT_DIR$/vendor/symfony/uid" />
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
<path value="$PROJECT_DIR$/vendor/symfony/brevo-mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/symfony/phpunit-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/runtime" />
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/browser-kit" /> <path value="$PROJECT_DIR$/vendor/symfony/browser-kit" />
<path value="$PROJECT_DIR$/vendor/symfony/asset" /> <path value="$PROJECT_DIR$/vendor/symfony/asset" />
<path value="$PROJECT_DIR$/vendor/symfony/cache" /> <path value="$PROJECT_DIR$/vendor/fidry/cpu-core-counter" />
<path value="$PROJECT_DIR$/vendor/symfony/config" /> <path value="$PROJECT_DIR$/vendor/symfony/ux-turbo" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" /> <path value="$PROJECT_DIR$/vendor/symfony/form" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" /> <path value="$PROJECT_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/symfony/intl" /> <path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" /> <path value="$PROJECT_DIR$/vendor/symfony/serializer" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" /> <path value="$PROJECT_DIR$/vendor/rector/rector" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" /> <path value="$PROJECT_DIR$/vendor/phpstan/phpdoc-parser" />
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" /> <path value="$PROJECT_DIR$/vendor/phpstan/extension-installer" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" /> <path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" /> <path value="$PROJECT_DIR$/vendor/symfonycasts/sass-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/property-access" /> <path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" /> <path value="$PROJECT_DIR$/vendor/symfonycasts/verify-email-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" /> <path value="$PROJECT_DIR$/vendor/psr/http-factory" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-doctrine" />
<path value="$PROJECT_DIR$/vendor/psr/clock" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-phpunit" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-symfony" />
<path value="$PROJECT_DIR$/vendor/symfony/mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/brevo-mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" /> <path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" /> <path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/symfony/mailer" /> <path value="$PROJECT_DIR$/vendor/symfony/runtime" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/symfony/phpunit-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
<path value="$PROJECT_DIR$/vendor/symfony/config" />
<path value="$PROJECT_DIR$/vendor/symfony/asset-mapper" />
<path value="$PROJECT_DIR$/vendor/symfony/uid" />
<path value="$PROJECT_DIR$/vendor/symfony/intl" />
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/masterminds/html5" />
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/property-access" />
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-uuid" /> <path value="$PROJECT_DIR$/vendor/symfony/polyfill-uuid" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" /> <path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" /> <path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" /> <path value="$PROJECT_DIR$/vendor/symfony/var-exporter" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" /> <path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-bundle" /> <path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" /> <path value="$PROJECT_DIR$/vendor/symfony/flex" />
<path value="$PROJECT_DIR$/vendor/doctrine/deprecations" />
<path value="$PROJECT_DIR$/vendor/symfony/type-info" />
<path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
<path value="$PROJECT_DIR$/vendor/symfony/property-info" /> <path value="$PROJECT_DIR$/vendor/symfony/property-info" />
<path value="$PROJECT_DIR$/vendor/doctrine/collections" /> <path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" /> <path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" /> <path value="$PROJECT_DIR$/vendor/symfony/type-info" />
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" /> <path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" /> <path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/security-core" /> <path value="$PROJECT_DIR$/vendor/symfony/security-core" />
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" /> <path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/string" /> <path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/symfony/yaml" /> <path value="$PROJECT_DIR$/vendor/symfony/yaml" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" /> <path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" /> <path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" /> <path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" /> <path value="$PROJECT_DIR$/vendor/markbaker/matrix" />
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" /> <path value="$PROJECT_DIR$/vendor/markbaker/complex" />
<path value="$PROJECT_DIR$/vendor/symfony/console" /> <path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" /> <path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/symfony/process" /> <path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/password-hasher" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/clock" />
<path value="$PROJECT_DIR$/vendor/symfony/stimulus-bundle" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/phpoffice/phpspreadsheet" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/clue/ndjson-react" />
<path value="$PROJECT_DIR$/vendor/react/socket" />
<path value="$PROJECT_DIR$/vendor/react/dns" />
<path value="$PROJECT_DIR$/vendor/react/child-process" />
<path value="$PROJECT_DIR$/vendor/react/cache" />
<path value="$PROJECT_DIR$/vendor/react/event-loop" />
<path value="$PROJECT_DIR$/vendor/react/promise" />
<path value="$PROJECT_DIR$/vendor/react/stream" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/runtime/frankenphp-symfony" />
<path value="$PROJECT_DIR$/vendor/twig/twig" />
<path value="$PROJECT_DIR$/vendor/twig/intl-extra" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/phpstan-safe-rule" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/safe" />
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" /> <path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/maennchen/zipstream-php" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" /> <path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/sebastian/type" /> <path value="$PROJECT_DIR$/vendor/sebastian/type" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" /> <path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" /> <path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" /> <path value="$PROJECT_DIR$/vendor/sentry/sentry" />
<path value="$PROJECT_DIR$/vendor/markbaker/matrix" /> <path value="$PROJECT_DIR$/vendor/sentry/sentry-symfony" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" /> <path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/markbaker/complex" /> <path value="$PROJECT_DIR$/vendor/jean85/pretty-package-versions" />
<path value="$PROJECT_DIR$/vendor/symfony/flex" /> <path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
<path value="$PROJECT_DIR$/vendor/maennchen/zipstream-php" /> <path value="$PROJECT_DIR$/vendor/doctrine/collections" />
<path value="$PROJECT_DIR$/vendor/symfony/var-exporter" /> <path value="$PROJECT_DIR$/vendor/doctrine/doctrine-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/deprecations" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
<path value="$PROJECT_DIR$/vendor/evenement/evenement" /> <path value="$PROJECT_DIR$/vendor/evenement/evenement" />
<path value="$PROJECT_DIR$/vendor/symfony/password-hasher" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/symfony/clock" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/symfony/stimulus-bundle" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/phpoffice/phpspreadsheet" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
<path value="$PROJECT_DIR$/vendor/brianium/paratest" />
<path value="$PROJECT_DIR$/vendor/dama/doctrine-test-bundle" />
<path value="$PROJECT_DIR$/vendor/stof/doctrine-extensions-bundle" /> <path value="$PROJECT_DIR$/vendor/stof/doctrine-extensions-bundle" />
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
</include_path> </include_path>
</component> </component>
<component name="PhpInterpreters"> <component name="PhpInterpreters">
@@ -293,7 +291,7 @@
</component> </component>
<component name="PhpUnit"> <component name="PhpUnit">
<phpunit_settings> <phpunit_settings>
<phpunit_by_interpreter interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" bootstrap_file_path="./tests/bootstrap.php" configuration_file_path="./phpunit.dist.xml" custom_loader_path="/app/vendor/autoload.php" paratest_path="$PROJECT_DIR$/vendor/bin/paratest_for_phpstorm" phpunit_phar_path="" use_bootstrap_file="true" use_configuration_file="true" /> <phpunit_by_interpreter interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" bootstrap_file_path="./tests/bootstrap.php" configuration_file_path="./phpunit.dist.xml" custom_loader_path="/app/vendor/autoload.php" phpunit_phar_path="" use_bootstrap_file="true" use_configuration_file="true" />
</phpunit_settings> </phpunit_settings>
</component> </component>
<component name="Psalm"> <component name="Psalm">

View File

@@ -24,7 +24,6 @@ return new Config()
'no_unreachable_default_argument_value' => true, 'no_unreachable_default_argument_value' => true,
'no_useless_else' => true, 'no_useless_else' => true,
'no_useless_return' => true, 'no_useless_return' => true,
'php_unit_strict' => true,
'phpdoc_line_span' => ['const' => 'single', 'method' => 'single', 'property' => 'single'], 'phpdoc_line_span' => ['const' => 'single', 'method' => 'single', 'property' => 'single'],
'phpdoc_order' => true, 'phpdoc_order' => true,
'single_line_empty_body' => true, 'single_line_empty_body' => true,

View File

@@ -43,5 +43,5 @@ clean:
reload-tests: reload-tests:
@docker compose exec php bin/console --env=test doctrine:database:drop --if-exists --force @docker compose exec php bin/console --env=test doctrine:database:drop --if-exists --force
@docker compose exec php bin/console --env=test doctrine:database:create @docker compose exec php bin/console --env=test doctrine:database:create
@docker compose exec php bin/console --env=test doctrine:schema:create --quiet @docker compose exec php bin/console --env=test doctrine:migrations:migrate -n
@docker compose exec php bin/console --env=test doctrine:fixtures:load --no-interaction --group=test @docker compose exec php bin/console --env=test doctrine:fixtures:load -n --group=test

View File

@@ -49,7 +49,6 @@
"twig/twig": "^3.21.1" "twig/twig": "^3.21.1"
}, },
"require-dev": { "require-dev": {
"brianium/paratest": "^7.14",
"dama/doctrine-test-bundle": "^8.4", "dama/doctrine-test-bundle": "^8.4",
"doctrine/doctrine-fixtures-bundle": "^4.3", "doctrine/doctrine-fixtures-bundle": "^4.3",
"friendsofphp/php-cs-fixer": "^3.89.0", "friendsofphp/php-cs-fixer": "^3.89.0",

95
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "944e218741f3c7a1f04072e075255c2c", "content-hash": "752576f663ccc67d22525a025afc01df",
"packages": [ "packages": [
{ {
"name": "composer/pcre", "name": "composer/pcre",
@@ -8750,99 +8750,6 @@
} }
], ],
"packages-dev": [ "packages-dev": [
{
"name": "brianium/paratest",
"version": "v7.14.2",
"source": {
"type": "git",
"url": "https://github.com/paratestphp/paratest.git",
"reference": "de06de1ae1203b11976c6ca01d6a9081c8b33d45"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paratestphp/paratest/zipball/de06de1ae1203b11976c6ca01d6a9081c8b33d45",
"reference": "de06de1ae1203b11976c6ca01d6a9081c8b33d45",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-pcre": "*",
"ext-reflection": "*",
"ext-simplexml": "*",
"fidry/cpu-core-counter": "^1.3.0",
"jean85/pretty-package-versions": "^2.1.1",
"php": "~8.3.0 || ~8.4.0 || ~8.5.0",
"phpunit/php-code-coverage": "^12.4.0",
"phpunit/php-file-iterator": "^6",
"phpunit/php-timer": "^8",
"phpunit/phpunit": "^12.4.1",
"sebastian/environment": "^8.0.3",
"symfony/console": "^6.4.20 || ^7.3.4",
"symfony/process": "^6.4.20 || ^7.3.4"
},
"require-dev": {
"doctrine/coding-standard": "^14.0.0",
"ext-pcntl": "*",
"ext-pcov": "*",
"ext-posix": "*",
"phpstan/phpstan": "^2.1.31",
"phpstan/phpstan-deprecation-rules": "^2.0.3",
"phpstan/phpstan-phpunit": "^2.0.7",
"phpstan/phpstan-strict-rules": "^2.0.7",
"symfony/filesystem": "^6.4.13 || ^7.3.2"
},
"bin": [
"bin/paratest",
"bin/paratest_for_phpstorm"
],
"type": "library",
"autoload": {
"psr-4": {
"ParaTest\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Brian Scaturro",
"email": "scaturrob@gmail.com",
"role": "Developer"
},
{
"name": "Filippo Tessarotto",
"email": "zoeslam@gmail.com",
"role": "Developer"
}
],
"description": "Parallel testing for PHP",
"homepage": "https://github.com/paratestphp/paratest",
"keywords": [
"concurrent",
"parallel",
"phpunit",
"testing"
],
"support": {
"issues": "https://github.com/paratestphp/paratest/issues",
"source": "https://github.com/paratestphp/paratest/tree/v7.14.2"
},
"funding": [
{
"url": "https://github.com/sponsors/Slamdunk",
"type": "github"
},
{
"url": "https://paypal.me/filippotessarotto",
"type": "paypal"
}
],
"time": "2025-10-24T07:20:53+00:00"
},
{ {
"name": "clue/ndjson-react", "name": "clue/ndjson-react",
"version": "v1.3.0", "version": "v1.3.0",

View File

@@ -108,6 +108,7 @@ final class QuizController extends AbstractController
if (!$answer instanceof Answer) { if (!$answer instanceof Answer) {
throw new BadRequestHttpException('Invalid Answer ID'); throw new BadRequestHttpException('Invalid Answer ID');
} }
$givenAnswer = new GivenAnswer($candidate, $answer->question->quiz, $answer); $givenAnswer = new GivenAnswer($candidate, $answer->question->quiz, $answer);
$this->entityManager->persist($givenAnswer); $this->entityManager->persist($givenAnswer);
$this->entityManager->flush(); $this->entityManager->flush();

View File

@@ -49,11 +49,14 @@ class QuizRepository extends ServiceEntityRepository
DQL) DQL)
->setParameter('quiz', $quiz) ->setParameter('quiz', $quiz)
->execute(); ->execute();
} catch (\Throwable $throwable) { }
// @codeCoverageIgnoreStart
catch (\Throwable $throwable) {
$this->logger->error($throwable->getMessage()); $this->logger->error($throwable->getMessage());
$em->rollback(); $em->rollback();
throw new ErrorClearingQuizException(previous: $throwable); throw new ErrorClearingQuizException(previous: $throwable);
} }
// @codeCoverageIgnoreEnd
$em->commit(); $em->commit();
} }
@@ -76,17 +79,17 @@ class QuizRepository extends ServiceEntityRepository
c.id, c.id,
c.name, c.name,
sum(case when a.isRightAnswer = true then 1 else 0 end) as correct, sum(case when a.isRightAnswer = true then 1 else 0 end) as correct,
qc.corrections, qd.corrections,
max(ga.created) as end_time, max(ga.created) as end_time,
qc.created as start_time, qd.created as start_time,
(sum(case when a.isRightAnswer = true then 1 else 0 end) + qc.corrections) as score (sum(case when a.isRightAnswer = true then 1 else 0 end) + qd.corrections) as score
from Tvdt\Entity\Candidate c from Tvdt\Entity\Candidate c
join c.givenAnswers ga join c.givenAnswers ga
join ga.answer a join ga.answer a
join c.quizData qc join c.quizData qd
where qc.quiz = :quiz and ga.quiz = :quiz where qd.quiz = :quiz and ga.quiz = :quiz
group by ga.quiz, c.id, qc.id group by ga.quiz, c.id, qd.id
order by score desc, max(ga.created) - qc.created asc order by score desc, max(ga.created) - qd.created asc
DQL DQL
)->setParameter('quiz', $quiz)->getResult(); )->setParameter('quiz', $quiz)->getResult();
@@ -95,7 +98,7 @@ class QuizRepository extends ServiceEntityRepository
name: $row['name'], name: $row['name'],
correct: (int) $row['correct'], correct: (int) $row['correct'],
corrections: $row['corrections'], corrections: $row['corrections'],
time: new DateTimeImmutable($row['end_time'])->diff($row['start_time']), time: $row['start_time']->diff(new DateTimeImmutable($row['end_time'])),
score: $row['score'], score: $row['score'],
), $result); ), $result);
} }

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Tvdt\Tests\Helpers;
use PHPUnit\Framework\TestCase;
use Safe\Exceptions\UrlException;
use Tvdt\Helpers\Base64;
class Base64Test extends TestCase
{
public function testBase64UrlEncode() {
$this->assertEquals('TWFyaWpu', Base64::base64UrlEncode('Marijn'));
$this->assertEquals('UGhpbGluZQ', Base64::base64UrlEncode('Philine'));
$this->assertEquals('_g', Base64::base64UrlEncode(chr(254)));
$this->assertEquals('-g', Base64::base64UrlEncode(chr(250)));
}
public function testBase64UrlDecode() {
$this->assertEquals('Marijn', Base64::base64UrlDecode('TWFyaWpu'));
$this->assertEquals('Philine', Base64::base64UrlDecode('UGhpbGluZQ'));
$this->assertEquals(chr(254), Base64::base64UrlDecode('_g'));
$this->assertEquals(chr(250), Base64::base64UrlDecode('-g'));
}
public function testBase64UrlDecodeCanHandlePadding() {
$this->assertEquals('Philine', Base64::base64UrlDecode('UGhpbGluZQ=='));
}
public function testBase64UrlDecodeThrowsExceptionOnInvalidInput() {
$this->expectException(UrlException::class);
Base64::base64UrlDecode('Philine==');
}
}

View File

@@ -7,6 +7,9 @@ namespace Tvdt\Tests\Repository;
use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\CoversClass;
use Psr\Clock\ClockInterface; use Psr\Clock\ClockInterface;
use Symfony\Component\Clock\MockClock; use Symfony\Component\Clock\MockClock;
use Tvdt\Entity\Answer;
use Tvdt\Entity\GivenAnswer;
use Tvdt\Entity\Question;
use Tvdt\Entity\Quiz; use Tvdt\Entity\Quiz;
use Tvdt\Entity\QuizCandidate; use Tvdt\Entity\QuizCandidate;
use Tvdt\Repository\GivenAnswerRepository; use Tvdt\Repository\GivenAnswerRepository;
@@ -46,20 +49,166 @@ final class QuizRepositoryTest extends DatabaseTestCase
$this->assertCount(1, $krtekSeason->quizzes); $this->assertCount(1, $krtekSeason->quizzes);
} }
public function testGetScores(): void public function testTimeForCandidate(): void
{ {
$clock = new MockClock('2025-11-01 16:00:00'); $clock = new MockClock('2025-11-01 16:00:00');
self::getContainer()->set(ClockInterface::class, $clock); self::getContainer()->set(ClockInterface::class, $clock);
$krtekSeason = $this->getSeasonByCode('krtek'); $krtekSeason = $this->getSeasonByCode('krtek');
$candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris'); $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
$quiz = $krtekSeason->activeQuiz;
$this->assertInstanceOf(Quiz::class, $quiz);
// Start Quiz // Start Quiz
$qc = new QuizCandidate($krtekSeason->activeQuiz, $candidate); $qc = new QuizCandidate($quiz, $candidate);
$this->entityManager->persist($qc); $this->entityManager->persist($qc);
$this->entityManager->flush(); $this->entityManager->flush();
dump($qc->created); for ($i = 0; $i < 15; ++$i) {
$question = $this->questionRepository->findNextQuestionForCandidate($candidate);
$this->assertInstanceOf(Question::class, $question);
$this->markTestIncomplete('TODO: Make fixtures first and write good test.'); $answer = $question->answers->first();
$this->assertInstanceOf(Answer::class, $answer);
$clock->sleep(10 + $i);
$qa = new GivenAnswer($candidate, $quiz, $answer);
$this->entityManager->persist($qa);
$this->entityManager->flush();
}
$result = $this->quizRepository->getScores($quiz);
$this->assertSame('Iris', $result[0]->name);
$this->assertSame(5, $result[0]->correct);
$this->assertEqualsWithDelta(5.0, $result[0]->score, \PHP_FLOAT_EPSILON);
$this->assertSame(4, $result[0]->time->i);
$this->assertSame(15, $result[0]->time->s);
}
public function testScoresAreCalculatedCorrectly(): void
{
$clock = new MockClock('2025-11-01 16:00:00');
self::getContainer()->set(ClockInterface::class, $clock);
$krtekSeason = $this->getSeasonByCode('krtek');
$candidate1 = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
$candidate2 = $this->getCandidateBySeasonAndName($krtekSeason, 'Philine');
$quiz = $krtekSeason->activeQuiz;
$this->assertInstanceOf(Quiz::class, $quiz);
$qc1 = new QuizCandidate($quiz, $candidate1);
$qc2 = new QuizCandidate($quiz, $candidate2);
$this->entityManager->persist($qc1);
$this->entityManager->persist($qc2);
$this->entityManager->flush();
for ($i = 0; $i < 15; ++$i) {
$question = $this->questionRepository->findNextQuestionForCandidate($candidate1);
$this->assertInstanceOf(Question::class, $question);
$answer1 = $question->answers->first();
$answer2 = $question->answers[intdiv(\count($question->answers), 2)];
$this->assertInstanceOf(Answer::class, $answer1);
$this->assertInstanceOf(Answer::class, $answer2);
$clock->sleep(10);
$qa = new GivenAnswer($candidate1, $quiz, $answer1);
$this->entityManager->persist($qa);
$qa = new GivenAnswer($candidate2, $quiz, $answer2);
$this->entityManager->persist($qa);
$this->entityManager->flush();
}
$scores = $this->quizRepository->getScores($quiz);
$this->assertCount(2, $scores);
$this->assertSame('Iris', $scores[0]->name);
$this->assertSame('Philine', $scores[1]->name);
$this->assertEqualsWithDelta(5.0, $scores[0]->score, \PHP_FLOAT_EPSILON);
$this->assertEqualsWithDelta(4.0, $scores[1]->score, \PHP_FLOAT_EPSILON);
}
public function testCorrectionsCalculatedCorrectly(): void
{
$clock = new MockClock('2025-11-01 16:00:00');
self::getContainer()->set(ClockInterface::class, $clock);
$krtekSeason = $this->getSeasonByCode('krtek');
$candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
$quiz = $krtekSeason->activeQuiz;
$this->assertInstanceOf(Quiz::class, $quiz);
$qc = new QuizCandidate($quiz, $candidate);
$this->entityManager->persist($qc);
$this->entityManager->flush();
for ($i = 0; $i < 15; ++$i) {
$question = $this->questionRepository->findNextQuestionForCandidate($candidate);
$this->assertInstanceOf(Question::class, $question);
$answer = $question->answers->first();
$this->assertInstanceOf(Answer::class, $answer);
$clock->sleep(10);
$qa = new GivenAnswer($candidate, $quiz, $answer);
$this->entityManager->persist($qa);
$this->entityManager->flush();
}
$qc->corrections = 2;
$this->entityManager->flush();
$result = $this->quizRepository->getScores($quiz);
$this->assertEqualsWithDelta(7.0, $result[0]->score, \PHP_FLOAT_EPSILON);
}
public function testCandidatesWithSameScoreAreSortedCorrectlyByTime(): void
{
$clock = new MockClock('2025-11-01 16:00:00');
self::getContainer()->set(ClockInterface::class, $clock);
$krtekSeason = $this->getSeasonByCode('krtek');
$candidate1 = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
$candidate2 = $this->getCandidateBySeasonAndName($krtekSeason, 'Philine');
$quiz = $krtekSeason->activeQuiz;
$this->assertInstanceOf(Quiz::class, $quiz);
$qc1 = new QuizCandidate($quiz, $candidate1);
$this->entityManager->persist($qc1);
$clock->sleep(10);
$qc2 = new QuizCandidate($quiz, $candidate2);
$this->entityManager->persist($qc2);
$this->entityManager->flush();
for ($i = 0; $i < 15; ++$i) {
$question = $this->questionRepository->findNextQuestionForCandidate($candidate1);
$this->assertInstanceOf(Question::class, $question);
$answer1 = $question->answers->first();
$answer2 = $question->answers->last();
$this->assertInstanceOf(Answer::class, $answer1);
$this->assertInstanceOf(Answer::class, $answer2);
$clock->sleep(10);
$qa = new GivenAnswer($candidate1, $quiz, $answer1);
$this->entityManager->persist($qa);
$qa = new GivenAnswer($candidate2, $quiz, $answer2);
$this->entityManager->persist($qa);
$this->entityManager->flush();
}
$result = $this->quizRepository->getScores($quiz);
$this->assertEqualsWithDelta(5.0, $result[0]->score, \PHP_FLOAT_EPSILON);
$this->assertEqualsWithDelta(5.0, $result[1]->score, \PHP_FLOAT_EPSILON);
$this->assertSame('Philine', $result[0]->name);
$this->assertSame('Iris', $result[1]->name);
} }
} }

View File

@@ -90,6 +90,7 @@ final class SeasonVoterTest extends TestCase
{ {
$user = new User(); $user = new User();
$user->roles = ['ROLE_ADMIN']; $user->roles = ['ROLE_ADMIN'];
$token = $this->createStub(TokenInterface::class); $token = $this->createStub(TokenInterface::class);
$token->method('getUser')->willReturn($user); $token->method('getUser')->willReturn($user);