* Update everything for TYPO3 v12 + v13

---------

Co-authored-by: Daniel Siepmann <daniel.siepmann@codappix.com>
This commit is contained in:
Daniel Siepmann 2024-10-15 14:07:38 +02:00 committed by GitHub
parent 5aa08b5e6c
commit b83093e023
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 1413 additions and 1565 deletions

View file

@ -10,12 +10,12 @@ jobs:
check-composer: check-composer:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install PHP - name: Install PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: 7.4 php-version: 8.3
coverage: none coverage: none
tools: composer:v2 tools: composer:v2
env: env:
@ -29,13 +29,12 @@ jobs:
strategy: strategy:
matrix: matrix:
php-version: php-version:
- 7.4
- 8.0
- 8.1 - 8.1
- 8.2 - 8.2
- 8.3
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Install PHP - name: Install PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@ -51,12 +50,12 @@ jobs:
needs: needs:
- check-composer - check-composer
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install PHP - name: Install PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: "7.4" php-version: "8.3"
coverage: none coverage: none
tools: composer:v2 tools: composer:v2
env: env:
@ -80,7 +79,7 @@ jobs:
coding-guideline: coding-guideline:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install PHP - name: Install PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@ -104,26 +103,23 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- db-version: '8'
php-version: '7.4'
typo3-version: '^11.5'
- db-version: '8'
php-version: '8.0'
typo3-version: '^11.5'
- db-version: '8'
php-version: '8.1'
typo3-version: '^11.5'
- db-version: '8'
php-version: '8.2'
typo3-version: '^11.5'
- db-version: '8' - db-version: '8'
php-version: '8.1' php-version: '8.1'
typo3-version: '^12.4' typo3-version: '^12.4'
- db-version: '8' - db-version: '8'
php-version: '8.2' php-version: '8.2'
typo3-version: '^12.4' typo3-version: '^12.4'
- db-version: '8'
php-version: '8.3'
typo3-version: '^12.4'
- db-version: '8'
php-version: '8.2'
typo3-version: '^13.3'
- db-version: '8'
php-version: '8.3'
typo3-version: '^13.3'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install PHP - name: Install PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@ -148,7 +144,7 @@ jobs:
done done
- name: Install dependencies with expected TYPO3 version - name: Install dependencies with expected TYPO3 version
run: composer require --prefer-dist --no-progress "typo3/cms-backend:${{ matrix.typo3-version }}" "typo3/cms-core:${{ matrix.typo3-version }}" "typo3/cms-dashboard:${{ matrix.typo3-version }}" run: composer require --prefer-dist --no-progress "typo3/cms-core:${{ matrix.typo3-version }}"
- name: PHPUnit Tests - name: PHPUnit Tests
run: |- run: |-
@ -164,20 +160,18 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- php-version: '7.4'
typo3-version: '^11.5'
- php-version: '8.0'
typo3-version: '^11.5'
- php-version: '8.1'
typo3-version: '^11.5'
- php-version: '8.2'
typo3-version: '^11.5'
- php-version: '8.1' - php-version: '8.1'
typo3-version: '^12.4' typo3-version: '^12.4'
- php-version: '8.2' - php-version: '8.2'
typo3-version: '^12.4' typo3-version: '^12.4'
- php-version: '8.3'
typo3-version: '^12.4'
- php-version: '8.2'
typo3-version: '^13.3'
- php-version: '8.3'
typo3-version: '^13.3'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install PHP - name: Install PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@ -189,7 +183,7 @@ jobs:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies with expected TYPO3 version - name: Install dependencies with expected TYPO3 version
run: composer require --prefer-dist --no-progress "typo3/cms-backend:${{ matrix.typo3-version }}" "typo3/cms-core:${{ matrix.typo3-version }}" "typo3/cms-dashboard:${{ matrix.typo3-version }}" run: composer require --prefer-dist --no-progress "typo3/cms-core:${{ matrix.typo3-version }}"
- name: Code Quality (by PHPStan) - name: Code Quality (by PHPStan)
run: ./vendor/bin/phpstan analyse run: ./vendor/bin/phpstan analyse

View file

@ -1,63 +1,365 @@
<?php <?php
$finder = (new PhpCsFixer\Finder())
declare(strict_types=1);
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Fixer\Alias\MbStrFunctionsFixer;
use PhpCsFixer\Fixer\Alias\NoAliasFunctionsFixer;
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
use PhpCsFixer\Fixer\ArrayNotation\NoMultilineWhitespaceAroundDoubleArrowFixer;
use PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceBeforeCommaInArrayFixer;
use PhpCsFixer\Fixer\ArrayNotation\NormalizeIndexBraceFixer;
use PhpCsFixer\Fixer\ArrayNotation\ReturnToYieldFromFixer;
use PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer;
use PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer;
use PhpCsFixer\Fixer\ArrayNotation\YieldFromArrayToYieldsFixer;
use PhpCsFixer\Fixer\AttributeNotation\AttributeEmptyParenthesesFixer;
use PhpCsFixer\Fixer\Basic\NoMultipleStatementsPerLineFixer;
use PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer;
use PhpCsFixer\Fixer\Basic\NonPrintableCharacterFixer;
use PhpCsFixer\Fixer\Basic\NumericLiteralSeparatorFixer;
use PhpCsFixer\Fixer\Casing\ClassReferenceNameCasingFixer;
use PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer;
use PhpCsFixer\Fixer\Casing\NativeTypeDeclarationCasingFixer;
use PhpCsFixer\Fixer\CastNotation\CastSpacesFixer;
use PhpCsFixer\Fixer\CastNotation\ModernizeTypesCastingFixer;
use PhpCsFixer\Fixer\CastNotation\NoUnsetCastFixer;
use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer;
use PhpCsFixer\Fixer\ClassNotation\NoNullPropertyInitializationFixer;
use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer;
use PhpCsFixer\Fixer\ClassNotation\OrderedInterfacesFixer;
use PhpCsFixer\Fixer\ClassNotation\OrderedTraitsFixer;
use PhpCsFixer\Fixer\ClassNotation\OrderedTypesFixer;
use PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer;
use PhpCsFixer\Fixer\Comment\MultilineCommentOpeningClosingFixer;
use PhpCsFixer\Fixer\Comment\NoEmptyCommentFixer;
use PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer;
use PhpCsFixer\Fixer\ControlStructure\NoSuperfluousElseifFixer;
use PhpCsFixer\Fixer\ControlStructure\NoUnneededBracesFixer;
use PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer;
use PhpCsFixer\Fixer\ControlStructure\NoUselessElseFixer;
use PhpCsFixer\Fixer\ControlStructure\SimplifiedIfReturnFixer;
use PhpCsFixer\Fixer\ControlStructure\TrailingCommaInMultilineFixer;
use PhpCsFixer\Fixer\FunctionNotation\DateTimeCreateFromFormatCallFixer;
use PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer;
use PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer;
use PhpCsFixer\Fixer\FunctionNotation\NoUselessSprintfFixer;
use PhpCsFixer\Fixer\FunctionNotation\NullableTypeDeclarationForDefaultNullValueFixer;
use PhpCsFixer\Fixer\FunctionNotation\PhpdocToParamTypeFixer;
use PhpCsFixer\Fixer\FunctionNotation\PhpdocToPropertyTypeFixer;
use PhpCsFixer\Fixer\FunctionNotation\PhpdocToReturnTypeFixer;
use PhpCsFixer\Fixer\FunctionNotation\RegularCallableCallFixer;
use PhpCsFixer\Fixer\FunctionNotation\StaticLambdaFixer;
use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer;
use PhpCsFixer\Fixer\Import\GlobalNamespaceImportFixer;
use PhpCsFixer\Fixer\Import\NoUnneededImportAliasFixer;
use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer;
use PhpCsFixer\Fixer\Import\OrderedImportsFixer;
use PhpCsFixer\Fixer\LanguageConstruct\ClassKeywordFixer;
use PhpCsFixer\Fixer\LanguageConstruct\CombineConsecutiveIssetsFixer;
use PhpCsFixer\Fixer\LanguageConstruct\CombineConsecutiveUnsetsFixer;
use PhpCsFixer\Fixer\LanguageConstruct\NullableTypeDeclarationFixer;
use PhpCsFixer\Fixer\LanguageConstruct\SingleSpaceAroundConstructFixer;
use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer;
use PhpCsFixer\Fixer\NamespaceNotation\BlankLinesBeforeNamespaceFixer;
use PhpCsFixer\Fixer\Naming\NoHomoglyphNamesFixer;
use PhpCsFixer\Fixer\Operator\ConcatSpaceFixer;
use PhpCsFixer\Fixer\Operator\IncrementStyleFixer;
use PhpCsFixer\Fixer\Operator\LongToShorthandOperatorFixer;
use PhpCsFixer\Fixer\Operator\NewWithParenthesesFixer;
use PhpCsFixer\Fixer\Operator\NoUselessConcatOperatorFixer;
use PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer;
use PhpCsFixer\Fixer\Operator\OperatorLinebreakFixer;
use PhpCsFixer\Fixer\Operator\StandardizeIncrementFixer;
use PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer;
use PhpCsFixer\Fixer\Operator\TernaryToElvisOperatorFixer;
use PhpCsFixer\Fixer\Operator\TernaryToNullCoalescingFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitConstructFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitDataProviderReturnTypeFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitDataProviderStaticFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertInternalTypeFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitFqcnAnnotationFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitMethodCasingFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitMockFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitMockShortWillReturnFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitNamespacedFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitNoExpectationAnnotationFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitSetUpTearDownVisibilityFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestAnnotationFixer;
use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestCaseStaticMethodCallsFixer;
use PhpCsFixer\Fixer\Phpdoc\NoBlankLinesAfterPhpdocFixer;
use PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer;
use PhpCsFixer\Fixer\Phpdoc\NoSuperfluousPhpdocTagsFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocAlignFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocLineSpanFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocNoAccessFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocOrderByValueFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocOrderFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocParamOrderFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocScalarFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocSeparationFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocToCommentFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocTrimConsecutiveBlankLineSeparationFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesOrderFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocVarAnnotationCorrectOrderFixer;
use PhpCsFixer\Fixer\Phpdoc\PhpdocVarWithoutNameFixer;
use PhpCsFixer\Fixer\ReturnNotation\NoUselessReturnFixer;
use PhpCsFixer\Fixer\Semicolon\MultilineWhitespaceBeforeSemicolonsFixer;
use PhpCsFixer\Fixer\Semicolon\NoEmptyStatementFixer;
use PhpCsFixer\Fixer\Semicolon\NoSinglelineWhitespaceBeforeSemicolonsFixer;
use PhpCsFixer\Fixer\Semicolon\SemicolonAfterInstructionFixer;
use PhpCsFixer\Fixer\Strict\DeclareStrictTypesFixer;
use PhpCsFixer\Fixer\StringNotation\NoTrailingWhitespaceInStringFixer;
use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer;
use PhpCsFixer\Fixer\StringNotation\StringImplicitBackslashesFixer;
use PhpCsFixer\Fixer\StringNotation\StringLengthToEmptyFixer;
use PhpCsFixer\Fixer\Whitespace\ArrayIndentationFixer;
use PhpCsFixer\Fixer\Whitespace\CompactNullableTypeDeclarationFixer;
use PhpCsFixer\Fixer\Whitespace\MethodChainingIndentationFixer;
use PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer;
use PhpCsFixer\Fixer\Whitespace\NoSpacesAroundOffsetFixer;
use PhpCsFixer\Fixer\Whitespace\StatementIndentationFixer;
use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer;
use PhpCsFixer\Fixer\Whitespace\TypesSpacesFixer;
use PhpCsFixer\Preg;
/**
* Transforms a given class to php-cs-fixer rule name.
* That way we can use auto completion, phpstan, etc.
*
* @param class-string $className
*/
function transform(string $className): string
{
$nameParts = explode('\\', $className);
$name = mb_substr(end($nameParts), 0, -mb_strlen('Fixer'));
return mb_strtolower(Preg::replace(
'/(?<!^)((?=[\p{Lu}][^\p{Lu}])|(?<![\p{Lu}])(?=[\p{Lu}]))/',
'_',
$name
));
}
return (new Config())
->setRiskyAllowed(true)
->setFinder(
(new Finder())
->ignoreVCSIgnored(true) ->ignoreVCSIgnored(true)
->in(realpath(__DIR__)) ->in(realpath(__DIR__))
; )
return (new \PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([ ->setRules([
'@DoctrineAnnotation' => true, '@PSR12' => true,
'@PSR2' => true, transform(ArrayIndentationFixer::class) => true,
'array_syntax' => ['syntax' => 'short'], transform(ArraySyntaxFixer::class) => [
'blank_line_after_opening_tag' => true, 'syntax' => 'short',
'braces' => ['allow_single_line_closure' => true], ],
'cast_spaces' => ['space' => 'none'], transform(AttributeEmptyParenthesesFixer::class) => true,
'compact_nullable_typehint' => true, transform(BlankLinesBeforeNamespaceFixer::class) => true,
'concat_space' => ['spacing' => 'one'], transform(CastSpacesFixer::class) => true,
'declare_equal_normalize' => ['space' => 'none'], transform(ClassAttributesSeparationFixer::class) => [
'dir_constant' => true, 'elements' => [
'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']], 'const' => 'one',
'function_typehint_space' => true, 'method' => 'one',
'lowercase_cast' => true, 'property' => 'one',
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], 'trait_import' => 'one',
'modernize_strpos' => true, ],
'modernize_types_casting' => true, ],
'native_function_casing' => true, transform(ClassKeywordFixer::class) => true,
'new_with_braces' => true, transform(ClassReferenceNameCasingFixer::class) => true,
'no_alias_functions' => true, transform(CombineConsecutiveIssetsFixer::class) => true,
'no_blank_lines_after_phpdoc' => true, transform(CombineConsecutiveUnsetsFixer::class) => true,
'no_empty_phpdoc' => true, transform(CompactNullableTypeDeclarationFixer::class) => true,
'no_empty_statement' => true, transform(ConcatSpaceFixer::class) => [
'no_extra_blank_lines' => true, 'spacing' => 'one',
'no_leading_import_slash' => true, ],
'no_leading_namespace_whitespace' => true, transform(DateTimeCreateFromFormatCallFixer::class) => true,
'no_null_property_initialization' => true, transform(DeclareStrictTypesFixer::class) => true,
'no_short_bool_cast' => true, transform(FullyQualifiedStrictTypesFixer::class) => [
'no_singleline_whitespace_before_semicolons' => true, 'import_symbols' => true,
'no_superfluous_elseif' => true, 'leading_backslash_in_global_namespace' => true,
'no_trailing_comma_in_singleline_array' => true, ],
'no_unneeded_control_parentheses' => true, transform(GlobalNamespaceImportFixer::class) => true,
'no_unused_imports' => true, transform(IncrementStyleFixer::class) => [
'no_useless_else' => true, 'style' => 'post',
'no_whitespace_in_blank_line' => true, ],
'ordered_imports' => true, transform(ListSyntaxFixer::class) => true,
'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], transform(LongToShorthandOperatorFixer::class) => true,
'php_unit_mock_short_will_return' => true, transform(MbStrFunctionsFixer::class) => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], transform(MethodArgumentSpaceFixer::class) => [
'phpdoc_no_access' => true, 'on_multiline' => 'ensure_fully_multiline',
'phpdoc_no_empty_return' => true, 'attribute_placement' => 'standalone',
'phpdoc_no_package' => true, ],
'phpdoc_scalar' => true, transform(MethodChainingIndentationFixer::class) => true,
'phpdoc_trim' => true, transform(ModernizeTypesCastingFixer::class) => true,
'phpdoc_types' => true, transform(MultilineCommentOpeningClosingFixer::class) => true,
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], transform(MultilineWhitespaceBeforeSemicolonsFixer::class) => [
'return_type_declaration' => ['space_before' => 'none'], 'strategy' => 'new_line_for_chained_calls',
'single_quote' => true, ],
'single_line_comment_style' => ['comment_types' => ['hash']], transform(NativeFunctionCasingFixer::class) => true,
'single_trait_insert_per_statement' => true, transform(NativeTypeDeclarationCasingFixer::class) => true,
'trailing_comma_in_multiline' => ['elements' => ['arrays']], transform(NewWithParenthesesFixer::class) => [
'whitespace_after_comma_in_array' => true, 'anonymous_class' => false,
'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false], 'named_class' => true,
],
transform(NoAliasFunctionsFixer::class) => true,
transform(NoBlankLinesAfterPhpdocFixer::class) => true,
transform(NoEmptyCommentFixer::class) => true,
transform(NoEmptyPhpdocFixer::class) => true,
transform(NoEmptyStatementFixer::class) => true,
transform(NoExtraBlankLinesFixer::class) => true,
transform(NoHomoglyphNamesFixer::class) => true,
transform(NoMultilineWhitespaceAroundDoubleArrowFixer::class) => true,
transform(NoMultipleStatementsPerLineFixer::class) => true,
transform(NoNullPropertyInitializationFixer::class) => true,
transform(NoSinglelineWhitespaceBeforeSemicolonsFixer::class) => true,
transform(NoSpacesAroundOffsetFixer::class) => true,
transform(NoSuperfluousElseifFixer::class) => true,
transform(NoSuperfluousPhpdocTagsFixer::class) => [
'allow_mixed' => true,
],
transform(NoTrailingCommaInSinglelineFixer::class) => true,
transform(NoTrailingWhitespaceInStringFixer::class) => true,
transform(NoUnneededBracesFixer::class) => true,
transform(NoUnneededControlParenthesesFixer::class) => true,
transform(NoUnneededImportAliasFixer::class) => true,
transform(NoUnreachableDefaultArgumentValueFixer::class) => true,
transform(NoUnsetCastFixer::class) => true,
transform(NoUnusedImportsFixer::class) => true,
transform(NoUselessConcatOperatorFixer::class) => true,
transform(NoUselessElseFixer::class) => true,
transform(NoUselessReturnFixer::class) => true,
transform(NoUselessSprintfFixer::class) => true,
transform(NoWhitespaceBeforeCommaInArrayFixer::class) => true,
transform(NonPrintableCharacterFixer::class) => true,
transform(NormalizeIndexBraceFixer::class) => true,
transform(NullableTypeDeclarationFixer::class) => true,
transform(NullableTypeDeclarationForDefaultNullValueFixer::class) => true,
transform(NumericLiteralSeparatorFixer::class) => [
'strategy' => NumericLiteralSeparatorFixer::STRATEGY_NO_SEPARATOR,
],
transform(ObjectOperatorWithoutWhitespaceFixer::class) => true,
transform(OperatorLinebreakFixer::class) => [
'position' => 'beginning', ],
transform(OrderedClassElementsFixer::class) => [
'order' => [
'use_trait',
'case',
'constant_public',
'constant_protected',
'constant_private',
'property_public',
'property_protected',
'property_private',
'construct',
'destruct',
'phpunit',
'method_public',
'method_protected',
'method_private',
'magic',
],
'case_sensitive' => true,
],
transform(OrderedImportsFixer::class) => [
'sort_algorithm' => 'alpha',
'case_sensitive' => true,
],
transform(OrderedInterfacesFixer::class) => [
'case_sensitive' => true,
],
transform(OrderedTraitsFixer::class) => [
'case_sensitive' => true,
],
transform(OrderedTypesFixer::class) => [
'case_sensitive' => true,
],
transform(PhpUnitConstructFixer::class) => true,
transform(PhpUnitDataProviderReturnTypeFixer::class) => true,
transform(PhpUnitDataProviderStaticFixer::class) => [
'force' => true,
],
transform(PhpUnitDedicateAssertFixer::class) => true,
transform(PhpUnitDedicateAssertInternalTypeFixer::class) => true,
transform(PhpUnitFqcnAnnotationFixer::class) => true,
transform(PhpUnitMethodCasingFixer::class) => true,
transform(PhpUnitMockFixer::class) => true,
transform(PhpUnitMockShortWillReturnFixer::class) => true,
transform(PhpUnitNamespacedFixer::class) => true,
transform(PhpUnitNoExpectationAnnotationFixer::class) => true,
transform(PhpUnitSetUpTearDownVisibilityFixer::class) => true,
transform(PhpUnitStrictFixer::class) => true,
transform(PhpUnitTestAnnotationFixer::class) => [
'style' => 'annotation',
],
transform(PhpUnitTestCaseStaticMethodCallsFixer::class) => [
'call_type' => 'self',
],
transform(PhpdocAlignFixer::class) => [
'align' => 'left',
],
transform(PhpdocIndentFixer::class) => true,
transform(PhpdocLineSpanFixer::class) => true,
transform(PhpdocNoAccessFixer::class) => true,
transform(PhpdocOrderByValueFixer::class) => [
'annotations' => [
'covers', 'throws',
],
],
transform(PhpdocOrderFixer::class) => true,
transform(PhpdocParamOrderFixer::class) => true,
transform(PhpdocScalarFixer::class) => true,
transform(PhpdocSeparationFixer::class) => [
'groups' => [
['see'],
['throw'],
['param'],
['return'],
],
],
transform(PhpdocToCommentFixer::class) => true,
transform(PhpdocToParamTypeFixer::class) => true,
transform(PhpdocToPropertyTypeFixer::class) => true,
transform(PhpdocToReturnTypeFixer::class) => true,
transform(PhpdocTrimConsecutiveBlankLineSeparationFixer::class) => true,
transform(PhpdocTrimFixer::class) => true,
transform(PhpdocTypesFixer::class) => true,
transform(PhpdocTypesOrderFixer::class) => [
'case_sensitive' => true,
],
transform(PhpdocVarAnnotationCorrectOrderFixer::class) => true,
transform(PhpdocVarWithoutNameFixer::class) => true,
transform(RegularCallableCallFixer::class) => true,
transform(ReturnToYieldFromFixer::class) => true,
transform(SelfAccessorFixer::class) => true,
transform(SemicolonAfterInstructionFixer::class) => true,
transform(SimplifiedIfReturnFixer::class) => true,
transform(SingleLineCommentStyleFixer::class) => true,
transform(SingleQuoteFixer::class) => true,
transform(SingleSpaceAroundConstructFixer::class) => true,
transform(StandardizeIncrementFixer::class) => true,
transform(StatementIndentationFixer::class) => true,
transform(StaticLambdaFixer::class) => true,
transform(StringImplicitBackslashesFixer::class) => [
'single_quoted' => 'ignore',
],
transform(StringLengthToEmptyFixer::class) => true,
transform(TernaryOperatorSpacesFixer::class) => true,
transform(TernaryToElvisOperatorFixer::class) => true,
transform(TernaryToNullCoalescingFixer::class) => true,
transform(TrailingCommaInMultilineFixer::class) => true,
transform(TrimArraySpacesFixer::class) => true,
transform(TypeDeclarationSpacesFixer::class) => true,
transform(TypesSpacesFixer::class) => true,
transform(WhitespaceAfterCommaInArrayFixer::class) => [
'ensure_single_space' => true,
],
transform(YieldFromArrayToYieldsFixer::class) => true,
]) ])
->setFinder($finder); ;

