diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c7d028..f817611 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,16 +13,62 @@ on: jobs: + composer-normalize: + name: Composer normalization + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: none + tools: composer-normalize + env: + fail-fast: true + - name: Composer normalize + run: composer-normalize --dry-run + + composer-require-checker: + name: Composer require checker + runs-on: "ubuntu-latest" + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: none + tools: composer-require-checker + env: + fail-fast: true + - name: Get composer cache directory + id: composer-cache + shell: bash + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install project dependencies + run: composer upgrade --no-interaction --no-progress --prefer-dist + - name: Composer require checker + run: composer-require-checker + phpcs: name: Code style (phpcs) runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.4' coverage: none tools: cs2pr, phpcs env: @@ -35,11 +81,11 @@ jobs: runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.4' coverage: none tools: cs2pr, php-cs-fixer env: @@ -52,11 +98,11 @@ jobs: runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.4' coverage: none tools: composer:v2, phpstan env: @@ -66,7 +112,7 @@ jobs: shell: bash run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -77,35 +123,25 @@ jobs: run: phpstan analyse --no-progress --verbose tests: - name: PHP ${{ matrix.php-versions }} on ${{ matrix.operating-systems }} - runs-on: ${{ matrix.operating-systems }} + name: PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} strategy: matrix: - operating-systems: ["windows-latest", "ubuntu-latest"] - php-versions: ['8.0', '8.1', '8.2'] + operating-system: ["windows-latest", "ubuntu-latest"] + php-version: ['8.2', '8.3', '8.4'] steps: - name: Checkout - uses: actions/checkout@v3 - - name: Setup PHP on Linux - if: matrix.operating-systems == 'ubuntu-latest' - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - coverage: none - tools: composer:v2 - env: - fail-fast: true - - name: Setup PHP on Windows - if: matrix.operating-systems == 'windows-latest' + uses: actions/checkout@v4 + - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php-versions }} + php-version: ${{ matrix.php-version }} coverage: none tools: composer:v2 env: fail-fast: true - name: Install poppler-utils - if: matrix.operating-systems == 'ubuntu-latest' + if: matrix.operating-system == 'ubuntu-latest' run: | sudo apt-get update -y -qq sudo apt-get install -y poppler-utils @@ -114,7 +150,7 @@ jobs: shell: bash run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -122,4 +158,4 @@ jobs: - name: Install project dependencies run: composer upgrade --no-interaction --no-progress --prefer-dist - name: Tests (phpunit) - run: vendor/bin/phpunit --testdox --verbose + run: vendor/bin/phpunit --testdox diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml deleted file mode 100644 index 574ad48..0000000 --- a/.github/workflows/sonarcloud.yml +++ /dev/null @@ -1,113 +0,0 @@ -name: sonarcloud -on: - workflow_dispatch: - push: - branches: [ "main" ] - -# Actions -# shivammathur/setup-php@v2 https://github.com/marketplace/actions/setup-php-action -# sonarsource/sonarcloud-github-action@master https://github.com/marketplace/actions/sonarcloud-scan - -jobs: - - tests-coverage: - name: Build code coverage - runs-on: "ubuntu-latest" - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - coverage: xdebug - tools: composer:v2 - env: - fail-fast: true - - name: Install poppler-utils - run: | - sudo apt-get update -y -qq - sudo apt-get install -y poppler-utils - - name: Get composer cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install project dependencies - run: composer upgrade --no-interaction --no-progress --prefer-dist - - name: Create code coverage - run: vendor/bin/phpunit --testdox --verbose --coverage-xml=build/coverage --coverage-clover=build/coverage/clover.xml --log-junit=build/coverage/junit.xml - - name: Store code coverage - uses: actions/upload-artifact@v3 - with: - name: code-coverage - path: build/coverage - - sonarcloud-secrets: - name: SonarCloud check secrets are present - runs-on: ubuntu-latest - outputs: - github: ${{ steps.check-secrets.outputs.github }} - sonar: ${{ steps.check-secrets.outputs.sonar }} - steps: - - name: Check secrets are present - id: check-secrets - run: | - if [ -n "${{ secrets.GITHUB_TOKEN }}" ]; then - echo "github=yes" >> $GITHUB_OUTPUT - else - echo "github=no" >> $GITHUB_OUTPUT - echo "::warning ::GITHUB_TOKEN non set" - fi - if [ -n "${{ secrets.SONAR_TOKEN }}" ]; then - echo "sonar=yes" >> $GITHUB_OUTPUT - else - echo "sonar=no" >> $GITHUB_OUTPUT - echo "::warning ::SONAR_TOKEN non set" - fi - - sonarcloud: - name: SonarCloud Scan and Report - needs: [ "tests-coverage", "sonarcloud-secrets" ] - if: ${{ needs.sonarcloud-secrets.outputs.github == 'yes' && needs.sonarcloud-secrets.outputs.sonar == 'yes' }} - runs-on: "ubuntu-latest" - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Unshallow clone to provide blame information - run: git fetch --unshallow - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - coverage: none - tools: composer:v2 - - name: Get composer cache directory - id: composer-cache - run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install project dependencies - run: composer upgrade --no-interaction --no-progress --prefer-dist - - name: Obtain code coverage - uses: actions/download-artifact@v3 - with: - name: code-coverage - path: build/coverage - - name: Prepare SonarCloud Code Coverage Files - run: | - sed 's#'$GITHUB_WORKSPACE'#/github/workspace#g' build/coverage/junit.xml > build/sonar-junit.xml - sed 's#'$GITHUB_WORKSPACE'#/github/workspace#g' build/coverage/clover.xml > build/sonar-coverage.xml - - name: SonarCloud Scan - uses: sonarsource/sonarcloud-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/sonarqube-cloud.yml b/.github/workflows/sonarqube-cloud.yml new file mode 100644 index 0000000..9abdcbf --- /dev/null +++ b/.github/workflows/sonarqube-cloud.yml @@ -0,0 +1,57 @@ +name: "SonarQube Cloud" +on: + workflow_dispatch: + push: + branches: [ "main" ] + +# Actions +# shivammathur/setup-php@v2 https://github.com/marketplace/actions/setup-php-action +# SonarSource/sonarqube-scan-action@v6 https://github.com/marketplace/actions/official-sonarqube-scan + +jobs: + + sonarqube-cloud: + name: SonarCloud Scan and Report + runs-on: "ubuntu-latest" + steps: + - name: Check SONAR_TOKEN secret + run: | + if [ -z "${{ secrets.SONAR_TOKEN }}" ]; then + echo "::warning ::SONAR_TOKEN non set" + exit 1 + fi + - name: Checkout + uses: actions/checkout@v4 + - name: Unshallow clone to provide blame information + run: git fetch --unshallow + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: xdebug + tools: composer:v2 + - name: Install poppler-utils + run: | + sudo apt-get update -y -qq + sudo apt-get install -y poppler-utils + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install project dependencies + run: composer upgrade --no-interaction --no-progress --prefer-dist + - name: Create code coverage + run: vendor/bin/phpunit --testdox --coverage-xml=build/coverage --coverage-clover=build/coverage/clover.xml --log-junit=build/coverage/junit.xml + - name: Prepare SonarCloud Code Coverage Files + run: | + sed 's#'$GITHUB_WORKSPACE'#/github/workspace#g' build/coverage/junit.xml > build/sonar-junit.xml + sed 's#'$GITHUB_WORKSPACE'#/github/workspace#g' build/coverage/clover.xml > build/sonar-coverage.xml + - name: SonarCloud Scan + uses: SonarSource/sonarqube-scan-action@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.phive/phars.xml b/.phive/phars.xml index f334cd6..f95968a 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -1,8 +1,9 @@ - - - - - + + + + + + diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 6c84854..712e3dc 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -15,15 +15,16 @@ ->setRules([ '@PSR12' => true, '@PSR12:risky' => true, - '@PHP80Migration' => true, - '@PHP80Migration:risky' => true, + '@PHP8x2Migration' => true, + '@PHP8x2Migration:risky' => true, // symfony + 'array_indentation' => true, 'class_attributes_separation' => true, 'whitespace_after_comma_in_array' => true, 'no_empty_statement' => true, 'no_extra_blank_lines' => true, 'type_declaration_spaces' => true, - 'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['arrays']], + 'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['array_destructuring', 'arrays', 'match', 'arguments', 'parameters']], 'no_blank_lines_after_phpdoc' => true, 'object_operator_without_whitespace' => true, 'binary_operator_spaces' => true, @@ -36,6 +37,8 @@ 'standardize_not_equals' => true, 'concat_space' => ['spacing' => 'one'], 'linebreak_after_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'global_namespace_import' => ['import_classes' => true], // symfony:risky 'no_alias_functions' => true, 'self_accessor' => true, @@ -47,6 +50,6 @@ PhpCsFixer\Finder::create() ->in(__DIR__) ->append([__FILE__]) - ->exclude(['tools', 'vendor', 'build']) + ->exclude(['tools', 'vendor', 'build']), ) ; diff --git a/LICENCE b/LICENCE index 1791339..84985b8 100644 --- a/LICENCE +++ b/LICENCE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2022 - 2024 PhpCfdi https://www.phpcfdi.com/ +Copyright (c) 2022 - 2025 PhpCfdi https://www.phpcfdi.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 43c7345..e5e7a37 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,6 @@ and licensed for use under the MIT License (MIT). Please see [LICENSE][] for mor [badge-build]: https://img.shields.io/github/actions/workflow/status/phpcfdi/csf-scraper/build.yml?branch=main&logo=github-actions [badge-reliability]: https://sonarcloud.io/api/project_badges/measure?project=phpcfdi_csf-scraper&metric=reliability_rating [badge-maintainability]: https://sonarcloud.io/api/project_badges/measure?project=phpcfdi_csf-scraper&metric=sqale_rating -[badge-coverage]: https://img.shields.io/sonar/coverage/phpcfdi_csf-scraper/main?logo=sonarcloud&server=https%3A%2F%2Fsonarcloud.io -[badge-violations]: https://img.shields.io/sonar/violations/phpcfdi_csf-scraper/main?format=long&logo=sonarcloud&server=https%3A%2F%2Fsonarcloud.io +[badge-coverage]: https://img.shields.io/sonar/coverage/phpcfdi_csf-scraper/main?logo=sonarqubecloud&server=https%3A%2F%2Fsonarcloud.io +[badge-violations]: https://img.shields.io/sonar/violations/phpcfdi_csf-scraper/main?format=long&logo=sonarqubecloud&server=https%3A%2F%2Fsonarcloud.io [badge-downloads]: https://img.shields.io/packagist/dt/phpcfdi/csf-scraper.svg?logo=packagist diff --git a/composer.json b/composer.json index 22d1935..3479612 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,13 @@ { "name": "phpcfdi/csf-scraper", "description": "Obtiene los datos fiscales actuales de una persona moral o física dado su RFC y CIFID", - "keywords": ["phpcfdi", "sat", "csf"], - "homepage": "https://github.com/phpcfdi/csf-scraper", - "type": "library", "license": "MIT", + "type": "library", + "keywords": [ + "phpcfdi", + "sat", + "csf" + ], "authors": [ { "name": "Cesar Aguilera", @@ -19,31 +22,27 @@ "email": "fernando.isidro@ocelotlstudio.com" } ], + "homepage": "https://github.com/phpcfdi/csf-scraper", "support": { - "source": "https://github.com/phpcfdi/csf-scraper", - "issues": "https://github.com/phpcfdi/csf-scraper/issues" - }, - "prefer-stable": true, - "config": { - "optimize-autoloader": true, - "preferred-install": { - "*": "dist" - } + "issues": "https://github.com/phpcfdi/csf-scraper/issues", + "source": "https://github.com/phpcfdi/csf-scraper" }, "require": { - "php": ">=8.0", - "ext-mbstring": "*", - "ext-json": "*", + "php": ">=8.2", "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", "guzzlehttp/guzzle": "^7.4", "phpcfdi/rfc": "^1.1", - "symfony/css-selector": ">=6.0", - "symfony/dom-crawler": ">=6.0", - "symfony/process": ">=6.0" + "psr/http-client": "^1.0", + "symfony/css-selector": "^7.0", + "symfony/dom-crawler": "^7.0", + "symfony/process": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^11.5" }, + "prefer-stable": true, "autoload": { "psr-4": { "PhpCfdi\\CsfScraper\\": "src/" @@ -54,31 +53,42 @@ "PhpCfdi\\CsfScraper\\Tests\\": "tests/" } }, + "config": { + "optimize-autoloader": true, + "preferred-install": { + "*": "dist" + } + }, "scripts": { - "dev:build": ["@dev:fix-style", "@dev:test"], + "dev:build": [ + "@dev:fix-style", + "@dev:test" + ], "dev:check-style": [ + "@php tools/composer-normalize normalize --dry-run", "@php tools/php-cs-fixer fix --dry-run --verbose", "@php tools/phpcs --colors -sp src/ tests/" ], + "dev:coverage": [ + "@php -dzend_extension=xdebug.so -dxdebug.mode=coverage vendor/bin/phpunit --coverage-html build/coverage/html/" + ], "dev:fix-style": [ + "@php tools/composer-normalize normalize", "@php tools/php-cs-fixer fix --verbose", "@php tools/phpcbf --colors -sp src/ tests/" ], "dev:test": [ "@dev:check-style", - "@php vendor/bin/phpunit --testdox --verbose --stop-on-failure", + "@php vendor/bin/phpunit --testdox --stop-on-failure", "@php tools/phpstan analyse --no-interaction --no-progress", "@php tools/composer-require-checker" - ], - "dev:coverage": [ - "@php -dzend_extension=xdebug.so -dxdebug.mode=coverage vendor/bin/phpunit --coverage-html build/coverage/html/" ] }, "scripts-descriptions": { "dev:build": "DEV: run dev:fix-style and dev:tests, run before pull request", - "dev:check-style": "DEV: search for code style errors using php-cs-fixer and phpcs", - "dev:fix-style": "DEV: fix code style errors using php-cs-fixer and phpcbf", - "dev:test": "DEV: run @dev:check-style, phpunit and phpstan", - "dev:coverage": "DEV: run phpunit with xdebug and storage coverage in build/coverage/html/" + "dev:check-style": "DEV: search for code style errors using composer-normalize, php-cs-fixer and phpcs", + "dev:coverage": "DEV: run phpunit with xdebug and storage coverage in build/coverage/html/", + "dev:fix-style": "DEV: fix code style errors using composer-normalize, php-cs-fixer and phpcbf", + "dev:test": "DEV: run @dev:check-style, phpunit and phpstan" } } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index cc2279f..4c8f56d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,36 @@ versión, aunque sí su incorporación en la rama principal de trabajo, generalm ## Listado de cambios +### Versión 0.2.0 2025-11-10 + +- Se asegura la compatibilidad con PHP 8.3 y PHP 8.4. +- Se elimina la compatibilidad con PHP 8.0 y PHP 8.1. +- Se actualiza el año de la licencia a 2025. +- No se estaban capturando correctamente las extensiones al intentar descargar la información de identificación fiscal, + se estaba atrapando la excepción `GuzzleHttp\Exception\GuzzleException` en lugar de la excepción estándar + `Psr\Http\Client\ClientExceptionInterface`. + +Cambios al entorno de desarrollo: + +- Se corrige la integración con SonarQube Cloud. +- Se actualiza a PHPUnit 11.5. +- Se actualizan las configuraciones de estándar de código para `phpcs` y `php-cs-fixer`. +- Se agrega `composer-normalize` a las herramientas de desarrollo. +- En los flujos de trabajo: + - Se ejecutan los trabajos en PHP 8.4. + - Se agrega PHP 8.3 y PHP 8.4 a la matriz de pruebas. + - Se agrega el trabajo `composer-normalize`. + - Se ejecutan las acciones en la versión 4. + - Se usa la variable `php-version` en singular en la matriz de pruebas. + - Se usa la variable `operating-system` en singular en la matriz de pruebas. + - Se usa una única configuración para Linux o Windows al configurar PHP. +- Se actualizan las herramientas de desarrollo. + +#### Mantenimiento 2023-06-17 + +- Se agrega un último test para alcanzar el 100% de cobertura de código. +- Se corrige en este archivo, que "los flujos de trabajo corren en PHP 8.2", decía "PHP 8.0". + ### Versión 0.1.7 2024-01-10 - Se arregla el problema para CSF que traen localidad en lugar de colonia. Agradecimientos a @luffynando, @blacktrue y @eclipxe13 por sus aportes. @@ -29,7 +59,7 @@ versión, aunque sí su incorporación en la rama principal de trabajo, generalm - Se actualiza el archivo de configuración de SonarCloud para excluir correctamente los archivos en `tests/_files`. - Para los flujos de trabajo: - Se permite ejecutarlos a petición. - - Los trabajos se ejecutan en PHP 8.0. + - Los trabajos se ejecutan en PHP 8.2. - No se instala `composer` cuando no es necesario. - Se sustituye la directiva `::set-output` con `$GITHUB_OUTPUT`. - Se actualizan las herramientas de desarrollo. diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 422820a..4316cec 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -18,7 +18,6 @@ - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ab9a195..f28de6a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,16 +1,22 @@ + xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" + cacheDirectory="build/phpunit" + bootstrap="tests/bootstrap.php" + colors="true" + displayDetailsOnAllIssues="true" +> + + + + src + + + - - ./tests/ + + tests - - - ./src/ - - + diff --git a/src/DataExtractor.php b/src/DataExtractor.php index 876cec0..b47b591 100644 --- a/src/DataExtractor.php +++ b/src/DataExtractor.php @@ -9,15 +9,13 @@ use RuntimeException; use Symfony\Component\DomCrawler\Crawler; -final class DataExtractor implements DataExtractorInterface +final readonly class DataExtractor implements DataExtractorInterface { public function __construct(private string $html) { } - /** - * @throws CifNotFoundException - */ + /** @throws CifNotFoundException */ public function extract(bool $isFisica): PersonaMoral|PersonaFisica { $html = $this->clearHtml($this->html); @@ -43,12 +41,12 @@ public function extract(bool $isFisica): PersonaMoral|PersonaFisica private function getValueByTdTitleText(Crawler $crawler, string $valueToSearch): string { - $element = $crawler->filterXPath("//td[@role='gridcell']/span[contains(normalize-space(.), '{$valueToSearch}')]"); + $element = $crawler->filterXPath("//td[@role='gridcell']/span[contains(normalize-space(.), '$valueToSearch')]"); $node = $element->getNode(0); if (null === $node) { return ''; } - return trim(str_replace($valueToSearch, ' ', $this->normalizeWhiteSpaces($node->parentNode?->parentNode?->textContent ?? ''))); + return trim(str_replace($valueToSearch, ' ', $this->normalizeWhiteSpaces($node->parentNode->parentNode->textContent ?? ''))); } private function normalizeWhiteSpaces(string $str): string @@ -62,7 +60,6 @@ private function clearHtml(string $html): string } /** - * * @return Regimen[] * @throws RuntimeException */ diff --git a/src/Exceptions/CifDownloadException.php b/src/Exceptions/CifDownloadException.php index 153b283..c1f3e93 100644 --- a/src/Exceptions/CifDownloadException.php +++ b/src/Exceptions/CifDownloadException.php @@ -9,7 +9,7 @@ final class CifDownloadException extends RuntimeException implements CsfScraperException { - public function __construct(private string $url, Throwable $previous) + public function __construct(private readonly string $url, Throwable $previous) { parent::__construct('The request has failed', previous: $previous); } diff --git a/src/Exceptions/PdfReader/PdfToTextConvertException.php b/src/Exceptions/PdfReader/PdfToTextConvertException.php index 8f0c765..7424642 100644 --- a/src/Exceptions/PdfReader/PdfToTextConvertException.php +++ b/src/Exceptions/PdfReader/PdfToTextConvertException.php @@ -9,15 +9,13 @@ final class PdfToTextConvertException extends RuntimeException implements CsfScraperException { - /** - * @param string[] $command - */ + /** @param string[] $command */ public function __construct( string $message, - private array $command, - private int $exitCode, - private string $output, - private string $error, + private readonly array $command, + private readonly int $exitCode, + private readonly string $output, + private readonly string $error, ) { parent::__construct($message); } diff --git a/src/Interfaces/ScraperInterface.php b/src/Interfaces/ScraperInterface.php index 733e306..a63684f 100644 --- a/src/Interfaces/ScraperInterface.php +++ b/src/Interfaces/ScraperInterface.php @@ -10,10 +10,7 @@ interface ScraperInterface { - /** - * Obtain a PersonaMoral or PersonaFisica object with the information from SAT website - * - */ + /** Obtain a PersonaMoral or PersonaFisica object with the information from SAT website */ public function obtainFromRfcAndCif(Rfc $rfc, string $idCIF): PersonaMoral|PersonaFisica; /** diff --git a/src/PdfReader/CsfExtractor.php b/src/PdfReader/CsfExtractor.php index 905a5ca..6edc146 100644 --- a/src/PdfReader/CsfExtractor.php +++ b/src/PdfReader/CsfExtractor.php @@ -6,23 +6,16 @@ use PhpCfdi\CsfScraper\Exceptions\PdfReader\EmptyPdfContentException; -/** - * - * @internal - */ -final class CsfExtractor +/** @internal */ +final readonly class CsfExtractor { - /** - * @var string[] - */ + /** @var list */ private array $lines; - /** - * @throws EmptyPdfContentException - */ + /** @throws EmptyPdfContentException */ public function __construct(string $contents) { - if ('' == $contents) { + if ('' === $contents) { throw new EmptyPdfContentException('Cannot read pdf contents.'); } $this->lines = explode("\n", $contents); diff --git a/src/PdfReader/PdfToText.php b/src/PdfReader/PdfToText.php index 9daad4a..debc891 100644 --- a/src/PdfReader/PdfToText.php +++ b/src/PdfReader/PdfToText.php @@ -10,7 +10,7 @@ /** * Extract the contents of a pdf file using pdftotext (apt-get install poppler-utils) */ -final class PdfToText +final readonly class PdfToText { private string $pdftotext; @@ -37,15 +37,13 @@ public function extract(string $path): string $command, $exitCode, $process->getOutput(), - $process->getErrorOutput() + $process->getErrorOutput(), ); } return $process->getOutput(); } - /** - * @return string[] - */ + /** @return list */ public function buildCommand(string $pdfFile): array { return [$this->pdftotext, '-eol', 'unix', '-raw', '-q', $pdfFile, '-']; diff --git a/src/Persona.php b/src/Persona.php index a243446..19cef1b 100644 --- a/src/Persona.php +++ b/src/Persona.php @@ -39,7 +39,7 @@ abstract class Persona implements JsonSerializable private string $al = ''; - private Regimenes $regimenes; + private readonly Regimenes $regimenes; /** @var mixed[] */ private array $data = []; @@ -212,7 +212,7 @@ public function addRegimenes(Regimen ...$regimenes): void } /** - * The values must be a simple text to search using xpath as in contains(normalize-space(.), {value})' + * The values must be a simple text to search using xpath as in 'contains(normalize-space(.), {value})' * @return array */ abstract public function getTdTitlesTextToSearch(): array; diff --git a/src/PersonaFisica.php b/src/PersonaFisica.php index ac3ef26..1822eba 100644 --- a/src/PersonaFisica.php +++ b/src/PersonaFisica.php @@ -69,10 +69,7 @@ public function setFechaNacimiento(string $fechaNacimiento): void $this->fechaNacimiento = false !== $date ? $date : null; } - /** - * - * @return array - */ + /** @return array */ public function getTdTitlesTextToSearch(): array { return [ diff --git a/src/PersonaMoral.php b/src/PersonaMoral.php index 817e945..e340004 100644 --- a/src/PersonaMoral.php +++ b/src/PersonaMoral.php @@ -45,10 +45,7 @@ public function setFechaConstitucion(string $fechaConstitucion): void $this->fechaConstitucion = false !== $date ? $date : null; } - /** - * - * @return array - */ + /** @return array */ public function getTdTitlesTextToSearch(): array { return [ diff --git a/src/Regimen.php b/src/Regimen.php index 0537a3a..9d42650 100644 --- a/src/Regimen.php +++ b/src/Regimen.php @@ -15,10 +15,7 @@ class Regimen implements JsonSerializable private ?DateTimeImmutable $fechaAlta = null; - /** - * - * @var array - */ + /** @var list */ private array $regimenes = [ [ 'id' => '601', @@ -137,9 +134,7 @@ private function searchRegimenIdByText(string $text): string return ''; } - /** - * @return array{regimen: string, regimen_id: string, fecha_alta: ?DateTimeImmutable} - */ + /** @return array{regimen: string, regimen_id: string, fecha_alta: ?DateTimeImmutable} */ public function toArray(): array { return [ diff --git a/src/Regimenes.php b/src/Regimenes.php index e429cc1..d8b9854 100644 --- a/src/Regimenes.php +++ b/src/Regimenes.php @@ -9,15 +9,10 @@ class Regimenes implements JsonSerializable { - /** - * @var Regimen[] - */ + /** @var list */ private array $regimenes = []; - /** - * - * @return Regimen[] - */ + /** @return list */ public function getRegimenes(): array { return $this->regimenes; @@ -31,14 +26,12 @@ public function addRegimen(Regimen $regimen, Regimen ...$regimenes): void } } - /** - * @return array - */ + /** @return list */ public function toArray(): array { return array_map( fn (Regimen $regimen): array => $regimen->toArray(), - $this->regimenes + $this->regimenes, ); } diff --git a/src/Scraper.php b/src/Scraper.php index 528890f..8d28be3 100644 --- a/src/Scraper.php +++ b/src/Scraper.php @@ -6,7 +6,6 @@ use GuzzleHttp\Client; use GuzzleHttp\ClientInterface; -use GuzzleHttp\Exception\GuzzleException; use PhpCfdi\CsfScraper\Exceptions\PdfReader\CifFromPdfNotFoundException; use PhpCfdi\CsfScraper\Exceptions\PdfReader\RfcFromPdfNotFoundException; use PhpCfdi\CsfScraper\Interfaces\ScraperInterface; @@ -14,6 +13,7 @@ use PhpCfdi\CsfScraper\PdfReader\PdfToText; use PhpCfdi\Rfc\Exceptions\InvalidExpressionToParseException; use PhpCfdi\Rfc\Rfc; +use Psr\Http\Client\ClientExceptionInterface; /** * Main class to obtain the data from a "Persona Moral" or a "Persona Física" from SAT website @@ -22,7 +22,7 @@ class Scraper implements ScraperInterface { public static string $url = 'https://siat.sat.gob.mx/app/qr/faces/pages/mobile/validadorqr.jsf?D1=10&D2=1&D3=%s_%s'; - public function __construct(private ClientInterface $client) + public function __construct(private readonly ClientInterface $client) { } @@ -49,7 +49,7 @@ public static function create(): self */ public function obtainFromRfcAndCif(Rfc $rfc, string $idCIF): PersonaMoral|PersonaFisica { - $uri = sprintf(self::$url, $idCIF, $rfc->getRfc()); + $uri = sprintf(static::$url, $idCIF, $rfc->getRfc()); $html = $this->obtainHtml($uri); $person = (new DataExtractor($html))->extract($rfc->isFisica()); $person->setRfc($rfc->getRfc()); @@ -61,12 +61,11 @@ public function obtainFromRfcAndCif(Rfc $rfc, string $idCIF): PersonaMoral|Perso * Obtain a PersonaMoral or PersonaFisica object with the information from SAT website * The RFC and CIF is taken from the "Constancia de Situación Fiscal" PDF file * - * @param string $path - * @return PersonaMoral|PersonaFisica + * @throws Exceptions\CifDownloadException * @throws Exceptions\CifNotFoundException - * @throws Exceptions\PdfReader\CifFromPdfNotFoundException + * @throws CifFromPdfNotFoundException * @throws Exceptions\PdfReader\EmptyPdfContentException - * @throws Exceptions\PdfReader\RfcFromPdfNotFoundException + * @throws RfcFromPdfNotFoundException * @throws InvalidExpressionToParseException */ public function obtainFromPdfPath(string $path): PersonaMoral|PersonaFisica @@ -88,8 +87,6 @@ public function obtainFromPdfPath(string $path): PersonaMoral|PersonaFisica /** * Helper method to extract the text information from PDF to plain text * - * @param string $path - * @return string * @throws Exceptions\PdfReader\PdfToTextConvertException when call to pdftotext fail */ protected function pdfToTextContent(string $path): string @@ -106,10 +103,10 @@ protected function pdfToTextContent(string $path): string protected function obtainHtml(string $uri): string { try { - $request = $this->client->request('GET', $uri); - } catch (GuzzleException $exception) { + $response = $this->client->request('GET', $uri); + } catch (ClientExceptionInterface $exception) { throw new Exceptions\CifDownloadException($uri, $exception); } - return (string) $request->getBody(); + return (string) $response->getBody(); } } diff --git a/tests/Integration/ScrapFromCsfFileTest.php b/tests/Integration/ScrapFromCsfFileTest.php index 11a081a..a363dee 100644 --- a/tests/Integration/ScrapFromCsfFileTest.php +++ b/tests/Integration/ScrapFromCsfFileTest.php @@ -9,11 +9,13 @@ use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\Psr7\Response; use PhpCfdi\CsfScraper\Exceptions\CifDownloadException; +use PhpCfdi\CsfScraper\Exceptions\CifNotFoundException; use PhpCfdi\CsfScraper\Exceptions\PdfReader\CifFromPdfNotFoundException; use PhpCfdi\CsfScraper\Exceptions\PdfReader\RfcFromPdfNotFoundException; use PhpCfdi\CsfScraper\Scraper; use PhpCfdi\CsfScraper\Tests\Integration\Helpers\ScraperHelper; use PhpCfdi\CsfScraper\Tests\TestCase; +use PHPUnit\Framework\Attributes\RequiresOperatingSystem; class ScrapFromCsfFileTest extends TestCase { @@ -68,36 +70,43 @@ public function test_scrap_from_idcif_and_rfc_by_moral(): void $this->assertEquals($expectedData, $data); } - /** - * @requires OSFAMILY Linux - */ + public function test_obtain_from_pdf_with_invalid_url(): void + { + $previousUrl = Scraper::$url; + Scraper::$url = str_replace('siat.sat.gob.mx', 'sat.gob.mx', $previousUrl); + + try { + $csfScrap = Scraper::create(); + $this->expectException(CifDownloadException::class); + $csfScrap->obtainFromPdfPath($this->filePath('csf-correct-but-invalid.pdf')); + } finally { + Scraper::$url = $previousUrl; + } + } + public function test_obtain_from_pdf_with_invalid_data(): void { - $csfScrap = new Scraper(new Client()); + $csfScrap = Scraper::create(); - $this->expectException(CifDownloadException::class); + $this->expectException(CifNotFoundException::class); $csfScrap->obtainFromPdfPath($this->filePath('csf-correct-but-invalid.pdf')); } - /** - * @requires OSFAMILY Linux - */ + #[RequiresOperatingSystem('Linux')] public function test_obtain_from_pdf_without_rfc(): void { - $csfScrap = new Scraper(new Client()); + $csfScrap = Scraper::create(); $this->expectException(RfcFromPdfNotFoundException::class); $csfScrap->obtainFromPdfPath($this->filePath('csf-without-rfc.pdf')); } - /** - * @requires OSFAMILY Linux - */ + #[RequiresOperatingSystem('Linux')] public function test_obtain_from_pdf_without_cif(): void { - $csfScrap = new Scraper(new Client()); + $csfScrap = Scraper::create(); $this->expectException(CifFromPdfNotFoundException::class); diff --git a/tests/Unit/Exceptions/CifDownloadExceptionTest.php b/tests/Unit/Exceptions/CifDownloadExceptionTest.php index ce7b670..1292371 100644 --- a/tests/Unit/Exceptions/CifDownloadExceptionTest.php +++ b/tests/Unit/Exceptions/CifDownloadExceptionTest.php @@ -13,6 +13,7 @@ final class CifDownloadExceptionTest extends TestCase { public function test_implements_library_exception_type(): void { + /** @phpstan-ignore function.alreadyNarrowedType */ $this->assertTrue(is_a(CifDownloadException::class, CsfScraperException::class, true)); } diff --git a/tests/Unit/Exceptions/CifNotFoundExceptionTest.php b/tests/Unit/Exceptions/CifNotFoundExceptionTest.php index bd5f323..a552ce8 100644 --- a/tests/Unit/Exceptions/CifNotFoundExceptionTest.php +++ b/tests/Unit/Exceptions/CifNotFoundExceptionTest.php @@ -12,6 +12,7 @@ final class CifNotFoundExceptionTest extends TestCase { public function test_implements_library_exception_type(): void { + /** @phpstan-ignore function.alreadyNarrowedType */ $this->assertTrue(is_a(CifNotFoundException::class, CsfScraperException::class, true)); } } diff --git a/tests/Unit/Exceptions/PdfReader/CifFromPdfNotFoundExceptionTest.php b/tests/Unit/Exceptions/PdfReader/CifFromPdfNotFoundExceptionTest.php index 81bb9c4..0e7eafb 100644 --- a/tests/Unit/Exceptions/PdfReader/CifFromPdfNotFoundExceptionTest.php +++ b/tests/Unit/Exceptions/PdfReader/CifFromPdfNotFoundExceptionTest.php @@ -12,6 +12,7 @@ final class CifFromPdfNotFoundExceptionTest extends TestCase { public function test_implements_library_exception_type(): void { + /** @phpstan-ignore function.alreadyNarrowedType */ $this->assertTrue(is_a(CifFromPdfNotFoundException::class, CsfScraperException::class, true)); } } diff --git a/tests/Unit/Exceptions/PdfReader/EmptyPdfContentExceptionTest.php b/tests/Unit/Exceptions/PdfReader/EmptyPdfContentExceptionTest.php index aaa4172..f297f56 100644 --- a/tests/Unit/Exceptions/PdfReader/EmptyPdfContentExceptionTest.php +++ b/tests/Unit/Exceptions/PdfReader/EmptyPdfContentExceptionTest.php @@ -12,6 +12,7 @@ final class EmptyPdfContentExceptionTest extends TestCase { public function test_implements_library_exception_type(): void { + /** @phpstan-ignore function.alreadyNarrowedType */ $this->assertTrue(is_a(EmptyPdfContentException::class, CsfScraperException::class, true)); } } diff --git a/tests/Unit/Exceptions/PdfReader/PdfToTextConvertExceptionTest.php b/tests/Unit/Exceptions/PdfReader/PdfToTextConvertExceptionTest.php index 73e8abe..05ba22b 100644 --- a/tests/Unit/Exceptions/PdfReader/PdfToTextConvertExceptionTest.php +++ b/tests/Unit/Exceptions/PdfReader/PdfToTextConvertExceptionTest.php @@ -12,6 +12,7 @@ final class PdfToTextConvertExceptionTest extends TestCase { public function test_implements_library_exception_type(): void { + /** @phpstan-ignore function.alreadyNarrowedType */ $this->assertTrue(is_a(PdfToTextConvertException::class, CsfScraperException::class, true)); } diff --git a/tests/Unit/Exceptions/PdfReader/RfcFromPdfNotFoundExceptionTest.php b/tests/Unit/Exceptions/PdfReader/RfcFromPdfNotFoundExceptionTest.php index b6a8bb9..99563f5 100644 --- a/tests/Unit/Exceptions/PdfReader/RfcFromPdfNotFoundExceptionTest.php +++ b/tests/Unit/Exceptions/PdfReader/RfcFromPdfNotFoundExceptionTest.php @@ -12,6 +12,7 @@ final class RfcFromPdfNotFoundExceptionTest extends TestCase { public function test_implements_library_exception_type(): void { + /** @phpstan-ignore function.alreadyNarrowedType */ $this->assertTrue(is_a(RfcFromPdfNotFoundException::class, CsfScraperException::class, true)); } } diff --git a/tests/Unit/PdfReader/CsfExtractor/GetRfcTest.php b/tests/Unit/PdfReader/CsfExtractor/GetRfcTest.php index 770cf0b..4e85641 100644 --- a/tests/Unit/PdfReader/CsfExtractor/GetRfcTest.php +++ b/tests/Unit/PdfReader/CsfExtractor/GetRfcTest.php @@ -7,6 +7,7 @@ use PhpCfdi\CsfScraper\Exceptions\PdfReader\EmptyPdfContentException; use PhpCfdi\CsfScraper\PdfReader\CsfExtractor; use PhpCfdi\CsfScraper\Tests\TestCase; +use PHPUnit\Framework\Attributes\RequiresOperatingSystem; class GetRfcTest extends TestCase { @@ -23,9 +24,7 @@ public function test_bad_content_returns_empty_rfc(): void $this->assertNull($rfc); } - /** - * @requires OSFAMILY Linux - */ + #[RequiresOperatingSystem('Linux')] public function test_cannot_read_content(): void { $this->expectException(EmptyPdfContentException::class); diff --git a/tests/Unit/PdfReader/PdfToText/PdfToTextConstructorTest.php b/tests/Unit/PdfReader/PdfToText/PdfToTextConstructorTest.php index 7a8038a..f70dd0c 100644 --- a/tests/Unit/PdfReader/PdfToText/PdfToTextConstructorTest.php +++ b/tests/Unit/PdfReader/PdfToText/PdfToTextConstructorTest.php @@ -6,13 +6,12 @@ use PhpCfdi\CsfScraper\PdfReader\PdfToText; use PhpCfdi\CsfScraper\Tests\TestCase; +use PHPUnit\Framework\Attributes\RequiresOperatingSystem; use RuntimeException; class PdfToTextConstructorTest extends TestCase { - /** - * @requires OSFAMILY Linux - */ + #[RequiresOperatingSystem('Linux')] public function test_pdftotext_is_installed_default_path(): void { $csfExtractor = new PdfToText(); diff --git a/tests/Unit/Persona/CommonPersonaPropertiesTest.php b/tests/Unit/Persona/CommonPersonaPropertiesTest.php index c883a27..fc53bd3 100644 --- a/tests/Unit/Persona/CommonPersonaPropertiesTest.php +++ b/tests/Unit/Persona/CommonPersonaPropertiesTest.php @@ -8,6 +8,7 @@ use PhpCfdi\CsfScraper\PersonaMoral; use PhpCfdi\CsfScraper\Tests\TestCase; use PhpCfdi\CsfScraper\Tests\Unit\Persona\Traits\PersonaTrait; +use PHPUnit\Framework\Attributes\DataProvider; class CommonPersonaPropertiesTest extends TestCase { @@ -21,11 +22,8 @@ public function setUp(): void $this->person = new PersonaMoral(); } - /** - * - * @return array> - */ - public function datePropertiesProvider(): array + /** @return array> */ + public static function datePropertiesProvider(): array { return [ ['FechaInicioOperaciones', '12-01-2017'], @@ -33,11 +31,8 @@ public function datePropertiesProvider(): array ]; } - /** - * - * @return array> - */ - public function stringPropertiesProvider(): array + /** @return array> */ + public static function stringPropertiesProvider(): array { return [ ['SituacionContribuyente', 'ACTIVO'], @@ -54,18 +49,14 @@ public function stringPropertiesProvider(): array ]; } - /** - * @dataProvider stringPropertiesProvider - */ + #[DataProvider('stringPropertiesProvider')] public function test_set_and_get_string_properties(string $complementFunction, string $value): void { $result = $this->setAndGetProperty($complementFunction, $value); $this->assertSame($value, $result); } - /** - * @dataProvider datePropertiesProvider - */ + #[DataProvider('datePropertiesProvider')] public function test_set_and_get_date_properties(string $complementFunction, string $value): void { $result = $this->setAndGetProperty($complementFunction, $value); @@ -73,7 +64,6 @@ public function test_set_and_get_date_properties(string $complementFunction, str } /** - * * test to check if new property not contained in Persona is found is assigned and value can be retrieved * its goal is not to be used but to prevent unexpected exceptions * */ diff --git a/tests/Unit/Persona/PersonaFisicaPropertiesTest.php b/tests/Unit/Persona/PersonaFisicaPropertiesTest.php index 5761aa9..4f12ace 100644 --- a/tests/Unit/Persona/PersonaFisicaPropertiesTest.php +++ b/tests/Unit/Persona/PersonaFisicaPropertiesTest.php @@ -8,6 +8,7 @@ use PhpCfdi\CsfScraper\PersonaFisica; use PhpCfdi\CsfScraper\Tests\TestCase; use PhpCfdi\CsfScraper\Tests\Unit\Persona\Traits\PersonaTrait; +use PHPUnit\Framework\Attributes\DataProvider; class PersonaFisicaPropertiesTest extends TestCase { @@ -21,22 +22,16 @@ public function setUp(): void $this->person = new PersonaFisica(); } - /** - * - * @return array> - */ - public function datePropertiesProvider(): array + /** @return array> */ + public static function datePropertiesProvider(): array { return [ ['FechaNacimiento', '16-05-1996'], ]; } - /** - * - * @return array> - */ - public function stringPropertiesProvider(): array + /** @return array> */ + public static function stringPropertiesProvider(): array { return [ ['Curp', 'MI CURP'], @@ -46,18 +41,14 @@ public function stringPropertiesProvider(): array ]; } - /** - * @dataProvider stringPropertiesProvider - */ + #[DataProvider('stringPropertiesProvider')] public function test_set_and_get_string_properties(string $complementFunction, string $value): void { $result = $this->setAndGetProperty($complementFunction, $value); $this->assertSame($value, $result); } - /** - * @dataProvider datePropertiesProvider - */ + #[DataProvider('datePropertiesProvider')] public function test_set_and_get_date_properties(string $complementFunction, string $value): void { $result = $this->setAndGetProperty($complementFunction, $value); diff --git a/tests/Unit/Persona/PersonaJsonSerializeTest.php b/tests/Unit/Persona/PersonaJsonSerializeTest.php index 4f98130..0305a08 100644 --- a/tests/Unit/Persona/PersonaJsonSerializeTest.php +++ b/tests/Unit/Persona/PersonaJsonSerializeTest.php @@ -14,8 +14,7 @@ public function test_serialize_default_person_moral(): void { $person = new PersonaMoral(); - /** @var string $json */ - $json = json_encode($person); + $json = (string) json_encode($person); $this->assertSame([ 'razon_social' => '', @@ -45,8 +44,7 @@ public function test_serialize_default_person_fisica(): void { $person = new PersonaFisica(); - /** @var string $json */ - $json = json_encode($person); + $json = (string) json_encode($person); $this->assertSame([ 'curp' => '', diff --git a/tests/Unit/Persona/PersonaMoralPropertiesTest.php b/tests/Unit/Persona/PersonaMoralPropertiesTest.php index a49d96c..947e772 100644 --- a/tests/Unit/Persona/PersonaMoralPropertiesTest.php +++ b/tests/Unit/Persona/PersonaMoralPropertiesTest.php @@ -8,6 +8,7 @@ use PhpCfdi\CsfScraper\PersonaMoral; use PhpCfdi\CsfScraper\Tests\TestCase; use PhpCfdi\CsfScraper\Tests\Unit\Persona\Traits\PersonaTrait; +use PHPUnit\Framework\Attributes\DataProvider; class PersonaMoralPropertiesTest extends TestCase { @@ -21,22 +22,16 @@ public function setUp(): void $this->person = new PersonaMoral(); } - /** - * - * @return array> - */ - public function datePropertiesProvider(): array + /** @return array> */ + public static function datePropertiesProvider(): array { return [ ['fechaConstitucion', '16-05-1996'], ]; } - /** - * - * @return array> - */ - public function stringPropertiesProvider(): array + /** @return array> */ + public static function stringPropertiesProvider(): array { return [ ['RazonSocial', 'MI TIENDITA'], @@ -44,18 +39,14 @@ public function stringPropertiesProvider(): array ]; } - /** - * @dataProvider stringPropertiesProvider - */ + #[DataProvider('stringPropertiesProvider')] public function test_set_and_get_string_properties(string $complementFunction, string $value): void { $result = $this->setAndGetProperty($complementFunction, $value); $this->assertSame($value, $result); } - /** - * @dataProvider datePropertiesProvider - */ + #[DataProvider('datePropertiesProvider')] public function test_set_and_get_date_properties(string $complementFunction, string $value): void { $result = $this->setAndGetProperty($complementFunction, $value); diff --git a/tests/Unit/Persona/Traits/PersonaTrait.php b/tests/Unit/Persona/Traits/PersonaTrait.php index 845a710..719de8e 100644 --- a/tests/Unit/Persona/Traits/PersonaTrait.php +++ b/tests/Unit/Persona/Traits/PersonaTrait.php @@ -31,10 +31,9 @@ public function test_allows_more_than_one_regimen(): void } /** - * - * test to check if new property not contained in Persona is found is assigned and value can be retrieved - * its goal is not to be used but to prevent unexpected exceptions - * */ + * test to check if new property not contained in Persona is found is assigned and value can be retrieved + * its goal is not to be used but to prevent unexpected exceptions + */ public function test_assign_dynamic_property(): void { /** @phpstan-ignore-next-line */ diff --git a/tests/Unit/Regimen/RegimenJsonSerializeTest.php b/tests/Unit/Regimen/RegimenJsonSerializeTest.php index 6a50e55..ff4bf6c 100644 --- a/tests/Unit/Regimen/RegimenJsonSerializeTest.php +++ b/tests/Unit/Regimen/RegimenJsonSerializeTest.php @@ -13,8 +13,7 @@ public function test_serialize_default_regimen(): void { $regimen = new Regimen(); - /** @var string $json */ - $json = json_encode($regimen); + $json = (string) json_encode($regimen); $this->assertSame([ 'regimen' => '', diff --git a/tests/Unit/Regimen/RegimenesJsonSerializeTest.php b/tests/Unit/Regimen/RegimenesJsonSerializeTest.php index 96973eb..c8d7148 100644 --- a/tests/Unit/Regimen/RegimenesJsonSerializeTest.php +++ b/tests/Unit/Regimen/RegimenesJsonSerializeTest.php @@ -16,8 +16,7 @@ public function test_serialize_default_regimenes(): void $regimenes->addRegimen(new Regimen(), new Regimen()); - /** @var string $json */ - $json = json_encode($regimenes); + $json = (string) json_encode($regimenes); $this->assertSame([ [ diff --git a/tests/Unit/Regimen/SetRegimenTest.php b/tests/Unit/Regimen/SetRegimenTest.php index 5b43177..d6aae0c 100644 --- a/tests/Unit/Regimen/SetRegimenTest.php +++ b/tests/Unit/Regimen/SetRegimenTest.php @@ -6,14 +6,12 @@ use PhpCfdi\CsfScraper\Regimen; use PhpCfdi\CsfScraper\Tests\TestCase; +use PHPUnit\Framework\Attributes\DataProvider; class SetRegimenTest extends TestCase { - /** - * - * @return array> - */ - public function regimenesProvider(): array + /** @return array> */ + public static function regimenesProvider(): array { return [ ['General de Ley Personas Morales', '601'], @@ -40,7 +38,7 @@ public function regimenesProvider(): array ]; } - /** @dataProvider regimenesProvider */ + #[DataProvider('regimenesProvider')] public function test_check_regimenes_are_well_assigned(string $regimenText, string $regimenIdExpected): void { $regimen = new Regimen(); @@ -92,7 +90,7 @@ public function test_fecha_alta_with_empty_value(): void } /** @return array */ - public function provider_fecha_alta_with_invalid_value(): array + public static function provider_fecha_alta_with_invalid_value(): array { return [ 'empty' => [''], @@ -101,7 +99,7 @@ public function provider_fecha_alta_with_invalid_value(): array ]; } - /** @dataProvider provider_fecha_alta_with_invalid_value */ + #[DataProvider('provider_fecha_alta_with_invalid_value')] public function test_fecha_alta_with_invalid_value(string $input): void { $regimen = new Regimen(); diff --git a/tests/Unit/ScraperTest.php b/tests/Unit/ScraperTest.php index e82240a..eda7abb 100644 --- a/tests/Unit/ScraperTest.php +++ b/tests/Unit/ScraperTest.php @@ -14,9 +14,6 @@ final class ScraperTest extends TestCase { public function test_create_with_specific_openssl_cipher_list(): void { - /** - * Problem: The scraper does not have a method to get the client, obtained by reflection - */ $scraper = Scraper::create(); $client = $scraper->getClient(); $this->assertInstanceOf(Client::class, $client); @@ -27,7 +24,7 @@ public function test_create_with_specific_openssl_cipher_list(): void */ $this->assertSame( [CURLOPT_SSL_CIPHER_LIST => 'DEFAULT@SECLEVEL=1'], - $client->getConfig('curl') + $client->getConfig('curl'), ); } }