diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..303c5b1
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,2 @@
+# see https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
+/.github/* @phpcfdi/core-mantainers
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..59d8b28
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,112 @@
+name: build
+on:
+ pull_request:
+ branches: [ main ]
+ push:
+ branches: [ main ]
+ schedule:
+ - cron: '0 16 * * 0' # sunday 16:00
+
+jobs:
+
+ ci: # this job runs all the development tools and upload code coverage to scrutinizer
+
+ name: PHP 8.0 (full)
+ runs-on: "ubuntu-latest"
+
+ steps:
+
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ # see https://github.com/marketplace/actions/setup-php-action
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.0'
+ extensions: dom
+ coverage: xdebug
+ tools: composer:v2, phpcs, php-cs-fixer, phpstan, psalm, infection, cs2pr
+ env:
+ fail-fast: true
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache dependencies
+ uses: actions/cache@v2
+ 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: Code style (phpcs)
+ run: phpcs -q --report=checkstyle | cs2pr
+
+ - name: Code style (php-cs-fixer)
+ run: php-cs-fixer fix --dry-run --format=checkstyle | cs2pr
+
+ - name: Tests (phpunit with code coverage)
+ run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml --coverage-xml=build/coverage --log-junit=build/coverage/junit.xml
+
+ - name: Code analysis (phpstan)
+ run: phpstan analyse --no-progress --verbose
+
+ - name: Code analysis (psalm)
+ run: psalm --no-progress --output-format=github
+
+ - name: Mutation testing analysis
+ run: infection --skip-initial-tests --coverage=build/coverage --no-progress --no-interaction --logger-github
+
+ # see https://github.com/marketplace/actions/action-scrutinizer
+ - name: Upload code coverage to scrutinizer
+ uses: sudo-bot/action-scrutinizer@latest
+ with:
+ cli-args: "--format=php-clover build/coverage-clover.xml"
+ continue-on-error: true
+
+ build: # this job runs tests on all php supported versions
+
+ name: PHP ${{ matrix.php-versions }} (tests)
+ runs-on: "ubuntu-latest"
+
+ strategy:
+ matrix:
+ php-versions: ['7.3', '7.4']
+
+ steps:
+
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ # see https://github.com/marketplace/actions/setup-php-action
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: dom
+ coverage: none
+ tools: composer:v2, cs2pr
+ env:
+ fail-fast: true
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache dependencies
+ uses: actions/cache@v2
+ 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: Tests
+ run: vendor/bin/phpunit --testdox --verbose
diff --git a/.phive/phars.xml b/.phive/phars.xml
new file mode 100644
index 0000000..012e080
--- /dev/null
+++ b/.phive/phars.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php
similarity index 68%
rename from .php_cs.dist
rename to .php-cs-fixer.dist.php
index 08de141..969cb89 100644
--- a/.php_cs.dist
+++ b/.php-cs-fixer.dist.php
@@ -1,51 +1,52 @@
setRiskyAllowed(true)
->setCacheFile(__DIR__ . '/build/php_cs.cache')
->setRules([
- '@PSR2' => true,
- '@PHP70Migration' => true,
- '@PHP70Migration:risky' => true,
- '@PHP71Migration' => true,
+ '@PSR12' => true,
+ '@PSR12:risky' => true,
'@PHP71Migration:risky' => true,
- // '@PHP73Migration' => true,
+ '@PHP73Migration' => true,
+ // PSR12 (remove when php-cs-fixer reaches ^3.1.1)
+ 'class_definition' => ['space_before_parenthesis' => true],
// symfony
'class_attributes_separation' => true,
'whitespace_after_comma_in_array' => true,
'no_empty_statement' => true,
'no_extra_blank_lines' => true,
'function_typehint_space' => true,
- 'no_alias_functions' => true,
- 'trailing_comma_in_multiline_array' => true,
- 'new_with_braces' => true,
- 'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'object_operator_without_whitespace' => true,
'binary_operator_spaces' => true,
'phpdoc_scalar' => true,
- 'self_accessor' => true,
'no_trailing_comma_in_singleline_array' => true,
'single_quote' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_unused_imports' => true,
- 'no_whitespace_in_blank_line' => true,
'yoda_style' => ['equal' => true, 'identical' => true, 'less_and_greater' => null],
'standardize_not_equals' => true,
- // contrib
'concat_space' => ['spacing' => 'one'],
- 'not_operator_with_successor_space' => true,
- 'single_blank_line_before_namespace' => true,
'linebreak_after_opening_tag' => true,
- 'blank_line_after_opening_tag' => true,
- 'ordered_imports' => true,
- 'array_syntax' => ['syntax' => 'short'],
+ // symfony:risky
+ 'no_alias_functions' => true,
+ 'self_accessor' => true,
+ // contrib
+ 'not_operator_with_successor_space' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__)
+ ->append([__FILE__])
->exclude(['vendor', 'build'])
)
;
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index 3df7e54..bf297bf 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -1,23 +1,19 @@
filter:
excluded_paths:
- 'tests/'
+ dependency_paths:
+ - 'tools/'
- 'vendor/'
build:
dependencies:
override:
- - composer self-update --2 --stable --no-interaction --no-progress
- - composer remove squizlabs/php_codesniffer friendsofphp/php-cs-fixer phpstan/phpstan --dev --no-interaction --no-progress --no-update
- - composer update --no-interaction --no-progress
+ - composer update --no-interaction --prefer-dist
nodes:
- analysis:
- project_setup:
- override: true
+ analysis: # see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/
+ project_setup: {override: true}
tests:
override:
- php-scrutinizer-run --enable-security-analysis
- - phpcs-run --standard=phpcs.xml.dist src/ tests/
- - command: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
- coverage:
- file: coverage.clover
- format: clover
+tools:
+ external_code_coverage: true
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 5b6e2eb..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-language: php
-
-# php compatibility
-php: ["7.2", "7.3", "7.4", "8.0"]
-
-cache:
- - directories:
- - $HOME/.composer
-
-env:
- global:
- - PHP_CS_FIXER_IGNORE_ENV=yes
-
-before_script:
- - phpenv config-rm xdebug.ini || true
- - travis_retry composer self-update --2 --stable --no-interaction --no-progress
- - travis_retry composer upgrade --prefer-dist --no-interaction --no-progress
-
-script:
- - vendor/bin/php-cs-fixer fix --dry-run --verbose
- - vendor/bin/phpcs --colors -sp src/ tests/
- - vendor/bin/phpunit --testdox --verbose
- - vendor/bin/phpstan analyse --no-progress --level max src/ tests/
-
-notifications:
- email:
- if: branch = master
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 0a673cd..0d98501 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,5 +1,4 @@
-
-# Código de Conducta convenido para Contribuyentes
+# Código de Conducta Convenido para Contribuyentes
## Nuestro compromiso
@@ -37,7 +36,7 @@ Este código de conducta aplica tanto a espacios del proyecto como a espacios p
## Aplicación
-Instancias de comportamiento abusivo, acosador o inaceptable de otro modo podrán ser reportadas a los administradores de la comunidad responsables del cumplimiento a través de [coc@phpcfdi.com](). Todas las quejas serán evaluadas e investigadas de una manera puntual y justa.
+Instancias de comportamiento abusivo, acosador o inaceptable de otro modo podrán ser reportadas a los administradores de la comunidad responsables del cumplimiento a través de [coc@phpcfdi.com](mailto:coc@phpcfdi.com). Todas las quejas serán evaluadas e investigadas de una manera puntual y justa.
Todos los administradores de la comunidad están obligados a respetar la privacidad y la seguridad de quienes reporten incidentes.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ad42ea..bba4278 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -64,6 +64,7 @@ Considera las siguientes directrices:
```shell
# Actualiza tus dependencias
composer update
+phive update
# Verificación de estilo de código
composer dev:check-style
@@ -74,12 +75,22 @@ composer dev:fix-style
# Ejecución de pruebas
composer dev:test
-# Ejecución todo en uno, corregir estilo, verificar estilo y correr pruebas
+# Ejecución todo en uno: corregir estilo, verificar estilo y correr pruebas
composer dev:build
```
+## Ejecutar GitHub Actions localmente
+
+Puedes usar [`act`](https://github.com/nektos/act) para ejecutar GitHub Actions localmente, tal como se
+muestra en [`actions/setup-php-action`](https://github.com/marketplace/actions/setup-php-action#local-testing-setup)
+puedes ejecutar el siguiente comando:
+
+```shell
+act -P ubuntu-latest=shivammathur/node:latest
+```
+
[phpCfdi]: https://github.com/phpcfdi/
[project]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr
[contributors]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/graphs/contributors
-[coc]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/master/CODE_OF_CONDUCT.md
+[coc]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/main/CODE_OF_CONDUCT.md
[issues]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/issues
diff --git a/README.md b/README.md
index 4fa89f8..0220472 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
> Consulta el estado de un CFDI en el webservice del SAT usando HTTP (PSR-17 y PSR-18)
-:us: The documentation of this project is in spanish as this is the natural language for intented audience.
+:us: The documentation of this project is in spanish as this is the natural language for intended audience.
:mexico: La documentación del proyecto está en español porque ese es el lenguaje principal de los usuarios.
@@ -88,7 +88,7 @@ Puedes ver los siguientes recursos para integrar `phpcfdi/sat-estado-cfdi-http-p
- [Integración genérica](docs/integracion-generica.md)
Implementación de los PSR-17 y PSR-18 que decidas, ejemplo usando Sunrise.
-## Compatilibilidad
+## Compatibilidad
Esta librería se mantendrá compatible con al menos la versión con
[soporte activo de PHP](https://www.php.net/supported-versions.php) más reciente.
@@ -106,22 +106,22 @@ y recuerda revisar el archivo de tareas pendientes [TODO][] y el archivo [CHANGE
The `phpcfdi/sat-estado-cfdi-http-psr` library is copyright © [PhpCfdi](https://www.phpcfdi.com/)
and licensed for use under the MIT License (MIT). Please see [LICENSE][] for more information.
-[contributing]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/master/CONTRIBUTING.md
-[changelog]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/master/docs/CHANGELOG.md
-[todo]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/master/docs/TODO.md
+[contributing]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/main/CONTRIBUTING.md
+[changelog]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/main/docs/CHANGELOG.md
+[todo]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/main/docs/TODO.md
[source]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr
[release]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/releases
-[license]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/master/LICENSE
-[build]: https://travis-ci.com/phpcfdi/sat-estado-cfdi-http-psr?branch=master
+[license]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/main/LICENSE
+[build]: https://github.com/phpcfdi/sat-estado-cfdi-http-psr/actions/workflows/build.yml?query=branch:main
[quality]: https://scrutinizer-ci.com/g/phpcfdi/sat-estado-cfdi-http-psr/
-[coverage]: https://scrutinizer-ci.com/g/phpcfdi/sat-estado-cfdi-http-psr/code-structure/master/code-coverage
+[coverage]: https://scrutinizer-ci.com/g/phpcfdi/sat-estado-cfdi-http-psr/code-structure/main/code-coverage
[downloads]: https://packagist.org/packages/phpcfdi/sat-estado-cfdi-http-psr
[badge-source]: https://img.shields.io/badge/source-phpcfdi/sat--estado--cfdi--http--psr-blue?style=flat-square
[badge-release]: https://img.shields.io/github/release/phpcfdi/sat-estado-cfdi-http-psr?style=flat-square
[badge-license]: https://img.shields.io/github/license/phpcfdi/sat-estado-cfdi-http-psr?style=flat-square
-[badge-build]: https://img.shields.io/travis/com/phpcfdi/sat-estado-cfdi-http-psr/master?style=flat-square
-[badge-quality]: https://img.shields.io/scrutinizer/g/phpcfdi/sat-estado-cfdi-http-psr/master?style=flat-square
-[badge-coverage]: https://img.shields.io/scrutinizer/coverage/g/phpcfdi/sat-estado-cfdi-http-psr/master?style=flat-square
+[badge-build]: https://img.shields.io/github/workflow/status/phpcfdi/sat-estado-cfdi-http-psr/build/main?style=flat-square
+[badge-quality]: https://img.shields.io/scrutinizer/g/phpcfdi/sat-estado-cfdi-http-psr/main?style=flat-square
+[badge-coverage]: https://img.shields.io/scrutinizer/coverage/g/phpcfdi/sat-estado-cfdi-http-psr/main?style=flat-square
[badge-downloads]: https://img.shields.io/packagist/dt/phpcfdi/sat-estado-cfdi-http-psr?style=flat-square
diff --git a/composer.json b/composer.json
index 2f2d88a..9ba454e 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,7 @@
}
},
"require": {
- "php": ">=7.2",
+ "php": ">=7.3",
"ext-dom": "*",
"phpcfdi/sat-estado-cfdi": "^1.0.0",
"psr/http-client": "^1.0",
@@ -35,10 +35,7 @@
"symfony/http-client": "^5.2",
"sunrise/http-factory": "^1.0",
"sunrise/http-message": "^1.0",
- "phpunit/phpunit": "^8.0",
- "squizlabs/php_codesniffer": "^3.0",
- "friendsofphp/php-cs-fixer": "^2.4",
- "phpstan/phpstan": "^0.12"
+ "phpunit/phpunit": "^9.5"
},
"suggest": {
"phpcfdi/cfdi-expresiones": "Genera expresiones de CFDI 3.3, CFDI 3.2 y RET 1.0"
@@ -56,27 +53,29 @@
"scripts": {
"dev:build": ["@dev:fix-style", "@dev:test"],
"dev:check-style": [
- "@php vendor/bin/php-cs-fixer fix --dry-run --verbose",
- "@php vendor/bin/phpcs --colors -sp src/ tests/"
+ "@php tools/php-cs-fixer fix --dry-run --verbose",
+ "@php tools/phpcs --colors -sp"
],
"dev:fix-style": [
- "@php vendor/bin/php-cs-fixer fix --verbose",
- "@php vendor/bin/phpcbf --colors -sp src/ tests/"
+ "@php tools/php-cs-fixer fix --verbose",
+ "@php tools/phpcbf --colors -sp"
],
"dev:test": [
"@dev:check-style",
"@php vendor/bin/phpunit --testdox --verbose --stop-on-failure",
- "@php vendor/bin/phpstan analyse --no-progress --verbose --level max src/ tests/"
+ "@php tools/phpstan analyse --no-progress",
+ "@php tools/psalm --no-progress",
+ "@php tools/infection --no-progress --no-interaction --show-mutations"
],
"dev:coverage": [
- "@php -dzend_extension=xdebug.so vendor/bin/phpunit --testdox --coverage-html build/coverage/html/"
+ "@php -dzend_extension=xdebug.so -dxdebug.mode=coverage vendor/bin/phpunit --verbose --coverage-html build/coverage/html/"
]
},
"scripts-descriptions": {
- "dev:build": "DEV: run dev:fix-style dev:tests and dev:docs, run before pull request",
+ "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:test": "DEV: run dev:check-style, phpunit, phpstan, psalm and infection",
"dev:coverage": "DEV: run phpunit with xdebug and storage coverage in build/coverage/html/"
}
}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 8ed8d73..6004a10 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -11,6 +11,15 @@ versión aunque sí su incorporación en la rama principal de trabajo, generalme
## Listado de cambios
+### Version 1.0.1 2021-09-03
+
+- La versión menor de PHP es 7.3.
+- Se actualiza PHPUnit a 9.5.
+- Se migra de Travis-CI a GitHub Workflows. Gracias Travis-CI.
+- Se instalan las herramientas de desarrollo usando `phive` en lugar de `composer`.
+- Se agregan revisiones de `psalm` e `infection`.
+- Se cambia la rama principal a `main`.
+
### Version 1.0.0 2021-01-10
- A partir de esta versión se ha puesto la documentación del proyecto en español.
diff --git a/docs/integracion-generica.md b/docs/integracion-generica.md
index a515d7f..55758f3 100644
--- a/docs/integracion-generica.md
+++ b/docs/integracion-generica.md
@@ -34,7 +34,7 @@ $consumer = new HttpConsumerClient($factory);
## Extendiendo HttpConsumerFactory
Otra forma de hacerlo es extendiendo la clase `HttpConsumerFactory`, un ejemplo de esto se puede ver
-en
+en
## Implementando HttpConsumerFactoryInterface
diff --git a/infection.json.dist b/infection.json.dist
new file mode 100644
index 0000000..b69deba
--- /dev/null
+++ b/infection.json.dist
@@ -0,0 +1,18 @@
+{
+ "timeout": 10,
+ "source": {
+ "directories": [
+ "src"
+ ],
+ "excludes": [
+ "ComplianceTester/ComplianceTester.php"
+ ]
+ },
+ "logs": {
+ "text": "build\/infection.log"
+ },
+ "mutators": {
+ "@default": true
+ },
+ "initialTestsPhpOptions": "-dzend_extension=xdebug.so -dxdebug.mode=coverage"
+}
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 24596ad..e7c3269 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -1,11 +1,17 @@
The EngineWorks (PSR-2 based) coding standard.
+
+ src
+ tests
+
-
+
+
+
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..e691e35
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,5 @@
+parameters:
+ level: max
+ paths:
+ - src/
+ - tests/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 2081ce6..7557d0b 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -2,17 +2,17 @@
+ >
-
- ./tests/
+
+ tests
-
-
+
+
./src/
-
-
+
+
diff --git a/psalm.xml.dist b/psalm.xml.dist
new file mode 100644
index 0000000..28c52a8
--- /dev/null
+++ b/psalm.xml.dist
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/HttpConsumerClient.php b/src/HttpConsumerClient.php
index e1f1860..03de0db 100644
--- a/src/HttpConsumerClient.php
+++ b/src/HttpConsumerClient.php
@@ -7,6 +7,7 @@
use PhpCfdi\SatEstadoCfdi\Contracts\ConsumerClientInterface;
use PhpCfdi\SatEstadoCfdi\Contracts\ConsumerClientResponseInterface;
use PhpCfdi\SatEstadoCfdi\HttpPsr\Internal\SoapXml;
+use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
@@ -41,15 +42,14 @@ public function createHttpRequest(string $uri, string $expression): RequestInter
// body
$xml = $this->soapXml->createXmlRequest($expression);
$body = $this->factory->streamFactory()->createStream($xml);
- $request = $request->withBody($body);
- return $request;
+ return $request->withBody($body);
}
public function createConsumerClientResponse(string $xmlResponse): ConsumerClientResponseInterface
{
// parse body
- $dataExtracted = $this->soapXml->extractDataFromXmlResponse($xmlResponse);
+ $dataExtracted = $this->soapXml->extractDataFromXmlResponse($xmlResponse, 'ConsultaResult');
// create & populate container
$container = $this->factory->newConsumerClientResponse();
@@ -60,6 +60,9 @@ public function createConsumerClientResponse(string $xmlResponse): ConsumerClien
return $container;
}
+ /**
+ * @throws ClientExceptionInterface
+ */
public function consume(string $uri, string $expression): ConsumerClientResponseInterface
{
// parameters --convert--> request --httpCall--> response --convert--> ConsumerClientResponse
@@ -73,6 +76,7 @@ public function consume(string $uri, string $expression): ConsumerClientResponse
*
* @param RequestInterface $request
* @return ResponseInterface
+ * @throws ClientExceptionInterface
*/
protected function sendRequest(RequestInterface $request): ResponseInterface
{
diff --git a/src/HttpConsumerFactoryInterface.php b/src/HttpConsumerFactoryInterface.php
index 5facb3d..e68a26a 100644
--- a/src/HttpConsumerFactoryInterface.php
+++ b/src/HttpConsumerFactoryInterface.php
@@ -1,9 +1,6 @@
uri = $uri;
}
- public function uri(): string
- {
- return $this->uri;
- }
-
/**
* Extract the information from expected soap response
*
* @param string $xmlResponse
+ * @param string $elementName
* @return array
*/
- public function extractDataFromXmlResponse(string $xmlResponse): array
+ public function extractDataFromXmlResponse(string $xmlResponse, string $elementName): array
{
- $extracted = [];
$document = new DOMDocument();
$document->loadXML($xmlResponse);
- /** @var DOMElement $consultaResult */
- foreach ($document->getElementsByTagNameNS($this->uri(), 'ConsultaResult') as $consultaResult) {
- foreach ($consultaResult->childNodes as $children) {
- if (! $children instanceof DOMElement) {
- continue;
- }
- $extracted[$children->localName] = $children->textContent;
+
+ $consultaResult = $this->obtainFirstElement($document, $elementName);
+ if (null === $consultaResult) {
+ return [];
+ }
+
+ $extracted = [];
+ foreach ($consultaResult->childNodes as $children) {
+ if (! $children instanceof DOMElement) {
+ continue;
}
- break; // exit loop if for any reason got more than 1 element ConsultaResult
+ $extracted[$children->localName] = $children->textContent;
}
+
return $extracted;
}
+ private function obtainFirstElement(DOMDocument $document, string $elementName): ?DOMElement
+ {
+ foreach ($document->getElementsByTagNameNS($this->uri, $elementName) as $consultaResult) {
+ return $consultaResult;
+ }
+ return null;
+ }
+
public function createXmlRequest(string $expression): string
{
$soap = 'http://schemas.xmlsoap.org/soap/envelope/';
$document = new DOMDocument('1.0', 'UTF-8');
$document->appendChild($document->createElementNS($soap, 's:Envelope'))
->appendChild($document->createElementNS($soap, 's:Body'))
- ->appendChild($document->createElementNS($this->uri(), 'c:Consulta'))
- ->appendChild($document->createElementNS($this->uri(), 'c:expresionImpresa'))
+ ->appendChild($document->createElementNS($this->uri, 'c:Consulta'))
+ ->appendChild($document->createElementNS($this->uri, 'c:expresionImpresa'))
->appendChild($document->createTextNode($expression));
return $document->saveXML() ?: '';
}
diff --git a/tests/Unit/HttpConsumerClientTest.php b/tests/Unit/HttpConsumerClientTest.php
index 24f9547..041c9e6 100644
--- a/tests/Unit/HttpConsumerClientTest.php
+++ b/tests/Unit/HttpConsumerClientTest.php
@@ -6,8 +6,12 @@
use PhpCfdi\SatEstadoCfdi\Contracts\ConsumerClientInterface;
use PhpCfdi\SatEstadoCfdi\HttpPsr\HttpConsumerClient;
+use PhpCfdi\SatEstadoCfdi\HttpPsr\HttpConsumerFactoryInterface;
use PhpCfdi\SatEstadoCfdi\Tests\HttpPsr\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
+use Psr\Http\Client\ClientInterface as HttpClientInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
use Sunrise\Http\Factory\ResponseFactory;
class HttpConsumerClientTest extends TestCase
@@ -75,4 +79,33 @@ public function testConsume(): void
$container = $client->consume('http://example.com/', '');
$this->assertSame('S - Comprobante obtenido satisfactoriamente.', $container->get('CodigoEstatus'));
}
+
+ public function testMethodSendRequest(): void
+ {
+ $request = $this->createMock(RequestInterface::class);
+ $response = $this->createMock(ResponseInterface::class);
+
+ /** @var HttpClientInterface&MockObject $httpClient */
+ $httpClient = $this->createMock(HttpClientInterface::class);
+ $httpClient->expects($this->once())
+ ->method('sendRequest')
+ ->with($request)
+ ->willReturn($response);
+
+ /** @var HttpConsumerFactoryInterface&MockObject $factory */
+ $factory = $this->createMock(HttpConsumerFactoryInterface::class);
+ $factory->expects($this->once())
+ ->method('httpClient')
+ ->willReturn($httpClient);
+
+ $httpConsumetClient = new class ($factory) extends HttpConsumerClient {
+ /** @noinspection PhpOverridingMethodVisibilityInspection */
+ public function sendRequest(RequestInterface $request): ResponseInterface // phpcs:ignore
+ {
+ return parent::sendRequest($request);
+ }
+ };
+
+ $this->assertSame($response, $httpConsumetClient->sendRequest($request));
+ }
}
diff --git a/tests/Unit/SoapXmlTest.php b/tests/Unit/SoapXmlTest.php
new file mode 100644
index 0000000..9c16777
--- /dev/null
+++ b/tests/Unit/SoapXmlTest.php
@@ -0,0 +1,63 @@
+
+
+
+
+ x-first
+ x-second
+ x-third
+
+
+ must be ignored
+
+
+
+
+ XML;
+
+ $soapXml = new SoapXml('http://tempuri.org/');
+ $extracted = $soapXml->extractDataFromXmlResponse($xml, 'Result');
+
+ $expected = [
+ 'first' => 'x-first',
+ 'second' => 'x-second',
+ 'third' => 'x-third',
+ ];
+ $this->assertSame($expected, $extracted);
+ }
+
+ public function testCreateConsumerClientResponse(): void
+ {
+ $xmlns = 'http://tempuri.org/';
+ $expression = 'Expresión con caracteres & y Ñ';
+
+ $expressionXml = htmlspecialchars($expression, ENT_XML1);
+ $expected = <<< XML
+
+
+
+ $expressionXml
+
+
+
+ XML;
+
+ $soapXml = new SoapXml($xmlns);
+ $createdXml = $soapXml->createXmlRequest($expression);
+
+ $this->assertXmlStringEqualsXmlString($expected, $createdXml);
+ }
+}
diff --git a/tools/infection b/tools/infection
new file mode 120000
index 0000000..313fced
--- /dev/null
+++ b/tools/infection
@@ -0,0 +1 @@
+/home/eclipxe/.phive/phars/infection-0.23.0.phar
\ No newline at end of file
diff --git a/tools/php-cs-fixer b/tools/php-cs-fixer
new file mode 120000
index 0000000..44b0111
--- /dev/null
+++ b/tools/php-cs-fixer
@@ -0,0 +1 @@
+/home/eclipxe/.phive/phars/php-cs-fixer-3.1.0.phar
\ No newline at end of file
diff --git a/tools/phpcbf b/tools/phpcbf
new file mode 120000
index 0000000..e439e7b
--- /dev/null
+++ b/tools/phpcbf
@@ -0,0 +1 @@
+/home/eclipxe/.phive/phars/phpcbf-3.6.0.phar
\ No newline at end of file
diff --git a/tools/phpcs b/tools/phpcs
new file mode 120000
index 0000000..b2cf86d
--- /dev/null
+++ b/tools/phpcs
@@ -0,0 +1 @@
+/home/eclipxe/.phive/phars/phpcs-3.6.0.phar
\ No newline at end of file
diff --git a/tools/phpstan b/tools/phpstan
new file mode 120000
index 0000000..0e2642d
--- /dev/null
+++ b/tools/phpstan
@@ -0,0 +1 @@
+/home/eclipxe/.phive/phars/phpstan-0.12.98.phar
\ No newline at end of file
diff --git a/tools/psalm b/tools/psalm
new file mode 120000
index 0000000..12be5d0
--- /dev/null
+++ b/tools/psalm
@@ -0,0 +1 @@
+/home/eclipxe/.phive/phars/psalm-4.9.3.phar
\ No newline at end of file