View file

@ -31,15 +31,9 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class UpdateDataCommand extends Command class UpdateDataCommand extends Command
{ {
/** public function __construct(
* @var Pageview private readonly Pageview $repository
*/ ) {
private $repository;
public function __construct(Pageview $repository)
{
$this->repository = $repository;
parent::__construct(); parent::__construct();
} }

View file

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace DanielSiepmann\Tracking\Dashboard\Provider; namespace DanielSiepmann\Tracking\Dashboard\Provider;
use Exception;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Dashboard\Widgets\ListDataProviderInterface; use TYPO3\CMS\Dashboard\Widgets\ListDataProviderInterface;
@ -30,35 +31,14 @@ use TYPO3\CMS\Dashboard\Widgets\ListDataProviderInterface;
class NewestPageviews implements ListDataProviderInterface class NewestPageviews implements ListDataProviderInterface
{ {
/** /**
* @var QueryBuilder * @param int[] $languageLimitation
*/ */
private $queryBuilder;
/**
* @var int
*/
private $maxResults;
/**
* @var array
*/
private $pagesToExclude;
/**
* @var array<int>
*/
private $languageLimitation;
public function __construct( public function __construct(
QueryBuilder $queryBuilder, private readonly QueryBuilder $queryBuilder,
int $maxResults = 6, private readonly int $maxResults = 6,
array $pagesToExclude = [], private readonly array $pagesToExclude = [],
array $languageLimitation = [] private readonly array $languageLimitation = []
) { ) {
$this->queryBuilder = $queryBuilder;
$this->maxResults = $maxResults;
$this->pagesToExclude = $pagesToExclude;
$this->languageLimitation = $languageLimitation;
} }
public function getItems(): array public function getItems(): array
@ -98,10 +78,13 @@ class NewestPageviews implements ListDataProviderInterface
$this->queryBuilder->where(...$constraints); $this->queryBuilder->where(...$constraints);
} }
$items = $this->queryBuilder->execute()->fetchAll(); $items = $this->queryBuilder->executeQuery()->fetchAllAssociative();
foreach ($items as $item) { foreach ($items as $item) {
if (is_array($item) === false) { if (is_string($item['url']) === false) {
continue; throw new Exception('url of item was not string: ' . var_export($item['url'], true), 1707327319);
}
if (is_string($item['user_agent']) === false) {
throw new Exception('user_agent of item was not string: ' . var_export($item['user_agent'], true), 1707327344);
} }
$preparedItems[] = sprintf( $preparedItems[] = sprintf(

View file

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace DanielSiepmann\Tracking\Dashboard\Provider; namespace DanielSiepmann\Tracking\Dashboard\Provider;
use DanielSiepmann\Tracking\Extension; use DanielSiepmann\Tracking\Extension;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Localization\LanguageService;
@ -32,49 +33,20 @@ use TYPO3\CMS\Dashboard\Widgets\ChartDataProviderInterface;
class PageviewsPerDay implements ChartDataProviderInterface class PageviewsPerDay implements ChartDataProviderInterface
{ {
/** private LanguageService $languageService;
* @var LanguageService
*/
private $languageService;
/** /**
* @var QueryBuilder * @param int[] $pagesToExclude
* @param int[] $languageLimitation
*/ */
private $queryBuilder;
/**
* @var int
*/
private $days;
/**
* @var array<int>
*/
private $pagesToExclude;
/**
* @var string
*/
private $dateFormat;
/**
* @var array<int>
*/
private $languageLimitation;
public function __construct( public function __construct(
QueryBuilder $queryBuilder, private readonly QueryBuilder $queryBuilder,
int $days = 31, private readonly int $days = 31,
array $pagesToExclude = [], private readonly array $pagesToExclude = [],
array $languageLimitation = [], private readonly array $languageLimitation = [],
string $dateFormat = 'Y-m-d' private readonly string $dateFormat = 'Y-m-d'
) { ) {
$this->languageService = $GLOBALS['LANG']; $this->languageService = $GLOBALS['LANG'];
$this->queryBuilder = $queryBuilder;
$this->days = $days;
$this->pagesToExclude = $pagesToExclude;
$this->languageLimitation = $languageLimitation;
$this->dateFormat = $dateFormat;
} }
public function getChartData(): array public function getChartData(): array
@ -102,16 +74,16 @@ class PageviewsPerDay implements ChartDataProviderInterface
$data = []; $data = [];
for ($daysBefore = $this->days; $daysBefore >= 0; $daysBefore--) { for ($daysBefore = $this->days; $daysBefore >= 0; $daysBefore--) {
$label = date($this->dateFormat, (int)strtotime('-' . $daysBefore . ' day')); $label = date($this->dateFormat, (int) strtotime('-' . $daysBefore . ' day'));
$labels[$label] = $label; $labels[$label] = $label;
$data[$label] = 0; $data[$label] = 0;
} }
$start = (int)strtotime('-' . $this->days . ' day 0:00:00'); $start = (int) strtotime('-' . $this->days . ' day 0:00:00');
$end = (int)strtotime('tomorrow midnight'); $end = (int) strtotime('tomorrow midnight');
foreach ($this->getPageviewsInPeriod($start, $end) as $day) { foreach ($this->getPageviewsInPeriod($start, $end) as $day) {
$data[$day['label']] = (int)$day['count']; $data[$day['label']] = (int) $day['count'];
} }
return [ return [
@ -154,13 +126,15 @@ class PageviewsPerDay implements ChartDataProviderInterface
->groupBy('label') ->groupBy('label')
->orderBy('label', 'ASC') ->orderBy('label', 'ASC')
; ;
if (
if ($this->queryBuilder->getConnection()->getDatabasePlatform()->getName() === 'sqlite') { (class_exists(SqlitePlatform::class) && $this->queryBuilder->getConnection()->getDatabasePlatform() instanceof SqlitePlatform)
|| (method_exists($this->queryBuilder->getConnection()->getDatabasePlatform(), 'getName') && $this->queryBuilder->getConnection()->getDatabasePlatform()->getName() === 'sqlite')
) {
$this->queryBuilder->addSelectLiteral('date(crdate, "unixepoch") as "label"'); $this->queryBuilder->addSelectLiteral('date(crdate, "unixepoch") as "label"');
} else { } else {
$this->queryBuilder->addSelectLiteral('FROM_UNIXTIME(crdate, "%Y-%m-%d") as "label"'); $this->queryBuilder->addSelectLiteral('FROM_UNIXTIME(crdate, "%Y-%m-%d") as "label"');
} }
return $this->queryBuilder->execute()->fetchAll(); return $this->queryBuilder->executeQuery()->fetchAllAssociative();
} }
} }

View file

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace DanielSiepmann\Tracking\Dashboard\Provider; namespace DanielSiepmann\Tracking\Dashboard\Provider;
use Exception;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Dashboard\WidgetApi; use TYPO3\CMS\Dashboard\WidgetApi;
@ -31,35 +32,14 @@ use TYPO3\CMS\Dashboard\Widgets\ChartDataProviderInterface;
class PageviewsPerOperatingSystem implements ChartDataProviderInterface class PageviewsPerOperatingSystem implements ChartDataProviderInterface
{ {
/** /**
* @var QueryBuilder * @param int[] $languageLimitation
*/ */
private $queryBuilder;
/**
* @var int
*/
private $days;
/**
* @var int
*/
private $maxResults;
/**
* @var array<int>
*/
private $languageLimitation;
public function __construct( public function __construct(
QueryBuilder $queryBuilder, private readonly QueryBuilder $queryBuilder,
int $days = 31, private readonly int $days = 31,
int $maxResults = 6, private readonly int $maxResults = 6,
array $languageLimitation = [] private readonly array $languageLimitation = []
) { ) {
$this->queryBuilder = $queryBuilder;
$this->days = $days;
$this->maxResults = $maxResults;
$this->languageLimitation = $languageLimitation;
} }
public function getChartData(): array public function getChartData(): array
@ -112,13 +92,13 @@ class PageviewsPerOperatingSystem implements ChartDataProviderInterface
->orderBy('total', 'desc') ->orderBy('total', 'desc')
->addOrderBy('operating_system', 'asc') ->addOrderBy('operating_system', 'asc')
->setMaxResults($this->maxResults) ->setMaxResults($this->maxResults)
->execute() ->executeQuery()
->fetchAll() ->fetchAllAssociative()
; ;
foreach ($result as $row) { foreach ($result as $row) {
if (is_array($row) === false) { if (is_string($row['operating_system']) === false) {
continue; throw new Exception('operating_system of row was not string: ' . var_export($row['operating_system'], true), 1707326866);
} }
$labels[] = mb_strimwidth($row['operating_system'], 0, 50, '…'); $labels[] = mb_strimwidth($row['operating_system'], 0, 50, '…');

View file

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace DanielSiepmann\Tracking\Dashboard\Provider; namespace DanielSiepmann\Tracking\Dashboard\Provider;
use Exception;
use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
@ -33,49 +34,17 @@ use TYPO3\CMS\Dashboard\Widgets\ChartDataProviderInterface;
class PageviewsPerPage implements ChartDataProviderInterface class PageviewsPerPage implements ChartDataProviderInterface
{ {
/** /**
* @var QueryBuilder * @param int[] $pagesToExclude
* @param int[] $languageLimitation
*/ */
private $queryBuilder;
/**
* @var PageRepository
*/
private $pageRepository;
/**
* @var int
*/
private $days;
/**
* @var int
*/
private $maxResults;
/**
* @var array<int>
*/
private $pagesToExclude;
/**
* @var array<int>
*/
private $languageLimitation;
public function __construct( public function __construct(
QueryBuilder $queryBuilder, private readonly QueryBuilder $queryBuilder,
PageRepository $pageRepository, private readonly PageRepository $pageRepository,
int $days = 31, private readonly int $days = 31,
int $maxResults = 6, private readonly int $maxResults = 6,
array $pagesToExclude = [], private readonly array $pagesToExclude = [],
array $languageLimitation = [] private readonly array $languageLimitation = []
) { ) {
$this->queryBuilder = $queryBuilder;
$this->pageRepository = $pageRepository;
$this->days = $days;
$this->maxResults = $maxResults;
$this->pagesToExclude = $pagesToExclude;
$this->languageLimitation = $languageLimitation;
} }
public function getChartData(): array public function getChartData(): array
@ -136,16 +105,16 @@ class PageviewsPerPage implements ChartDataProviderInterface
->orderBy('total', 'desc') ->orderBy('total', 'desc')
->addOrderBy('latest', 'desc') ->addOrderBy('latest', 'desc')
->setMaxResults($this->maxResults) ->setMaxResults($this->maxResults)
->execute() ->executeQuery()
->fetchAll() ->fetchAllAssociative()
; ;
foreach ($result as $row) { foreach ($result as $row) {
if (is_array($row) === false) { if (is_numeric($row['pid']) === false) {
continue; throw new Exception('PID of row was not numeric: ' . var_export($row['pid'], true), 1707326783);
} }
$labels[] = $this->getRecordTitle((int)$row['pid']); $labels[] = $this->getRecordTitle((int) $row['pid']);
$data[] = $row['total']; $data[] = $row['total'];
} }
@ -159,13 +128,16 @@ class PageviewsPerPage implements ChartDataProviderInterface
{ {
$record = BackendUtility::getRecord('pages', $uid); $record = BackendUtility::getRecord('pages', $uid);
if (count($this->languageLimitation) === 1 && $record !== null) { if (count($this->languageLimitation) === 1 && $record !== null) {
$record = $this->pageRepository->getRecordOverlay('pages', $record, $this->languageLimitation[0]); $record = $this->pageRepository->getPageOverlay(
$record,
$this->languageLimitation[0]
);
} }
if (is_array($record) === false) { if (is_array($record) === false) {
return 'Unkown'; return 'Unkown';
} }
return strip_tags(BackendUtility::getRecordTitle('pages', $record, true)); return strip_tags((string) BackendUtility::getRecordTitle('pages', $record, true));
} }
} }

View file

@ -23,9 +23,10 @@ declare(strict_types=1);
namespace DanielSiepmann\Tracking\Dashboard\Provider; namespace DanielSiepmann\Tracking\Dashboard\Provider;
use DanielSiepmann\Tracking\LanguageAspectFactory;
use Exception;
use Generator; use Generator;
use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Context\LanguageAspect;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Domain\Repository\PageRepository;
@ -35,63 +36,20 @@ use TYPO3\CMS\Dashboard\Widgets\ChartDataProviderInterface;
class Recordviews implements ChartDataProviderInterface class Recordviews implements ChartDataProviderInterface
{ {
/** /**
* @var PageRepository * @param int[] $pagesToExclude
* @param int[] $languageLimitation
*/ */
private $pageRepository;
/**
* @var QueryBuilder
*/
private $queryBuilder;
/**
* @var int
*/
private $days;
/**
* @var int
*/
private $maxResults;
/**
* @var array<int>
*/
private $pagesToExclude;
/**
* @var array<int>
*/
private $languageLimitation;
/**
* @var array
*/
private $recordTableLimitation;
/**
* @var array
*/
private $recordTypeLimitation;
public function __construct( public function __construct(
PageRepository $pageRepository, private readonly PageRepository $pageRepository,
QueryBuilder $queryBuilder, private readonly QueryBuilder $queryBuilder,
int $days = 31, private readonly LanguageAspectFactory $languageAspectFactory,
int $maxResults = 6, private readonly int $days = 31,
array $pagesToExclude = [], private readonly int $maxResults = 6,
array $languageLimitation = [], private readonly array $pagesToExclude = [],
array $recordTableLimitation = [], private readonly array $languageLimitation = [],
array $recordTypeLimitation = [] private readonly array $recordTableLimitation = [],
private readonly array $recordTypeLimitation = []
) { ) {
$this->pageRepository = $pageRepository;
$this->queryBuilder = $queryBuilder;
$this->days = $days;
$this->pagesToExclude = $pagesToExclude;
$this->languageLimitation = $languageLimitation;
$this->maxResults = $maxResults;
$this->recordTableLimitation = $recordTableLimitation;
$this->recordTypeLimitation = $recordTypeLimitation;
} }
public function getChartData(): array public function getChartData(): array
@ -118,8 +76,13 @@ class Recordviews implements ChartDataProviderInterface
if (is_numeric($recordview['record_uid']) === false) { if (is_numeric($recordview['record_uid']) === false) {
continue; continue;
} }
if (is_string($recordview['record_table_name']) === false) {
throw new Exception('record_table_name of recordview was not string: ' . var_export($recordview['record_table_name'], true), 1707327404);
}
$record = $this->getRecord( $record = $this->getRecord(
(int)$recordview['record_uid'], (int) $recordview['record_uid'],
$recordview['record_table_name'] $recordview['record_table_name']
); );
@ -133,7 +96,7 @@ class Recordviews implements ChartDataProviderInterface
continue; continue;
} }
$labels[] = mb_strimwidth($record['title'], 0, 25, '…'); $labels[] = mb_strimwidth((string) $record['title'], 0, 25, '…');
$data[] = $recordview['total']; $data[] = $recordview['total'];
} }
@ -143,6 +106,9 @@ class Recordviews implements ChartDataProviderInterface
]; ];
} }
/**
* @return Generator<array>
*/
private function getRecordviewsRecords(): Generator private function getRecordviewsRecords(): Generator
{ {
$constraints = [ $constraints = [
@ -194,10 +160,10 @@ class Recordviews implements ChartDataProviderInterface
->orderBy('total', 'desc') ->orderBy('total', 'desc')
->addOrderBy('latest', 'desc') ->addOrderBy('latest', 'desc')
->setMaxResults($this->maxResults) ->setMaxResults($this->maxResults)
->execute() ->executeQuery()
; ;
while ($row = $result->fetch()) { while ($row = $result->fetchAssociative()) {
yield $row; yield $row;
} }
} }
@ -210,10 +176,10 @@ class Recordviews implements ChartDataProviderInterface
$record = BackendUtility::getRecord($table, $uid); $record = BackendUtility::getRecord($table, $uid);
if (count($this->languageLimitation) === 1 && $record !== null) { if (count($this->languageLimitation) === 1 && $record !== null) {
$record = $this->pageRepository->getRecordOverlay( $record = $this->pageRepository->getLanguageOverlay(
$table, $table,
$record, $record,
$this->createLanguageAspect($this->languageLimitation[0]) $this->languageAspectFactory->createFromLanguageUid($this->languageLimitation[0])
); );
} }
@ -222,17 +188,8 @@ class Recordviews implements ChartDataProviderInterface
} }
return [ return [
'title' => strip_tags(BackendUtility::getRecordTitle($table, $record, true)), 'title' => strip_tags((string) BackendUtility::getRecordTitle($table, $record, true)),
'type' => $record[$recordTypeField] ?? '', 'type' => $record[$recordTypeField] ?? '',
]; ];
} }
private function createLanguageAspect(int $languageUid): LanguageAspect
{
return new LanguageAspect(
$languageUid,
null,
LanguageAspect::OVERLAYS_MIXED
);
}
} }

View file

@ -61,7 +61,7 @@ class SymfonyExpressionLanguage implements Factory
} }
try { try {
return ArrayUtility::getValueByPath($array, $path); return ArrayUtility::getValueByPath($array, $path);
} catch (MissingArrayPathException $e) { } catch (MissingArrayPathException) {
return ''; return '';
} }
} }

View file

@ -25,8 +25,5 @@ namespace DanielSiepmann\Tracking\Domain\Model;
interface Expression interface Expression
{ {
/** public function evaluate(): mixed;
* @return mixed
*/
public function evaluate();
} }

View file

@ -28,57 +28,15 @@ use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
class Pageview implements HasUserAgent class Pageview implements HasUserAgent
{ {
/**
* @var int
*/
private $uid = 0;
/**
* @var int
*/
private $pageUid;
/**
* @var SiteLanguage
*/
private $language;
/**
* @var DateTimeImmutable
*/
private $crdate;
/**
* @var int
*/
private $pageType;
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $userAgent;
public function __construct( public function __construct(
int $pageUid, private readonly int $pageUid,
SiteLanguage $language, private readonly SiteLanguage $language,
DateTimeImmutable $crdate, private readonly DateTimeImmutable $crdate,
int $pageType, private readonly int $pageType,
string $url, private readonly string $url,
string $userAgent, private readonly string $userAgent,
int $uid = 0 private readonly int $uid = 0
) { ) {
$this->uid = $uid;
$this->pageUid = $pageUid;
$this->language = $language;
$this->crdate = $crdate;
$this->pageType = $pageType;
$this->url = $url;
$this->userAgent = $userAgent;
} }
public function getUid(): int public function getUid(): int

View file

@ -25,29 +25,11 @@ namespace DanielSiepmann\Tracking\Domain\Model;
class RecordRule class RecordRule
{ {
/**
* @var string
*/
private $matches;
/**
* @var string
*/
private $recordUid;
/**
* @var string
*/
private $tableName;
public function __construct( public function __construct(
string $matches, private readonly string $matches,
string $recordUid, private readonly string $recordUid,
string $tableName private readonly string $tableName
) { ) {
$this->matches = $matches;
$this->recordUid = $recordUid;
$this->tableName = $tableName;
} }
public static function fromArray(array $config): self public static function fromArray(array $config): self

View file

@ -28,57 +28,15 @@ use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
class Recordview implements HasUserAgent class Recordview implements HasUserAgent
{ {
/**
* @var int
*/
private $pageUid;
/**
* @var SiteLanguage
*/
private $language;
/**
* @var DateTimeImmutable
*/
private $crdate;
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $userAgent;
/**
* @var int
*/
private $recordUid;
/**
* @var string
*/
private $tableName;
public function __construct( public function __construct(
int $pageUid, private readonly int $pageUid,
SiteLanguage $language, private readonly SiteLanguage $language,
DateTimeImmutable $crdate, private readonly DateTimeImmutable $crdate,
string $url, private readonly string $url,
string $userAgent, private readonly string $userAgent,
int $recordUid, private readonly int $recordUid,
string $tableName private readonly string $tableName
) { ) {
$this->pageUid = $pageUid;
$this->language = $language;
$this->crdate = $crdate;
$this->url = $url;
$this->userAgent = $userAgent;
$this->recordUid = $recordUid;
$this->tableName = $tableName;
} }
public function getPageUid(): int public function getPageUid(): int

View file

@ -27,32 +27,14 @@ use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
class SymfonyExpression implements Expression class SymfonyExpression implements Expression
{ {
/**
* @var string
*/
private $expression;
/**
* @var array
*/
private $values;
/**
* @var ExpressionLanguage
*/
private $symfonyExpression;
public function __construct( public function __construct(
string $expression, private readonly string $expression,
array $values, private readonly array $values,
ExpressionLanguage $symfonyExpression private readonly ExpressionLanguage $symfonyExpression
) { ) {
$this->expression = $expression;
$this->values = $values;
$this->symfonyExpression = $symfonyExpression;
} }
public function evaluate() public function evaluate(): mixed
{ {
return $this->symfonyExpression->evaluate( return $this->symfonyExpression->evaluate(
$this->expression, $this->expression,

View file

@ -24,23 +24,18 @@ declare(strict_types=1);
namespace DanielSiepmann\Tracking\Domain\Pageview; namespace DanielSiepmann\Tracking\Domain\Pageview;
use DanielSiepmann\Tracking\Domain\Model\Pageview; use DanielSiepmann\Tracking\Domain\Model\Pageview;
use DanielSiepmann\Tracking\Domain\Repository\Site;
use DateTimeImmutable; use DateTimeImmutable;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Routing\PageArguments; use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteFinder;
use UnexpectedValueException; use UnexpectedValueException;
class Factory class Factory
{ {
/** public function __construct(
* @var SiteFinder private readonly Site $siteRepository
*/ ) {
private $siteFinder;
public function __construct(SiteFinder $siteFinder)
{
$this->siteFinder = $siteFinder;
} }
public function fromRequest(ServerRequestInterface $request): Pageview public function fromRequest(ServerRequestInterface $request): Pageview
@ -49,8 +44,8 @@ class Factory
$this->getRouting($request)->getPageId(), $this->getRouting($request)->getPageId(),
$this->getLanguage($request), $this->getLanguage($request),
new DateTimeImmutable(), new DateTimeImmutable(),
(int)$this->getRouting($request)->getPageType(), (int) $this->getRouting($request)->getPageType(),
(string)$request->getUri(), (string) $request->getUri(),
$request->getHeader('User-Agent')[0] ?? '' $request->getHeader('User-Agent')[0] ?? ''
); );
} }
@ -58,13 +53,13 @@ class Factory
public function fromDbRow(array $dbRow): Pageview public function fromDbRow(array $dbRow): Pageview
{ {
return new Pageview( return new Pageview(
(int)$dbRow['pid'], (int) $dbRow['pid'],
$this->siteFinder->getSiteByPageId((int)$dbRow['pid'])->getLanguageById((int)$dbRow['sys_language_uid']), $this->siteRepository->findByPageUid((int) $dbRow['pid'])->getLanguageById((int) $dbRow['sys_language_uid']),
new DateTimeImmutable('@' . $dbRow['crdate']), new DateTimeImmutable('@' . $dbRow['crdate']),
(int)$dbRow['type'], (int) $dbRow['type'],
$dbRow['url'], $dbRow['url'],
$dbRow['user_agent'], $dbRow['user_agent'],
(int)$dbRow['uid'] (int) $dbRow['uid']
); );
} }

View file

@ -34,15 +34,9 @@ use UnexpectedValueException;
class Factory class Factory
{ {
/**
* @var ExpressionFactory
*/
private $expressionFactory;
public function __construct( public function __construct(
ExpressionFactory $expressionFactory private readonly ExpressionFactory $expressionFactory
) { ) {
$this->expressionFactory = $expressionFactory;
} }
public function fromRequest( public function fromRequest(
@ -69,9 +63,9 @@ class Factory
self::getRouting($request)->getPageId(), self::getRouting($request)->getPageId(),
self::getLanguage($request), self::getLanguage($request),
new DateTimeImmutable(), new DateTimeImmutable(),
(string)$request->getUri(), (string) $request->getUri(),
$request->getHeader('User-Agent')[0] ?? '', $request->getHeader('User-Agent')[0] ?? '',
(int)$recordUid, (int) $recordUid,
$rule->getTableName() $rule->getTableName()
); );
} }

View file

@ -31,22 +31,10 @@ use TYPO3\CMS\Core\Database\Connection;
class Pageview class Pageview
{ {
/**
* @var Connection
*/
private $connection;
/**
* @var Factory
*/
private $factory;
public function __construct( public function __construct(
Connection $connection, private readonly Connection $connection,
Factory $factory private readonly Factory $factory
) { ) {
$this->connection = $connection;
$this->factory = $factory;
} }
public function countAll(): int public function countAll(): int
@ -54,27 +42,26 @@ class Pageview
$result = $this->connection->createQueryBuilder() $result = $this->connection->createQueryBuilder()
->count('uid') ->count('uid')
->from('tx_tracking_pageview') ->from('tx_tracking_pageview')
->execute() ->executeQuery()
->fetchOne() ->fetchOne()
; ;
if (is_numeric($result)) { if (is_numeric($result)) {
return (int)$result; return (int) $result;
} }
return 0; return 0;
} }
/**
* @return Generator<Model>
*/
public function findAll(): Generator public function findAll(): Generator
{ {
$queryBuilder = $this->connection->createQueryBuilder(); $queryBuilder = $this->connection->createQueryBuilder();
$pageViews = $queryBuilder->select('*')->from('tx_tracking_pageview')->execute(); $pageViews = $queryBuilder->select('*')->from('tx_tracking_pageview')->executeQuery();
while ($pageView = $pageViews->fetch()) {
if (is_array($pageView) === false) {
continue;
}
while ($pageView = $pageViews->fetchAssociative()) {
yield $this->factory->fromDbRow($pageView); yield $this->factory->fromDbRow($pageView);
} }
} }

View file

@ -28,15 +28,9 @@ use TYPO3\CMS\Core\Database\Connection;
class Recordview class Recordview
{ {
/**
* @var Connection
*/
private $connection;
public function __construct( public function __construct(
Connection $connection private readonly Connection $connection
) { ) {
$this->connection = $connection;
} }
public function add(Model $recordview): void public function add(Model $recordview): void

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2024 Daniel Siepmann <daniel.siepmann@codappix.com>
*
* 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.
*/
namespace DanielSiepmann\Tracking\Domain\Repository;
use TYPO3\CMS\Core\Site\Entity\Site as SiteEntity;
use TYPO3\CMS\Core\Site\SiteFinder;
class Site
{
public function __construct(
private readonly SiteFinder $siteFinder
) {
}
public function findByPageUid(int $pageUid): SiteEntity
{
return $this->siteFinder->getSiteByPageId($pageUid);
}
}

View file

@ -55,9 +55,10 @@ class DataHandler
$copyWhichTables = GeneralUtility::trimExplode(',', $dataHandler->copyWhichTables, true); $copyWhichTables = GeneralUtility::trimExplode(',', $dataHandler->copyWhichTables, true);
} }
$copyWhichTables = array_filter($copyWhichTables, static function (string $tableName) { $copyWhichTables = array_filter(
return \str_starts_with($tableName, 'tx_tracking_') === false; $copyWhichTables,
}); static fn (int|string $tableName): bool => \str_starts_with((string) $tableName, 'tx_tracking_') === false
);
$dataHandler->copyWhichTables = implode(',', $copyWhichTables); $dataHandler->copyWhichTables = implode(',', $copyWhichTables);
} }

View file

@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2024 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.
*/
namespace DanielSiepmann\Tracking;
use TYPO3\CMS\Core\Context\LanguageAspect;
class LanguageAspectFactory
{
public function createFromLanguageUid(int $languageUid): LanguageAspect
{
return new LanguageAspect(
$languageUid,
null,
LanguageAspect::OVERLAYS_MIXED
);
}
}

View file

@ -34,43 +34,13 @@ use TYPO3\CMS\Core\Context\Context;
class Pageview implements MiddlewareInterface class Pageview implements MiddlewareInterface
{ {
/**
* @var Repository
*/
private $repository;
/**
* @var Context
*/
private $context;
/**
* @var Factory
*/
private $factory;
/**
* @var ExpressionFactory
*/
private $expressionFactory;
/**
* @var string
*/
private $rule = '';
public function __construct( public function __construct(
Repository $repository, private readonly Repository $repository,
Context $context, private readonly Context $context,
Factory $factory, private readonly Factory $factory,
ExpressionFactory $expressionFactory, private readonly ExpressionFactory $expressionFactory,
string $rule private readonly string $rule
) { ) {
$this->repository = $repository;
$this->context = $context;
$this->factory = $factory;
$this->expressionFactory = $expressionFactory;
$this->rule = $rule;
} }
public function process( public function process(
@ -88,7 +58,7 @@ class Pageview implements MiddlewareInterface
ServerRequestInterface $request, ServerRequestInterface $request,
Context $context Context $context
): bool { ): bool {
return (bool)$this->expressionFactory->create( return (bool) $this->expressionFactory->create(
$this->rule, $this->rule,
[ [
'request' => $request, 'request' => $request,

View file

@ -35,43 +35,18 @@ use TYPO3\CMS\Core\Context\Context;
class Recordview implements MiddlewareInterface class Recordview implements MiddlewareInterface
{ {
/**
* @var Repository
*/
private $repository;
/**
* @var Context
*/
private $context;
/**
* @var Factory
*/
private $factory;
/**
* @var ExpressionFactory
*/
private $expressionFactory;
/** /**
* @var array<RecordRule> * @var array<RecordRule>
*/ */
private $rules = []; private array $rules = [];
public function __construct( public function __construct(
Repository $repository, private readonly Repository $repository,
Context $context, private readonly Context $context,
Factory $factory, private readonly Factory $factory,
ExpressionFactory $expressionFactory, private readonly ExpressionFactory $expressionFactory,
array $rules array $rules
) { ) {
$this->repository = $repository;
$this->context = $context;
$this->factory = $factory;
$this->expressionFactory = $expressionFactory;
$this->rules = RecordRule::multipleFromArray($rules); $this->rules = RecordRule::multipleFromArray($rules);
} }
@ -93,7 +68,7 @@ class Recordview implements MiddlewareInterface
Context $context, Context $context,
RecordRule $rule RecordRule $rule
): bool { ): bool {
return (bool)$this->expressionFactory->create( return (bool) $this->expressionFactory->create(
$rule->getMatchesExpression(), $rule->getMatchesExpression(),
[ [
'request' => $request, 'request' => $request,

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'tracking' => [ 'tracking' => [
'title' => 'LLL:EXT:tracking/Resources/Private/Language/locallang.xlf:dashboard.widget.group.tracking', 'title' => 'LLL:EXT:tracking/Resources/Private/Language/locallang.xlf:dashboard.widget.group.tracking',

View file

@ -14,7 +14,6 @@ services:
dashboard.widget.danielsiepmann.tracking.pageViewsPerDay: dashboard.widget.danielsiepmann.tracking.pageViewsPerDay:
class: 'TYPO3\CMS\Dashboard\Widgets\BarChartWidget' class: 'TYPO3\CMS\Dashboard\Widgets\BarChartWidget'
arguments: arguments:
$view: '@dashboard.views.widget'
$dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay' $dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay'
tags: tags:
- name: 'dashboard.widget' - name: 'dashboard.widget'
@ -34,7 +33,6 @@ services:
dashboard.widget.danielsiepmann.tracking.pageViewsPerPage: dashboard.widget.danielsiepmann.tracking.pageViewsPerPage:
class: 'TYPO3\CMS\Dashboard\Widgets\DoughnutChartWidget' class: 'TYPO3\CMS\Dashboard\Widgets\DoughnutChartWidget'
arguments: arguments:
$view: '@dashboard.views.widget'
$dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage' $dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage'
tags: tags:
- name: 'dashboard.widget' - name: 'dashboard.widget'
@ -54,7 +52,6 @@ services:
dashboard.widget.danielsiepmann.tracking.newestPageviews: dashboard.widget.danielsiepmann.tracking.newestPageviews:
class: 'TYPO3\CMS\Dashboard\Widgets\ListWidget' class: 'TYPO3\CMS\Dashboard\Widgets\ListWidget'
arguments: arguments:
$view: '@dashboard.views.widget'
$dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews' $dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews'
tags: tags:
- name: 'dashboard.widget' - name: 'dashboard.widget'
@ -74,7 +71,6 @@ services:
dashboard.widget.danielsiepmann.tracking.operatingSystems: dashboard.widget.danielsiepmann.tracking.operatingSystems:
class: 'TYPO3\CMS\Dashboard\Widgets\DoughnutChartWidget' class: 'TYPO3\CMS\Dashboard\Widgets\DoughnutChartWidget'
arguments: arguments:
$view: '@dashboard.views.widget'
$dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem' $dataProvider: '@DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem'
tags: tags:
- name: 'dashboard.widget' - name: 'dashboard.widget'

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
use DanielSiepmann\Tracking\Middleware\Pageview; use DanielSiepmann\Tracking\Middleware\Pageview;
use DanielSiepmann\Tracking\Middleware\Recordview; use DanielSiepmann\Tracking\Middleware\Recordview;

View file

@ -1,6 +1,8 @@
<?php <?php
$tca = [ declare(strict_types=1);
return [
'ctrl' => [ 'ctrl' => [
'label' => 'url', 'label' => 'url',
'label_alt' => 'crdate', 'label_alt' => 'crdate',
@ -69,16 +71,3 @@ $tca = [
], ],
], ],
]; ];
if ((new \TYPO3\CMS\Core\Information\Typo3Version())->getMajorVersion() < 12) {
$tca['ctrl']['cruser_id'] = 'cruser_id';
$tca['columns']['crdate']['config']['type'] = 'input';
$tca['columns']['crdate']['config']['renderType'] = 'inputDateTime';
$tca['columns']['crdate']['config']['eval'] = 'datetime';
$tca['columns']['type']['config']['type'] = 'input';
$tca['columns']['type']['config']['eval'] = 'int';
}
return $tca;

View file

@ -1,6 +1,8 @@
<?php <?php
$tca = [ declare(strict_types=1);
return [
'ctrl' => [ 'ctrl' => [
'label' => 'record', 'label' => 'record',
'label_alt' => 'crdate', 'label_alt' => 'crdate',
@ -72,13 +74,3 @@ $tca = [
], ],
], ],
]; ];
if ((new \TYPO3\CMS\Core\Information\Typo3Version())->getMajorVersion() < 12) {
$tca['ctrl']['cruser_id'] = 'cruser_id';
$tca['columns']['crdate']['config']['type'] = 'input';
$tca['columns']['crdate']['config']['renderType'] = 'inputDateTime';
$tca['columns']['crdate']['config']['eval'] = 'datetime';
}
return $tca;

View file

@ -0,0 +1,30 @@
3.0.0
=====
Breaking
--------
* Drop support for TYPO3 v11.
We only support last two TYPO3 versions.
* Drop `ext_emconf.php` this probably will remove support for none composer setups.
Features
--------
* Add Support for TYPO3 v13.
Fixes
-----
Nothing
Tasks
-----
Nothing
Deprecation
-----------
Nothing

View file

@ -1,8 +0,0 @@
V11
===
Remove TCA fallback wrapped in version constraint in:
- ``Configuration/TCA/tx_tracking_pageview.php``
- ``Configuration/TCA/tx_tracking_recordview.php``

View file

@ -0,0 +1,4 @@
V12
===
Remove `new DataHandler()` calls.

View file

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/*
* Copyright (C) 2024 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.
*/
namespace DanielSiepmann\Tracking\Tests\Functional;
use Codappix\Typo3PhpDatasets\TestingFramework;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
abstract class AbstractFunctionalTestCase extends FunctionalTestCase
{
use TestingFramework;
protected array $testExtensionsToLoad = ['danielsiepmann/tracking'];
protected array $coreExtensionsToLoad = ['typo3/cms-dashboard'];
}

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional\Command; namespace DanielSiepmann\Tracking\Tests\Functional\Command;
/* /*
@ -21,30 +23,21 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Command;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework;
use DanielSiepmann\Tracking\Command\UpdateDataCommand; use DanielSiepmann\Tracking\Command\UpdateDataCommand;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(UpdateDataCommand::class)]
* @covers \DanielSiepmann\Tracking\Command\UpdateDataCommand final class UpdateDataCommandTest extends AbstractFunctionalTestCase
*/
class UpdateDataCommandTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
protected array $pathsToLinkInTestInstance = [ protected array $pathsToLinkInTestInstance = [
'typo3conf/ext/tracking/Tests/Functional/Fixtures/sites' => 'typo3conf/sites', 'typo3conf/ext/tracking/Tests/Functional/Fixtures/sites' => 'typo3conf/sites',
]; ];
/** #[Test]
* @test
*/
public function updatesAllEntriesWithMissingOperatingSystem(): void public function updatesAllEntriesWithMissingOperatingSystem(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../Fixtures/UpdateDataCommandTest/PageviewsWithMissingOperatingSystem.php'); $this->importPHPDataSet(__DIR__ . '/../Fixtures/UpdateDataCommandTest/PageviewsWithMissingOperatingSystem.php');
@ -61,9 +54,7 @@ class UpdateDataCommandTest extends FunctionalTestCase
self::assertSame('Android', $records[1]['operating_system']); self::assertSame('Android', $records[1]['operating_system']);
} }
/** #[Test]
* @test
*/
public function doesNotChangeExistingOperatingSystem(): void public function doesNotChangeExistingOperatingSystem(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../Fixtures/UpdateDataCommandTest/PageviewsWithOperatingSystem.php'); $this->importPHPDataSet(__DIR__ . '/../Fixtures/UpdateDataCommandTest/PageviewsWithOperatingSystem.php');
@ -80,9 +71,7 @@ class UpdateDataCommandTest extends FunctionalTestCase
self::assertSame('Android', $records[1]['operating_system']); self::assertSame('Android', $records[1]['operating_system']);
} }
/** #[Test]
* @test
*/
public function doesNothingIfNoRecordExists(): void public function doesNothingIfNoRecordExists(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../Fixtures/Pages.php');

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider; namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
/* /*
@ -22,22 +24,16 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
*/ */
use DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews; use DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(NewestPageviews::class)]
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\NewestPageviews final class NewestPageviewsTest extends AbstractFunctionalTestCase
*/
class NewestPageviewsTest extends FunctionalTestCase
{ {
protected array $testExtensionsToLoad = [ #[Test]
'typo3conf/ext/tracking',
];
/**
* @test
*/
public function returnsRecentSixPageviews(): void public function returnsRecentSixPageviews(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
@ -64,9 +60,7 @@ class NewestPageviewsTest extends FunctionalTestCase
], $subject->getItems()); ], $subject->getItems());
} }
/** #[Test]
* @test
*/
public function respectsMaxResults(): void public function respectsMaxResults(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
@ -90,9 +84,7 @@ class NewestPageviewsTest extends FunctionalTestCase
], $subject->getItems()); ], $subject->getItems());
} }
/** #[Test]
* @test
*/
public function respectsPagesToExclude(): void public function respectsPagesToExclude(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
@ -121,9 +113,7 @@ class NewestPageviewsTest extends FunctionalTestCase
], $subject->getItems()); ], $subject->getItems());
} }
/** #[Test]
* @test
*/
public function respectsLimitToLanguages(): void public function respectsLimitToLanguages(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider; namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
/* /*
@ -21,28 +23,21 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework;
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay; use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(PageviewsPerDay::class)]
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerDay final class PageviewsPerDayTest extends AbstractFunctionalTestCase
*/
class PageviewsPerDayTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
$GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default'); $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
} }
protected function tearDown(): void protected function tearDown(): void
@ -51,9 +46,7 @@ class PageviewsPerDayTest extends FunctionalTestCase
parent::tearDown(); parent::tearDown();
} }
/** #[Test]
* @test
*/
public function listsResultsForLast31DaysByDefault(): void public function listsResultsForLast31DaysByDefault(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
@ -73,9 +66,7 @@ class PageviewsPerDayTest extends FunctionalTestCase
self::assertCount(32, $result['datasets'][0]['data']); self::assertCount(32, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedNumberOfDays(): void public function respectedNumberOfDays(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -102,9 +93,7 @@ class PageviewsPerDayTest extends FunctionalTestCase
], $result['datasets'][0]['data']); ], $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedExcludedPages(): void public function respectedExcludedPages(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -132,9 +121,7 @@ class PageviewsPerDayTest extends FunctionalTestCase
], $result['datasets'][0]['data']); ], $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedDateFormat(): void public function respectedDateFormat(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -156,9 +143,7 @@ class PageviewsPerDayTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectsLimitToLanguages(): void public function respectsLimitToLanguages(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider; namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
/* /*
@ -21,26 +23,17 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework;
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem; use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(PageviewsPerOperatingSystem::class)]
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerOperatingSystem final class PageviewsPerOperatingSystemTest extends AbstractFunctionalTestCase
*/
class PageviewsPerOperatingSystemTest extends FunctionalTestCase
{ {
use TestingFramework; #[Test]
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
/**
* @test
*/
public function listsSixResultsForLast31DaysByDefault(): void public function listsSixResultsForLast31DaysByDefault(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_pageview');
@ -68,9 +61,7 @@ class PageviewsPerOperatingSystemTest extends FunctionalTestCase
self::assertCount(6, $result['datasets'][0]['data']); self::assertCount(6, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedOrdering(): void public function respectedOrdering(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -109,9 +100,7 @@ class PageviewsPerOperatingSystemTest extends FunctionalTestCase
self::assertCount(3, $result['datasets'][0]['data']); self::assertCount(3, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedNumberOfDays(): void public function respectedNumberOfDays(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -145,9 +134,7 @@ class PageviewsPerOperatingSystemTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedMaxResults(): void public function respectedMaxResults(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -176,9 +163,7 @@ class PageviewsPerOperatingSystemTest extends FunctionalTestCase
self::assertCount(4, $result['datasets'][0]['data']); self::assertCount(4, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectsLimitToLanguages(): void public function respectsLimitToLanguages(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider; namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
/* /*
@ -21,40 +23,35 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework;
use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage; use DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(PageviewsPerPage::class)]
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\PageviewsPerPage final class PageviewsPerPageTest extends AbstractFunctionalTestCase
*/
class PageviewsPerPageTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
$GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/BackendUser.php');
$GLOBALS['BE_USER'] = $this->setUpBackendUser(1);
$GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
} }
protected function tearDown(): void protected function tearDown(): void
{ {
unset($GLOBALS['LANG']); unset(
$GLOBALS['BE_USER'],
$GLOBALS['LANG']
);
parent::tearDown(); parent::tearDown();
} }
/** #[Test]
* @test
*/
public function listsSixResultsForLast31DaysByDefault(): void public function listsSixResultsForLast31DaysByDefault(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -67,8 +64,8 @@ class PageviewsPerPageTest extends FunctionalTestCase
} }
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class) $this->get(PageRepository::class)
); );
$result = $subject->getChartData(); $result = $subject->getChartData();
@ -83,9 +80,7 @@ class PageviewsPerPageTest extends FunctionalTestCase
self::assertCount(6, $result['datasets'][0]['data']); self::assertCount(6, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedOrdering(): void public function respectedOrdering(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -108,8 +103,8 @@ class PageviewsPerPageTest extends FunctionalTestCase
]); ]);
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class) $this->get(PageRepository::class)
); );
$result = $subject->getChartData(); $result = $subject->getChartData();
@ -121,9 +116,7 @@ class PageviewsPerPageTest extends FunctionalTestCase
self::assertCount(3, $result['datasets'][0]['data']); self::assertCount(3, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedNumberOfDays(): void public function respectedNumberOfDays(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -142,8 +135,8 @@ class PageviewsPerPageTest extends FunctionalTestCase
]); ]);
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
2 2
); );
@ -155,9 +148,7 @@ class PageviewsPerPageTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedMaxResults(): void public function respectedMaxResults(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -170,8 +161,8 @@ class PageviewsPerPageTest extends FunctionalTestCase
} }
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
31, 31,
4 4
); );
@ -186,9 +177,7 @@ class PageviewsPerPageTest extends FunctionalTestCase
self::assertCount(4, $result['datasets'][0]['data']); self::assertCount(4, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedExcludedPages(): void public function respectedExcludedPages(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -201,8 +190,8 @@ class PageviewsPerPageTest extends FunctionalTestCase
} }
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
31, 31,
6, 6,
[1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
@ -218,9 +207,7 @@ class PageviewsPerPageTest extends FunctionalTestCase
self::assertCount(4, $result['datasets'][0]['data']); self::assertCount(4, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function localizedRecordTitlesIfLimitedToSingleLanguage(): void public function localizedRecordTitlesIfLimitedToSingleLanguage(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -249,8 +236,8 @@ class PageviewsPerPageTest extends FunctionalTestCase
]); ]);
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
31, 31,
6, 6,
[], [],
@ -260,14 +247,12 @@ class PageviewsPerPageTest extends FunctionalTestCase
$result = $subject->getChartData(); $result = $subject->getChartData();
self::assertSame([ self::assertSame([
'Page 2', 'Page 2',
'Page 1', 'Seite 1',
], $result['labels']); ], $result['labels']);
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function defaultLanguageTitleIsUsedIfMultipleLanguagesAreAllowed(): void public function defaultLanguageTitleIsUsedIfMultipleLanguagesAreAllowed(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/Pages.php');
@ -296,12 +281,12 @@ class PageviewsPerPageTest extends FunctionalTestCase
]); ]);
$subject = new PageviewsPerPage( $subject = new PageviewsPerPage(
GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'), $this->get(ConnectionPool::class)->getQueryBuilderForTable('tx_tracking_pageview'),
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
31, 31,
6, 6,
[], [],
[1, '0'] [1, 0]
); );
$result = $subject->getChartData(); $result = $subject->getChartData();

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider; namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
/* /*
@ -21,39 +23,35 @@ namespace DanielSiepmann\Tracking\Tests\Functional\Dashboard\Provider;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework;
use DanielSiepmann\Tracking\Dashboard\Provider\Recordviews; use DanielSiepmann\Tracking\Dashboard\Provider\Recordviews;
use DanielSiepmann\Tracking\LanguageAspectFactory;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Domain\Repository\PageRepository;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(Recordviews::class)]
* @covers \DanielSiepmann\Tracking\Dashboard\Provider\Recordviews final class RecordviewsTest extends AbstractFunctionalTestCase
*/
class RecordviewsTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
$GLOBALS['LANG'] = $this->getContainer()->get(LanguageServiceFactory::class)->create('default'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/BackendUser.php');
$GLOBALS['BE_USER'] = $this->setUpBackendUser(1);
$GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default');
} }
protected function tearDown(): void protected function tearDown(): void
{ {
unset($GLOBALS['LANG']); unset(
$GLOBALS['BE_USER'],
$GLOBALS['LANG']
);
parent::tearDown(); parent::tearDown();
} }
/** #[Test]
* @test
*/
public function listsSixResultsForLast31DaysByDefault(): void public function listsSixResultsForLast31DaysByDefault(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -68,8 +66,9 @@ class RecordviewsTest extends FunctionalTestCase
} }
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview') $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory()
); );
$result = $subject->getChartData(); $result = $subject->getChartData();
@ -84,9 +83,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(6, $result['datasets'][0]['data']); self::assertCount(6, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedOrdering(): void public function respectedOrdering(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -117,8 +114,9 @@ class RecordviewsTest extends FunctionalTestCase
]); ]);
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
2 2
); );
@ -131,9 +129,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(3, $result['datasets'][0]['data']); self::assertCount(3, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedNumberOfDays(): void public function respectedNumberOfDays(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -158,8 +154,9 @@ class RecordviewsTest extends FunctionalTestCase
]); ]);
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
2 2
); );
@ -171,9 +168,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedMaxResults(): void public function respectedMaxResults(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -188,8 +183,9 @@ class RecordviewsTest extends FunctionalTestCase
} }
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
31, 31,
2 2
); );
@ -202,9 +198,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectedExcludedPages(): void public function respectedExcludedPages(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -220,8 +214,9 @@ class RecordviewsTest extends FunctionalTestCase
} }
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
31, 31,
6, 6,
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
@ -238,9 +233,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(5, $result['datasets'][0]['data']); self::assertCount(5, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectLimitesTables(): void public function respectLimitesTables(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -261,8 +254,9 @@ class RecordviewsTest extends FunctionalTestCase
]); ]);
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
31, 31,
6, 6,
[], [],
@ -279,9 +273,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(3, $result['datasets'][0]['data']); self::assertCount(3, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function respectsLimitedTypes(): void public function respectsLimitedTypes(): void
{ {
$connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_recordview'); $connection = $this->getConnectionPool()->getConnectionForTable('tx_tracking_recordview');
@ -300,8 +292,9 @@ class RecordviewsTest extends FunctionalTestCase
} }
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
31, 31,
6, 6,
[], [],
@ -318,9 +311,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function localizedRecordTitlesIfLimitedToSingleLanguage(): void public function localizedRecordTitlesIfLimitedToSingleLanguage(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -348,8 +339,9 @@ class RecordviewsTest extends FunctionalTestCase
]); ]);
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
31, 31,
6, 6,
[], [],
@ -366,9 +358,7 @@ class RecordviewsTest extends FunctionalTestCase
self::assertCount(2, $result['datasets'][0]['data']); self::assertCount(2, $result['datasets'][0]['data']);
} }
/** #[Test]
* @test
*/
public function defaultLanguageTitleIsUsedIfMultipleLanguagesAreAllowed(): void public function defaultLanguageTitleIsUsedIfMultipleLanguagesAreAllowed(): void
{ {
$this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php'); $this->importPHPDataSet(__DIR__ . '/../../Fixtures/SysCategories.php');
@ -396,8 +386,9 @@ class RecordviewsTest extends FunctionalTestCase
]); ]);
$subject = new Recordviews( $subject = new Recordviews(
GeneralUtility::makeInstance(PageRepository::class), $this->get(PageRepository::class),
$this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'), $this->getConnectionPool()->getQueryBuilderForTable('tx_tracking_recordview'),
new LanguageAspectFactory(),
31, 31,
6, 6,
[], [],

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Recordview; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Recordview;
/* /*
@ -24,253 +26,246 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Recordview;
use DanielSiepmann\Tracking\Domain\Model\RecordRule; use DanielSiepmann\Tracking\Domain\Model\RecordRule;
use DanielSiepmann\Tracking\Domain\Model\Recordview; use DanielSiepmann\Tracking\Domain\Model\Recordview;
use DanielSiepmann\Tracking\Domain\Recordview\Factory; use DanielSiepmann\Tracking\Domain\Recordview\Factory;
use DanielSiepmann\Tracking\Tests\Functional\AbstractFunctionalTestCase;
use DateTimeImmutable; use DateTimeImmutable;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Routing\PageArguments; use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[CoversClass(Factory::class)]
* @covers \DanielSiepmann\Tracking\Domain\Recordview\Factory final class FactoryTest extends AbstractFunctionalTestCase
*/
class FactoryTest extends FunctionalTestCase
{ {
use ProphecyTrait; #[Test]
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
/**
* @test
*/
public function returnsRecordviewFromRequest(): void public function returnsRecordviewFromRequest(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([]);
$request->method('getQueryParams')->willReturn([
'category' => 10, 'category' => 10,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertInstanceOf(Recordview::class, $result); self::assertInstanceOf(Recordview::class, $result);
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsUserAgent(): void public function returnedRecordviewContainsUserAgent(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['Some User Agent']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn(['Some User Agent']);
$request->method('getQueryParams')->willReturn([
'category' => 10, 'category' => 10,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertSame('Some User Agent', $result->getUserAgent()); self::assertSame('Some User Agent', $result->getUserAgent());
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsUri(): void public function returnedRecordviewContainsUri(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('https://example.com');
$request->method('getHeader')->willReturn(['']);
$request->method('getQueryParams')->willReturn([
'category' => 10, 'category' => 10,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertSame('https://example.com', $result->getUrl()); self::assertSame('https://example.com', $result->getUrl());
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsDateTime(): void public function returnedRecordviewContainsDateTime(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('https://example.com');
$request->method('getHeader')->willReturn(['']);
$request->method('getQueryParams')->willReturn([
'category' => 10, 'category' => 10,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertInstanceOf(DateTimeImmutable::class, $result->getCrdate()); self::assertInstanceOf(DateTimeImmutable::class, $result->getCrdate());
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsLanguage(): void public function returnedRecordviewContainsLanguage(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('https://example.com');
$request->method('getHeader')->willReturn(['']);
$request->method('getQueryParams')->willReturn([
'category' => 10, 'category' => 10,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertSame($language->reveal(), $result->getLanguage()); self::assertSame($language, $result->getLanguage());
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsPageId(): void public function returnedRecordviewContainsPageId(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('https://example.com');
$request->method('getHeader')->willReturn(['']);
$request->method('getQueryParams')->willReturn([
'category' => 10, 'category' => 10,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertSame(10, $result->getPageUid()); self::assertSame(10, $result->getPageUid());
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsRecordUid(): void public function returnedRecordviewContainsRecordUid(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('https://example.com');
$request->method('getHeader')->willReturn(['']);
$request->method('getQueryParams')->willReturn([
'category' => 20, 'category' => 20,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertSame(20, $result->getRecordUid()); self::assertSame(20, $result->getRecordUid());
} }
/** #[Test]
* @test
*/
public function returnedRecordviewContainsTableName(): void public function returnedRecordviewContainsTableName(): void
{ {
$rule = $this->prophesize(RecordRule::class); $rule = $this->createStub(RecordRule::class);
$rule->getUidExpression()->willReturn('request.getQueryParams()["category"]'); $rule->method('getUidExpression')->willReturn('request.getQueryParams()["category"]');
$rule->getTableName()->willReturn('sys_category'); $rule->method('getTableName')->willReturn('sys_category');
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn(['']); ]);
$request->getQueryParams()->willReturn([ $request->method('getUri')->willReturn('https://example.com');
$request->method('getHeader')->willReturn(['']);
$request->method('getQueryParams')->willReturn([
'category' => 20, 'category' => 20,
]); ]);
$subject = $this->get(Factory::class); $subject = $this->get(Factory::class);
$result = $subject->fromRequest($request->reveal(), $rule->reveal()); $result = $subject->fromRequest($request, $rule);
self::assertSame('sys_category', $result->getTableName()); self::assertSame('sys_category', $result->getTableName());
} }
} }

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'be_users' => [ 'be_users' => [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
$EM_CONF[$_EXTKEY] = [ $EM_CONF[$_EXTKEY] = [
'title' => 'TESTING: Tracking recordview', 'title' => 'TESTING: Tracking recordview',
'description' => 'Used by functional tests', 'description' => 'Used by functional tests',

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'pages' => [ 'pages' => [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'sys_category' => [ 'sys_category' => [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'pages' => [ 'pages' => [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'pages' => [ 'pages' => [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
return [ return [
'pages' => [ 'pages' => [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional; namespace DanielSiepmann\Tracking\Tests\Functional;
/* /*
@ -21,24 +23,17 @@ namespace DanielSiepmann\Tracking\Tests\Functional;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework; use PHPUnit\Framework\Attributes\CoversNothing;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequestContext;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[TestDox('Pageviews are')]
* @testdox Pageviews are #[CoversNothing]
* final class PageviewTest extends AbstractFunctionalTestCase
* @coversNothing
*/
class PageviewTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
protected array $pathsToLinkInTestInstance = [ protected array $pathsToLinkInTestInstance = [
'typo3conf/ext/tracking/Tests/Functional/Fixtures/sites' => 'typo3conf/sites', 'typo3conf/ext/tracking/Tests/Functional/Fixtures/sites' => 'typo3conf/sites',
]; ];
@ -53,31 +48,27 @@ class PageviewTest extends FunctionalTestCase
]); ]);
} }
/** #[Test]
* @test
*/
public function trackedWhenAllowed(): void public function trackedWhenAllowed(): void
{ {
$request = new InternalRequest(); $request = new InternalRequest();
$request = $request->withPageId(1); $request = $request->withPageId(1);
$request = $request->withHeader('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0'); $request = $request->withHeader('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0');
$response = $this->executeFrontendRequest($request); $response = $this->executeFrontendSubRequest($request);
self::assertSame(200, $response->getStatusCode()); self::assertSame(200, $response->getStatusCode());
$records = $this->getAllRecords('tx_tracking_pageview'); $records = $this->getAllRecords('tx_tracking_pageview');
self::assertCount(1, $records); self::assertCount(1, $records);
self::assertSame('1', (string)$records[0]['pid']); self::assertSame('1', (string) $records[0]['pid']);
self::assertSame('1', (string)$records[0]['uid']); self::assertSame('1', (string) $records[0]['uid']);
self::assertSame('http://localhost/?id=1', $records[0]['url']); self::assertSame('http://localhost/?id=1', $records[0]['url']);
self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']); self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']);
self::assertSame('Macintosh', $records[0]['operating_system']); self::assertSame('Macintosh', $records[0]['operating_system']);
self::assertSame('0', (string)$records[0]['type']); self::assertSame('0', (string) $records[0]['type']);
} }
/** #[Test]
* @test
*/
public function notTrackedWhenDisallowed(): void public function notTrackedWhenDisallowed(): void
{ {
$this->importPHPDataSet(__DIR__ . '/Fixtures/BackendUser.php'); $this->importPHPDataSet(__DIR__ . '/Fixtures/BackendUser.php');
@ -87,7 +78,7 @@ class PageviewTest extends FunctionalTestCase
$request = $request->withPageId(1); $request = $request->withPageId(1);
$context = new InternalRequestContext(); $context = new InternalRequestContext();
$context = $context->withBackendUserId(1); $context = $context->withBackendUserId(1);
$response = $this->executeFrontendRequest($request, $context); $response = $this->executeFrontendSubRequest($request, $context);
self::assertSame(200, $response->getStatusCode()); self::assertSame(200, $response->getStatusCode());
@ -95,17 +86,14 @@ class PageviewTest extends FunctionalTestCase
self::assertCount(0, $records); self::assertCount(0, $records);
} }
/** #[DataProvider('possibleDeniedUserAgents')]
* @test #[Test]
*
* @dataProvider possibleDeniedUserAgents
*/
public function preventsTrackingOfUserAgents(string $userAgent): void public function preventsTrackingOfUserAgents(string $userAgent): void
{ {
$request = new InternalRequest(); $request = new InternalRequest();
$request = $request->withPageId(1); $request = $request->withPageId(1);
$request = $request->withHeader('User-Agent', $userAgent); $request = $request->withHeader('User-Agent', $userAgent);
$response = $this->executeFrontendRequest($request); $response = $this->executeFrontendSubRequest($request);
self::assertSame(200, $response->getStatusCode()); self::assertSame(200, $response->getStatusCode());
self::assertCount(0, $this->getAllRecords('tx_tracking_pageview')); self::assertCount(0, $this->getAllRecords('tx_tracking_pageview'));

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional; namespace DanielSiepmann\Tracking\Tests\Functional;
/* /*
@ -21,24 +23,15 @@ namespace DanielSiepmann\Tracking\Tests\Functional;
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use Codappix\Typo3PhpDatasets\TestingFramework; use PHPUnit\Framework\Attributes\CoversNothing;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
/** #[TestDox('Recordviews are')]
* @testdox Recordviews are #[CoversNothing]
* final class RecordviewTest extends AbstractFunctionalTestCase
* @coversNothing
*/
class RecordviewTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
'typo3conf/ext/tracking/Tests/Functional/Fixtures/Extensions/recordview',
];
protected array $pathsToLinkInTestInstance = [ protected array $pathsToLinkInTestInstance = [
'typo3conf/ext/tracking/Tests/Functional/Fixtures/sites' => 'typo3conf/sites', 'typo3conf/ext/tracking/Tests/Functional/Fixtures/sites' => 'typo3conf/sites',
]; ];
@ -53,6 +46,7 @@ class RecordviewTest extends FunctionalTestCase
protected function setUp(): void protected function setUp(): void
{ {
$this->testExtensionsToLoad[] = 'typo3conf/ext/tracking/Tests/Functional/Fixtures/Extensions/recordview';
parent::setUp(); parent::setUp();
$this->importPHPDataSet(__DIR__ . '/Fixtures/Pages.php'); $this->importPHPDataSet(__DIR__ . '/Fixtures/Pages.php');
@ -61,39 +55,35 @@ class RecordviewTest extends FunctionalTestCase
]); ]);
} }
/** #[Test]
* @test
*/
public function trackedWhenAllowed(): void public function trackedWhenAllowed(): void
{ {
$request = new InternalRequest(); $request = new InternalRequest();
$request = $request->withPageId(1); $request = $request->withPageId(1);
$request = $request->withQueryParameter('topic_id', 1); $request = $request->withQueryParameter('topic_id', 1);
$request = $request->withHeader('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0'); $request = $request->withHeader('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0');
$response = $this->executeFrontendRequest($request); $response = $this->executeFrontendSubRequest($request);
self::assertSame(200, $response->getStatusCode()); self::assertSame(200, $response->getStatusCode());
$records = $this->getAllRecords('tx_tracking_recordview'); $records = $this->getAllRecords('tx_tracking_recordview');
self::assertCount(1, $records); self::assertCount(1, $records);
self::assertSame('1', (string)$records[0]['pid']); self::assertSame('1', (string) $records[0]['pid']);
self::assertSame('1', (string)$records[0]['uid']); self::assertSame('1', (string) $records[0]['uid']);
self::assertSame('http://localhost/?id=1&topic_id=1', $records[0]['url']); self::assertSame('http://localhost/?id=1&topic_id=1', $records[0]['url']);
self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']); self::assertSame('Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0', $records[0]['user_agent']);
self::assertSame('Macintosh', $records[0]['operating_system']); self::assertSame('Macintosh', $records[0]['operating_system']);
self::assertSame('sys_category_1', $records[0]['record']); self::assertSame('sys_category_1', $records[0]['record']);
self::assertSame('1', (string)$records[0]['record_uid']); self::assertSame('1', (string) $records[0]['record_uid']);
self::assertSame('sys_category', $records[0]['record_table_name']); self::assertSame('sys_category', $records[0]['record_table_name']);
} }
/** #[Test]
* @test
*/
public function notTrackedWhenNotDetected(): void public function notTrackedWhenNotDetected(): void
{ {
$request = new InternalRequest(); $request = new InternalRequest();
$request = $request->withPageId(1); $request = $request->withPageId(1);
$response = $this->executeFrontendRequest($request); $response = $this->executeFrontendSubRequest($request);
self::assertSame(200, $response->getStatusCode()); self::assertSame(200, $response->getStatusCode());

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Functional; namespace DanielSiepmann\Tracking\Tests\Functional;
/* /*
@ -20,26 +22,15 @@ namespace DanielSiepmann\Tracking\Tests\Functional;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use PHPUnit\Framework\Attributes\Test;
use Codappix\Typo3PhpDatasets\TestingFramework; use PHPUnit\Framework\Attributes\TestDox;
use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory; use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
use UnexpectedValueException; use UnexpectedValueException;
/** #[TestDox('This extension works with TYPO3 feature:')]
* @covers \DanielSiepmann\Tracking\Functional\CopyingPageWithRecordsWorks final class Typo3FeaturesTest extends AbstractFunctionalTestCase
*
* @testdox This extension works with TYPO3 feature:
*/
class Typo3FeaturesTest extends FunctionalTestCase
{ {
use TestingFramework;
protected array $testExtensionsToLoad = [
'typo3conf/ext/tracking',
];
protected function setUp(): void protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
@ -47,7 +38,7 @@ class Typo3FeaturesTest extends FunctionalTestCase
$this->importPHPDataSet(__DIR__ . '/Fixtures/BackendUser.php'); $this->importPHPDataSet(__DIR__ . '/Fixtures/BackendUser.php');
$this->importPHPDataSet(__DIR__ . '/Fixtures/Typo3FeaturesTest/PageWithRecords.php'); $this->importPHPDataSet(__DIR__ . '/Fixtures/Typo3FeaturesTest/PageWithRecords.php');
$this->setUpBackendUser(1); $this->setUpBackendUser(1);
$languageServiceFactory = $this->getContainer()->get(LanguageServiceFactory::class); $languageServiceFactory = $this->get(LanguageServiceFactory::class);
if (!$languageServiceFactory instanceof LanguageServiceFactory) { if (!$languageServiceFactory instanceof LanguageServiceFactory) {
throw new UnexpectedValueException('Did not retrieve LanguageServiceFactory.', 1637847250); throw new UnexpectedValueException('Did not retrieve LanguageServiceFactory.', 1637847250);
} }
@ -61,14 +52,11 @@ class Typo3FeaturesTest extends FunctionalTestCase
parent::tearDown(); parent::tearDown();
} }
/** #[TestDox('Copy pages. Tracking records will not be copied.')]
* @test #[Test]
*
* @testdox Copy pages. Tracking records will not be copied.
*/
public function copyContainingRecords(): void public function copyContainingRecords(): void
{ {
$dataHandler = new DataHandler(); $dataHandler = $this->createDataHandler();
$dataHandler->start([], [ $dataHandler->start([], [
'pages' => [ 'pages' => [
1 => [ 1 => [
@ -84,14 +72,11 @@ class Typo3FeaturesTest extends FunctionalTestCase
); );
} }
/** #[TestDox('Copy individual tables, but always exclude tracking tables.')]
* @test #[Test]
*
* @testdox Copy individual tables, but always exclude tracking tables.
*/
public function copyCustomTablesViaDataHandler(): void public function copyCustomTablesViaDataHandler(): void
{ {
$dataHandler = new DataHandler(); $dataHandler = $this->createDataHandler();
$dataHandler->copyWhichTables = 'pages,tx_tracking_pageview,tx_tracking_recordview'; $dataHandler->copyWhichTables = 'pages,tx_tracking_pageview,tx_tracking_recordview';
$dataHandler->start([], [ $dataHandler->start([], [
'pages' => [ 'pages' => [
@ -107,4 +92,14 @@ class Typo3FeaturesTest extends FunctionalTestCase
'EXT:tracking/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv' 'EXT:tracking/Tests/Functional/ExpectedResults/Typo3FeaturesTest/CopyPasteContainingRecords.csv'
); );
} }
private function createDataHandler(): DataHandler
{
// Prior TYPO3 v13.2
if ($this->has(DataHandler::class) === false) {
return new DataHandler();
}
return $this->get(DataHandler::class);
}
} }

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
/* /*
@ -20,38 +22,32 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\Extractor; use DanielSiepmann\Tracking\Domain\Model\Extractor;
use DanielSiepmann\Tracking\Domain\Model\HasUserAgent; use DanielSiepmann\Tracking\Domain\Model\HasUserAgent;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\TestDox;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(Extractor::class)]
* @covers \DanielSiepmann\Tracking\Domain\Model\Extractor
*/
class ExtractorTest extends UnitTestCase class ExtractorTest extends UnitTestCase
{ {
use ProphecyTrait; #[DataProvider('possibleUserStringWithOperatingSystems')]
#[TestDox('Operating system $expectedOperatingSystem is extracted from UserAgent string: $userAgent')]
/** #[Test]
* @test
*
* @dataProvider possibleUserStringWithOperatingSystems
*
* @testdox Operating system $expectedOperatingSystem is extracted from UserAgent string: $userAgent
*/
public function returnsOperatingSystem(string $userAgent, string $expectedOperatingSystem): void public function returnsOperatingSystem(string $userAgent, string $expectedOperatingSystem): void
{ {
$model = $this->prophesize(HasUserAgent::class); $model = $this->createStub(HasUserAgent::class);
$model->getUserAgent()->willReturn($userAgent); $model->method('getUserAgent')->willReturn($userAgent);
self::assertSame( self::assertSame(
$expectedOperatingSystem, $expectedOperatingSystem,
Extractor::getOperatingSystem($model->reveal()) Extractor::getOperatingSystem($model)
); );
} }
public function possibleUserStringWithOperatingSystems(): array public static function possibleUserStringWithOperatingSystems(): array
{ {
return [ return [
[ [

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
/* /*
@ -20,30 +22,24 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\Pageview; use DanielSiepmann\Tracking\Domain\Model\Pageview;
use DateTimeImmutable; use DateTimeImmutable;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(Pageview::class)]
* @covers \DanielSiepmann\Tracking\Domain\Model\Pageview
*/
class PageviewTest extends UnitTestCase class PageviewTest extends UnitTestCase
{ {
use ProphecyTrait; #[Test]
/**
* @test
*/
public function canBeCreated(): void public function canBeCreated(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',
@ -53,16 +49,14 @@ class PageviewTest extends UnitTestCase
self::assertInstanceOf(Pageview::class, $subject); self::assertInstanceOf(Pageview::class, $subject);
} }
/** #[Test]
* @test
*/
public function returnsPageUid(): void public function returnsPageUid(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
500, 500,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',
@ -72,36 +66,32 @@ class PageviewTest extends UnitTestCase
self::assertSame(500, $subject->getPageUid()); self::assertSame(500, $subject->getPageUid());
} }
/** #[Test]
* @test
*/
public function returnsLanguage(): void public function returnsLanguage(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',
'' ''
); );
self::assertSame($language->reveal(), $subject->getLanguage()); self::assertSame($language, $subject->getLanguage());
} }
/** #[Test]
* @test
*/
public function returnsCrdate(): void public function returnsCrdate(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$crdate = new DateTimeImmutable(); $crdate = new DateTimeImmutable();
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
$crdate, $crdate,
0, 0,
'', '',
@ -111,16 +101,14 @@ class PageviewTest extends UnitTestCase
self::assertSame($crdate, $subject->getCrdate()); self::assertSame($crdate, $subject->getCrdate());
} }
/** #[Test]
* @test
*/
public function returnsPageType(): void public function returnsPageType(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
999, 999,
'', '',
@ -130,16 +118,14 @@ class PageviewTest extends UnitTestCase
self::assertSame(999, $subject->getPageType()); self::assertSame(999, $subject->getPageType());
} }
/** #[Test]
* @test
*/
public function returnsUrl(): void public function returnsUrl(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'https://example.com/path.html', 'https://example.com/path.html',
@ -149,16 +135,14 @@ class PageviewTest extends UnitTestCase
self::assertSame('https://example.com/path.html', $subject->getUrl()); self::assertSame('https://example.com/path.html', $subject->getUrl());
} }
/** #[Test]
* @test
*/
public function returnsUserAgent(): void public function returnsUserAgent(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',
@ -171,16 +155,14 @@ class PageviewTest extends UnitTestCase
); );
} }
/** #[Test]
* @test
*/
public function returnsZeroAsDefaultUid(): void public function returnsZeroAsDefaultUid(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',
@ -193,16 +175,14 @@ class PageviewTest extends UnitTestCase
); );
} }
/** #[Test]
* @test
*/
public function returnsSetAsUid(): void public function returnsSetAsUid(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',
@ -216,16 +196,14 @@ class PageviewTest extends UnitTestCase
); );
} }
/** #[Test]
* @test
*/
public function returnsOperatingSystem(): void public function returnsOperatingSystem(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Pageview( $subject = new Pageview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
0, 0,
'', '',

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
/* /*
@ -20,18 +22,15 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\RecordRule; use DanielSiepmann\Tracking\Domain\Model\RecordRule;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(RecordRule::class)]
* @covers \DanielSiepmann\Tracking\Domain\Model\RecordRule
*/
class RecordRuleTest extends UnitTestCase class RecordRuleTest extends UnitTestCase
{ {
/** #[Test]
* @test
*/
public function canBeCreatedViaConstructor(): void public function canBeCreatedViaConstructor(): void
{ {
$subject = new RecordRule( $subject = new RecordRule(
@ -43,9 +42,7 @@ class RecordRuleTest extends UnitTestCase
self::assertInstanceOf(RecordRule::class, $subject); self::assertInstanceOf(RecordRule::class, $subject);
} }
/** #[Test]
* @test
*/
public function canBeCreatedFromArray(): void public function canBeCreatedFromArray(): void
{ {
$subject = RecordRule::fromArray([ $subject = RecordRule::fromArray([
@ -58,9 +55,7 @@ class RecordRuleTest extends UnitTestCase
self::assertInstanceOf(RecordRule::class, $subject); self::assertInstanceOf(RecordRule::class, $subject);
} }
/** #[Test]
* @test
*/
public function multipleCanBeCratedFromArray(): void public function multipleCanBeCratedFromArray(): void
{ {
$result = RecordRule::multipleFromArray([ $result = RecordRule::multipleFromArray([
@ -81,9 +76,7 @@ class RecordRuleTest extends UnitTestCase
self::assertInstanceOf(RecordRule::class, $result[1]); self::assertInstanceOf(RecordRule::class, $result[1]);
} }
/** #[Test]
* @test
*/
public function returnsMatchExpression(): void public function returnsMatchExpression(): void
{ {
$subject = new RecordRule( $subject = new RecordRule(
@ -95,9 +88,7 @@ class RecordRuleTest extends UnitTestCase
self::assertSame('match expression', $subject->getMatchesExpression()); self::assertSame('match expression', $subject->getMatchesExpression());
} }
/** #[Test]
* @test
*/
public function returnsUidExpression(): void public function returnsUidExpression(): void
{ {
$subject = new RecordRule( $subject = new RecordRule(
@ -109,9 +100,7 @@ class RecordRuleTest extends UnitTestCase
self::assertSame('match expression', $subject->getUidExpression()); self::assertSame('match expression', $subject->getUidExpression());
} }
/** #[Test]
* @test
*/
public function returnsTableName(): void public function returnsTableName(): void
{ {
$subject = new RecordRule( $subject = new RecordRule(

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
/* /*
@ -20,30 +22,24 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Model;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\Recordview; use DanielSiepmann\Tracking\Domain\Model\Recordview;
use DateTimeImmutable; use DateTimeImmutable;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(Recordview::class)]
* @covers \DanielSiepmann\Tracking\Domain\Model\Recordview
*/
class RecordviewTest extends UnitTestCase class RecordviewTest extends UnitTestCase
{ {
use ProphecyTrait; #[Test]
/**
* @test
*/
public function canBeCreated(): void public function canBeCreated(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'', '',
@ -54,16 +50,14 @@ class RecordviewTest extends UnitTestCase
self::assertInstanceOf(Recordview::class, $subject); self::assertInstanceOf(Recordview::class, $subject);
} }
/** #[Test]
* @test
*/
public function returnsPageUid(): void public function returnsPageUid(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
500, 500,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'', '',
@ -74,16 +68,14 @@ class RecordviewTest extends UnitTestCase
self::assertSame(500, $subject->getPageUid()); self::assertSame(500, $subject->getPageUid());
} }
/** #[Test]
* @test
*/
public function returnsLanguage(): void public function returnsLanguage(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'', '',
@ -91,20 +83,18 @@ class RecordviewTest extends UnitTestCase
'sys_category' 'sys_category'
); );
self::assertSame($language->reveal(), $subject->getLanguage()); self::assertSame($language, $subject->getLanguage());
} }
/** #[Test]
* @test
*/
public function returnsCrdate(): void public function returnsCrdate(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$crdate = new DateTimeImmutable(); $crdate = new DateTimeImmutable();
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
$crdate, $crdate,
'', '',
'', '',
@ -115,16 +105,14 @@ class RecordviewTest extends UnitTestCase
self::assertSame($crdate, $subject->getCrdate()); self::assertSame($crdate, $subject->getCrdate());
} }
/** #[Test]
* @test
*/
public function returnsUrl(): void public function returnsUrl(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'https://example.com/path.html', 'https://example.com/path.html',
'', '',
@ -135,16 +123,14 @@ class RecordviewTest extends UnitTestCase
self::assertSame('https://example.com/path.html', $subject->getUrl()); self::assertSame('https://example.com/path.html', $subject->getUrl());
} }
/** #[Test]
* @test
*/
public function returnsUserAgent(): void public function returnsUserAgent(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
@ -158,16 +144,14 @@ class RecordviewTest extends UnitTestCase
); );
} }
/** #[Test]
* @test
*/
public function returnsRecordUid(): void public function returnsRecordUid(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'', '',
@ -181,16 +165,14 @@ class RecordviewTest extends UnitTestCase
); );
} }
/** #[Test]
* @test
*/
public function returnsTableName(): void public function returnsTableName(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'', '',
@ -204,16 +186,14 @@ class RecordviewTest extends UnitTestCase
); );
} }
/** #[Test]
* @test
*/
public function returnsOperatingSystem(): void public function returnsOperatingSystem(): void
{ {
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$subject = new Recordview( $subject = new Recordview(
0, 0,
$language->reveal(), $language,
new DateTimeImmutable(), new DateTimeImmutable(),
'', '',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36',

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Pageview; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Pageview;
/* /*
@ -20,212 +22,206 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Pageview;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\Pageview; use DanielSiepmann\Tracking\Domain\Model\Pageview;
use DanielSiepmann\Tracking\Domain\Pageview\Factory; use DanielSiepmann\Tracking\Domain\Pageview\Factory;
use DanielSiepmann\Tracking\Domain\Repository\Site;
use DateTimeImmutable; use DateTimeImmutable;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Routing\PageArguments; use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Site\Entity\Site as SiteEntity;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(Factory::class)]
* @covers \DanielSiepmann\Tracking\Domain\Pageview\Factory
*/
class FactoryTest extends UnitTestCase class FactoryTest extends UnitTestCase
{ {
use ProphecyTrait; #[Test]
/**
* @test
*/
public function returnsPageviewFromRequest(): void public function returnsPageviewFromRequest(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(0); $routing->method('getPageType')->willReturn('0');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertInstanceOf(Pageview::class, $result); self::assertInstanceOf(Pageview::class, $result);
} }
/** #[Test]
* @test
*/
public function returnedPageviewContainsUserAgent(): void public function returnedPageviewContainsUserAgent(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(0); $routing->method('getPageType')->willReturn('0');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([ ]);
$request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
]); ]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertSame( self::assertSame(
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
$result->getUserAgent() $result->getUserAgent()
); );
} }
/** #[Test]
* @test
*/
public function returnedPageviewContainsUri(): void public function returnedPageviewContainsUri(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(0); $routing->method('getPageType')->willReturn('0');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn('https://example.com/path?query=params&some=more#anchor'); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->method('getUri')->willReturn('https://example.com/path?query=params&some=more#anchor');
$request->method('getHeader')->willReturn([]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertSame( self::assertSame(
'https://example.com/path?query=params&some=more#anchor', 'https://example.com/path?query=params&some=more#anchor',
$result->getUrl() $result->getUrl()
); );
} }
/** #[Test]
* @test
*/
public function returnedPageviewContainsPageType(): void public function returnedPageviewContainsPageType(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(50); $routing->method('getPageType')->willReturn('50');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertSame( self::assertSame(
50, 50,
$result->getPageType() $result->getPageType()
); );
} }
/** #[Test]
* @test
*/
public function returnedPageviewContainsDateTime(): void public function returnedPageviewContainsDateTime(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(0); $routing->method('getPageType')->willReturn('0');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertInstanceOf(DateTimeImmutable::class, $result->getCrdate()); self::assertInstanceOf(DateTimeImmutable::class, $result->getCrdate());
} }
/** #[Test]
* @test
*/
public function returnedPageviewContainsLanguage(): void public function returnedPageviewContainsLanguage(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(0); $routing->method('getPageType')->willReturn('0');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertInstanceOf(SiteLanguage::class, $result->getLanguage()); self::assertInstanceOf(SiteLanguage::class, $result->getLanguage());
} }
/** #[Test]
* @test
*/
public function returnedPageviewContainsPageId(): void public function returnedPageviewContainsPageId(): void
{ {
$routing = $this->prophesize(PageArguments::class); $routing = $this->createStub(PageArguments::class);
$routing->getPageId()->willReturn(10); $routing->method('getPageId')->willReturn(10);
$routing->getPageType()->willReturn(0); $routing->method('getPageType')->willReturn('0');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$request = $this->prophesize(ServerRequestInterface::class); $request = $this->createStub(ServerRequestInterface::class);
$request->getAttribute('routing')->willReturn($routing->reveal()); $request->method('getAttribute')->willReturnMap([
$request->getAttribute('language')->willReturn($language->reveal()); ['routing', null, $routing],
$request->getUri()->willReturn(''); ['language', null, $language],
$request->getHeader('User-Agent')->willReturn([]); ]);
$request->method('getUri')->willReturn('');
$request->method('getHeader')->willReturn([]);
$subject = new Factory($this->prophesize(SiteFinder::class)->reveal()); $subject = new Factory($this->createStub(Site::class));
$result = $subject->fromRequest($request->reveal()); $result = $subject->fromRequest($request);
self::assertSame( self::assertSame(
10, 10,
$result->getPageUid() $result->getPageUid()
); );
} }
/** #[Test]
* @test
*/
public function returnsPageviewFromDbRow(): void public function returnsPageviewFromDbRow(): void
{ {
$siteLanguage = $this->prophesize(SiteLanguage::class); $siteLanguage = $this->createStub(SiteLanguage::class);
$site = $this->prophesize(Site::class); $site = $this->createStub(SiteEntity::class);
$site->getLanguageById(0)->willReturn($siteLanguage->reveal()); $site->method('getLanguageById')->willReturn($siteLanguage);
$siteFinder = $this->prophesize(SiteFinder::class); $siteRepository = $this->createStub(Site::class);
$siteFinder->getSiteByPageId(2)->willReturn($site->reveal()); $siteRepository->method('findByPageUid')->willReturn($site);
$subject = new Factory($siteFinder->reveal()); $subject = new Factory($siteRepository);
$result = $subject->fromDbRow([ $result = $subject->fromDbRow([
'uid' => 1, 'uid' => 1,
@ -240,7 +236,7 @@ class FactoryTest extends UnitTestCase
self::assertInstanceOf(Pageview::class, $result); self::assertInstanceOf(Pageview::class, $result);
self::assertSame(1, $result->getUid()); self::assertSame(1, $result->getUid());
self::assertSame(2, $result->getPageUid()); self::assertSame(2, $result->getPageUid());
self::assertSame($siteLanguage->reveal(), $result->getLanguage()); self::assertSame($siteLanguage, $result->getLanguage());
self::assertSame('1533906435', $result->getCrdate()->format('U')); self::assertSame('1533906435', $result->getCrdate()->format('U'));
self::assertSame(0, $result->getPageType()); self::assertSame(0, $result->getPageType());
self::assertSame('https://example.com/path', $result->getUrl()); self::assertSame('https://example.com/path', $result->getUrl());

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository;
/* /*
@ -20,47 +22,44 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\Pageview as Model; use DanielSiepmann\Tracking\Domain\Model\Pageview as Model;
use DanielSiepmann\Tracking\Domain\Pageview\Factory; use DanielSiepmann\Tracking\Domain\Pageview\Factory;
use DanielSiepmann\Tracking\Domain\Repository\Pageview; use DanielSiepmann\Tracking\Domain\Repository\Pageview;
use DateTimeImmutable; use DateTimeImmutable;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(Pageview::class)]
* @covers \DanielSiepmann\Tracking\Domain\Repository\Pageview
*/
class PageviewTest extends UnitTestCase class PageviewTest extends UnitTestCase
{ {
use ProphecyTrait; #[Test]
/**
* @test
*/
public function modelCanBeAdded(): void public function modelCanBeAdded(): void
{ {
$connection = $this->prophesize(Connection::class); $connection = $this->createMock(Connection::class);
$factory = $this->prophesize(Factory::class); $factory = $this->createMock(Factory::class);
$dateTime = $this->prophesize(DateTimeImmutable::class); $dateTime = $this->createStub(DateTimeImmutable::class);
$dateTime->format('U')->willReturn(1582660189); $dateTime->method('format')->willReturn('1582660189');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$language->getLanguageId()->willReturn(2); $language->method('getLanguageId')->willReturn(2);
$model = $this->prophesize(Model::class); $model = $this->createStub(Model::class);
$model->getPageUid()->willReturn(10); $model->method('getPageUid')->willReturn(10);
$model->getCrdate()->willReturn($dateTime->reveal()); $model->method('getCrdate')->willReturn($dateTime);
$model->getPageType()->willReturn(999); $model->method('getPageType')->willReturn(999);
$model->getLanguage()->willReturn($language->reveal()); $model->method('getLanguage')->willReturn($language);
$model->getUrl()->willReturn('https://example.com/path.html'); $model->method('getUrl')->willReturn('https://example.com/path.html');
$model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0'); $model->method('getUserAgent')->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
$model->getOperatingSystem()->willReturn('Linux'); $model->method('getOperatingSystem')->willReturn('Linux');
$connection->insert( $connection
->expects(self::once())
->method('insert')
->with(
'tx_tracking_pageview', 'tx_tracking_pageview',
[ [
'pid' => 10, 'pid' => 10,
@ -72,53 +71,54 @@ class PageviewTest extends UnitTestCase
'user_agent' => 'Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0', 'user_agent' => 'Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0',
'operating_system' => 'Linux', 'operating_system' => 'Linux',
] ]
)->willReturn(1)->shouldBeCalledTimes(1); )
->willReturn(1)
;
$subject = new Pageview($connection->reveal(), $factory->reveal()); $subject = new Pageview($connection, $factory);
$subject->add($model->reveal()); $subject->add($model);
} }
/** #[Test]
* @test
*/
public function throwsExceptionIfModelToUodateHasNoUid(): void public function throwsExceptionIfModelToUodateHasNoUid(): void
{ {
$connection = $this->prophesize(Connection::class); $connection = $this->createMock(Connection::class);
$factory = $this->prophesize(Factory::class); $factory = $this->createMock(Factory::class);
$model = $this->prophesize(Model::class); $model = $this->createStub(Model::class);
$model->getUid()->willReturn(0); $model->method('getUid')->willReturn(0);
$subject = new Pageview($connection->reveal(), $factory->reveal()); $subject = new Pageview($connection, $factory);
$this->expectExceptionMessage('Can not update pageview if uid is 0.'); $this->expectExceptionMessage('Can not update pageview if uid is 0.');
$subject->update($model->reveal()); $subject->update($model);
} }
/** #[Test]
* @test
*/
public function modelCanBeUpdated(): void public function modelCanBeUpdated(): void
{ {
$connection = $this->prophesize(Connection::class); $connection = $this->createMock(Connection::class);
$factory = $this->prophesize(Factory::class); $factory = $this->createMock(Factory::class);
$dateTime = $this->prophesize(DateTimeImmutable::class); $dateTime = $this->createStub(DateTimeImmutable::class);
$dateTime->format('U')->willReturn(1582660189); $dateTime->method('format')->willReturn('1582660189');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$language->getLanguageId()->willReturn(2); $language->method('getLanguageId')->willReturn(2);
$model = $this->prophesize(Model::class); $model = $this->createStub(Model::class);
$model->getUid()->willReturn(1); $model->method('getUid')->willReturn(1);
$model->getPageUid()->willReturn(10); $model->method('getPageUid')->willReturn(10);
$model->getCrdate()->willReturn($dateTime->reveal()); $model->method('getCrdate')->willReturn($dateTime);
$model->getPageType()->willReturn(999); $model->method('getPageType')->willReturn(999);
$model->getLanguage()->willReturn($language->reveal()); $model->method('getLanguage')->willReturn($language);
$model->getUrl()->willReturn('https://example.com/path.html'); $model->method('getUrl')->willReturn('https://example.com/path.html');
$model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0'); $model->method('getUserAgent')->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
$model->getOperatingSystem()->willReturn('Linux'); $model->method('getOperatingSystem')->willReturn('Linux');
$connection->update( $connection
->expects(self::once())
->method('update')
->with(
'tx_tracking_pageview', 'tx_tracking_pageview',
[ [
'pid' => 10, 'pid' => 10,
@ -133,9 +133,11 @@ class PageviewTest extends UnitTestCase
[ [
'uid' => 1, 'uid' => 1,
] ]
)->willReturn(1)->shouldBeCalledTimes(1); )
->willReturn(1)
;
$subject = new Pageview($connection->reveal(), $factory->reveal()); $subject = new Pageview($connection, $factory);
$subject->update($model->reveal()); $subject->update($model);
} }
} }

View file

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository; namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository;
/* /*
@ -20,46 +22,43 @@ namespace DanielSiepmann\Tracking\Tests\Unit\Domain\Repository;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use DanielSiepmann\Tracking\Domain\Model\Recordview as Model; use DanielSiepmann\Tracking\Domain\Model\Recordview as Model;
use DanielSiepmann\Tracking\Domain\Repository\Recordview; use DanielSiepmann\Tracking\Domain\Repository\Recordview;
use DateTimeImmutable; use DateTimeImmutable;
use Prophecy\PhpUnit\ProphecyTrait; use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase; use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/** #[CoversClass(Recordview::class)]
* @covers \DanielSiepmann\Tracking\Domain\Repository\Recordview
*/
class RecordviewTest extends UnitTestCase class RecordviewTest extends UnitTestCase
{ {
use ProphecyTrait; #[Test]
/**
* @test
*/
public function modelCanBeAdded(): void public function modelCanBeAdded(): void
{ {
$connection = $this->prophesize(Connection::class); $connection = $this->createMock(Connection::class);
$dateTime = $this->prophesize(DateTimeImmutable::class); $dateTime = $this->createStub(DateTimeImmutable::class);
$dateTime->format('U')->willReturn(1582660189); $dateTime->method('format')->willReturn('1582660189');
$language = $this->prophesize(SiteLanguage::class); $language = $this->createStub(SiteLanguage::class);
$language->getLanguageId()->willReturn(2); $language->method('getLanguageId')->willReturn(2);
$model = $this->prophesize(Model::class); $model = $this->createStub(Model::class);
$model->getPageUid()->willReturn(10); $model->method('getPageUid')->willReturn(10);
$model->getCrdate()->willReturn($dateTime->reveal()); $model->method('getCrdate')->willReturn($dateTime);
$model->getLanguage()->willReturn($language->reveal()); $model->method('getLanguage')->willReturn($language);
$model->getUrl()->willReturn('https://example.com/path.html'); $model->method('getUrl')->willReturn('https://example.com/path.html');
$model->getUserAgent()->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0'); $model->method('getUserAgent')->willReturn('Mozilla/5.0 (Windows NT 10.0) Gecko/20100101 Firefox/74.0');
$model->getOperatingSystem()->willReturn('Linux'); $model->method('getOperatingSystem')->willReturn('Linux');
$model->getRecordUid()->willReturn(10); $model->method('getRecordUid')->willReturn(10);
$model->getTableName()->willReturn('sys_category'); $model->method('getTableName')->willReturn('sys_category');
$connection->insert( $connection
->expects(self::once())
->method('insert')
->with(
'tx_tracking_recordview', 'tx_tracking_recordview',
[ [
'pid' => 10, 'pid' => 10,
@ -73,9 +72,11 @@ class RecordviewTest extends UnitTestCase
'record_table_name' => 'sys_category', 'record_table_name' => 'sys_category',
'record' => 'sys_category_10', 'record' => 'sys_category_10',
] ]
)->willReturn(1)->shouldBeCalledTimes(1); )
->willReturn(1)
;
$subject = new Recordview($connection->reveal()); $subject = new Recordview($connection);
$subject->add($model->reveal()); $subject->add($model);
} }
} }

View file

@ -26,28 +26,27 @@
} }
}, },
"require": { "require": {
"php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0", "php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"ext-mbstring": "*", "ext-mbstring": "*",
"doctrine/dbal": "^2.12 || ^3.3", "doctrine/dbal": "^2.12 || ^3.3 || ^4.0",
"psr/http-message": "^1.0", "psr/http-message": "^1.0",
"psr/http-server-handler": "^1.0", "psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0", "psr/http-server-middleware": "^1.0",
"symfony/console": "^5.2 || ^6.1", "symfony/console": "^5.2 || ^6.1 || ^7.0",
"symfony/expression-language": "^5.2 || ^6.1", "symfony/expression-language": "^5.2 || ^6.1 || ^7.0",
"typo3/cms-backend": "^11.5 || ^12.4", "typo3/cms-backend": "^12.4 || ^13.4",
"typo3/cms-core": "^11.5 || ^12.4", "typo3/cms-core": "^12.4 || ^13.4",
"typo3/cms-dashboard": "^11.5 || ^12.4" "typo3/cms-dashboard": "^12.4 || ^13.4"
}, },
"require-dev": { "require-dev": {
"codappix/typo3-php-datasets": "^1.3", "codappix/typo3-php-datasets": "^1.5",
"cweagans/composer-patches": "^1.7", "cweagans/composer-patches": "^1.7",
"friendsofphp/php-cs-fixer": "^3.14", "friendsofphp/php-cs-fixer": "^3.14",
"jangregor/phpstan-prophecy": "^1.0",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/extension-installer": "^1.1", "phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.8.7", "phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.0", "phpunit/phpunit": "^10.5",
"typo3/testing-framework": "^7.0" "saschaegerer/phpstan-typo3": "^1.10",
"typo3/testing-framework": "^8.0.9"
}, },
"minimum-stability": "dev", "minimum-stability": "dev",
"prefer-stable": true, "prefer-stable": true,
@ -59,15 +58,8 @@
}, },
"extra": { "extra": {
"typo3/cms": { "typo3/cms": {
"app-dir": ".Build",
"extension-key": "tracking", "extension-key": "tracking",
"web-dir": ".Build/web" "web-dir": ".Build/web"
},
"composer-exit-on-patch-failure": true,
"patches": {
},
"branch-alias": {
"dev-main": "1.0.x-dev"
} }
}, },
"config": { "config": {
@ -77,8 +69,7 @@
"typo3/class-alias-loader": true, "typo3/class-alias-loader": true,
"typo3/cms-composer-installers": true, "typo3/cms-composer-installers": true,
"cweagans/composer-patches": true, "cweagans/composer-patches": true,
"phpstan/extension-installer": true, "phpstan/extension-installer": true
"sbuerk/typo3-cmscomposerinstallers-testingframework-bridge": true
} }
} }
} }

View file

@ -1,21 +0,0 @@
<?php
$EM_CONF[$_EXTKEY] = [
'title' => 'Tracking',
'description' => 'Tracks page visits in TYPO3.',
'category' => 'fe',
'state' => 'stable',
'author' => 'Daniel Siepmann',
'author_email' => 'coding@daniel-siepmann.de',
'author_company' => '',
'version' => '2.5.0',
'constraints' => [
'depends' => [
'core' => '',
],
'conflicts' => [],
'suggests' => [
'dashboard' => '',
],
],
];

View file

@ -1,3 +1,7 @@
<?php <?php
\DanielSiepmann\Tracking\Hooks\DataHandler::register(); declare(strict_types=1);
use DanielSiepmann\Tracking\Hooks\DataHandler;
DataHandler::register();

View file

@ -1,51 +1,6 @@
parameters: parameters:
ignoreErrors: ignoreErrors:
- -
message: "#^Call to protected method getRecordOverlay\\(\\) of class TYPO3\\\\CMS\\\\Core\\\\Domain\\\\Repository\\\\PageRepository\\.$#" message: "#^Class TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\DataHandler constructor invoked with 0 parameters, 14 required\\.$#"
count: 1 count: 1
path: Classes/Dashboard/Provider/PageviewsPerPage.php path: Tests/Functional/Typo3FeaturesTest.php
-
message: "#^Call to protected method getRecordOverlay\\(\\) of class TYPO3\\\\CMS\\\\Core\\\\Domain\\\\Repository\\\\PageRepository\\.$#"
count: 1
path: Classes/Dashboard/Provider/Recordviews.php
-
message: "#^Parameter \\#2 \\$callback of function array_filter expects callable\\(int\\|string\\)\\: mixed, Closure\\(string\\)\\: bool given\\.$#"
count: 1
path: Classes/Hooks/DataHandler.php
-
message: "#^Parameter \\#1 \\$command of class Symfony\\\\Component\\\\Console\\\\Tester\\\\CommandTester constructor expects Symfony\\\\Component\\\\Console\\\\Command\\\\Command, object given\\.$#"
count: 3
path: Tests/Functional/Command/UpdateDataCommandTest.php
-
message: "#^Call to an undefined method object\\:\\:getQueryBuilderForTable\\(\\)\\.$#"
count: 4
path: Tests/Functional/Dashboard/Provider/NewestPageviewsTest.php
-
message: "#^Call to an undefined method object\\:\\:getQueryBuilderForTable\\(\\)\\.$#"
count: 5
path: Tests/Functional/Dashboard/Provider/PageviewsPerDayTest.php
-
message: "#^Call to an undefined method object\\:\\:getQueryBuilderForTable\\(\\)\\.$#"
count: 5
path: Tests/Functional/Dashboard/Provider/PageviewsPerOperatingSystemTest.php
-
message: "#^Call to an undefined method object\\:\\:getQueryBuilderForTable\\(\\)\\.$#"
count: 7
path: Tests/Functional/Dashboard/Provider/PageviewsPerPageTest.php
-
message: "#^Parameter \\#2 \\$pageRepository of class DanielSiepmann\\\\Tracking\\\\Dashboard\\\\Provider\\\\PageviewsPerPage constructor expects TYPO3\\\\CMS\\\\Core\\\\Domain\\\\Repository\\\\PageRepository, object given\\.$#"
count: 7
path: Tests/Functional/Dashboard/Provider/PageviewsPerPageTest.php
-
message: "#^Parameter \\#1 \\$pageRepository of class DanielSiepmann\\\\Tracking\\\\Dashboard\\\\Provider\\\\Recordviews constructor expects TYPO3\\\\CMS\\\\Core\\\\Domain\\\\Repository\\\\PageRepository, object given\\.$#"
count: 9
path: Tests/Functional/Dashboard/Provider/RecordviewsTest.php

View file

@ -5,16 +5,7 @@ parameters:
paths: paths:
- Classes - Classes
- Tests - Tests
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: false reportUnmatchedIgnoredErrors: false
ignoreErrors: ignoreErrors:
# Ignore error for TYPO3 11 and TYPO3 12 - identifier: missingType.iterableValue
- '#Cannot call method fetch\(\) on Doctrine\\DBAL\\Result\|int\.#'
- '#Cannot call method fetchAll\(\) on Doctrine\\DBAL\\Result\|int\.#'
- '#Cannot call method fetchColumn\(\) on Doctrine\\DBAL\\Result\|int\.#'
- '#Cannot call method fetchOne\(\) on Doctrine\\DBAL\\Result\|int\.#'
- "#^Parameter \\#[0-9] \\.\\.\\.\\$predicates of method TYPO3\\\\CMS\\\\Core\\\\Database\\\\Query\\\\QueryBuilder\\:\\:where\\(\\) expects array\\<int, mixed\\>\\|Doctrine\\\\DBAL\\\\Query\\\\Expression\\\\CompositeExpression, string given\\.$#"
- '#^Variable \$_EXTKEY might not be defined\.$#' - '#^Variable \$_EXTKEY might not be defined\.$#'
- "#^Cannot access offset '.*' on mixed.$#"
- "#^Parameter .* expects .*, mixed given.$#"
- "#^Cannot call method .* on mixed.$#"

View file

@ -1,22 +1,19 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<phpunit <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="false" backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php" bootstrap="vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTestsBootstrap.php"
colors="true" colors="true"
convertErrorsToExceptions="true"
convertWarningsToExceptions="true"
forceCoversAnnotation="false"
processIsolation="false" processIsolation="false"
stopOnError="false" stopOnError="false"
stopOnFailure="false" stopOnFailure="false"
stopOnIncomplete="false" stopOnIncomplete="false"
stopOnSkipped="false" stopOnSkipped="false"
verbose="false" cacheDirectory=".phpunit.cache"
> backupStaticProperties="false"
requireCoverageMetadata="false"
>
<testsuites> <testsuites>
<testsuite name="unit"> <testsuite name="unit">
<directory>Tests/Unit/</directory> <directory>Tests/Unit/</directory>
@ -25,14 +22,14 @@
<directory>Tests/Functional/</directory> <directory>Tests/Functional/</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
<coverage>
<include>
<directory suffix=".php">Classes</directory>
</include>
</coverage>
<php> <php>
<env name="typo3DatabaseDriver" value="pdo_sqlite"/> <env name="typo3DatabaseDriver" value="pdo_sqlite"/>
</php> </php>
<source>
<include>
<directory suffix=".php">
Classes
</directory>
</include>
</source>
</phpunit> </phpunit>

View file

@ -1,8 +1,20 @@
{ pkgs ? import <nixpkgs> { } }: {
pkgs ? import <nixpkgs> { }
,phps ? import <phps>
}:
let let
php = pkgs.php82; php = phps.packages.x86_64-linux.php83.buildEnv {
inherit(pkgs.php82Packages) composer; extensions = { enabled, all }: enabled ++ (with all; [
xdebug
]);
extraConfig = ''
xdebug.mode = debug
memory_limit = 4G
'';
};
inherit(php.packages) composer;
projectInstall = pkgs.writeShellApplication { projectInstall = pkgs.writeShellApplication {
name = "project-install"; name = "project-install";