Skip to content
This repository was archived by the owner on Mar 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #9 from eclipxe13/development
Browse files Browse the repository at this point in the history
Review 2021-09-03
eclipxe13 authored Sep 4, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents 8a700c3 + c27f5d1 commit 089eae0
Showing 28 changed files with 383 additions and 118 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# see https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
/.github/* @phpcfdi/core-mantainers
112 changes: 112 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -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
9 changes: 9 additions & 0 deletions .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="php-cs-fixer" version="^3.1.0" installed="3.1.0" location="./tools/php-cs-fixer" copy="false"/>
<phar name="phpcs" version="^3.6.0" installed="3.6.0" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.6.0" installed="3.6.0" location="./tools/phpcbf" copy="false"/>
<phar name="phpstan" version="^0.12.98" installed="0.12.98" location="./tools/phpstan" copy="false"/>
<phar name="psalm" version="^4.9.3" installed="4.9.3" location="./tools/psalm" copy="false"/>
<phar name="infection" version="^0.23.0" installed="0.23.0" location="./tools/infection" copy="false"/>
</phive>
37 changes: 19 additions & 18 deletions .php_cs.dist → .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
<?php

/**
* @noinspection PhpUndefinedClassInspection
* @noinspection PhpUndefinedNamespaceInspection
* @see https://cs.symfony.com/doc/ruleSets/
* @see https://cs.symfony.com/doc/rules/
*/

declare(strict_types=1);

return PhpCsFixer\Config::create()
return (new PhpCsFixer\Config())
->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'])
)
;
18 changes: 7 additions & 11 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -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
27 changes: 0 additions & 27 deletions .travis.yml

This file was deleted.

5 changes: 2 additions & 3 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -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 [[email protected]](). 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 [[email protected]](mailto:[email protected]). 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.

15 changes: 13 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -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
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
25 changes: 12 additions & 13 deletions composer.json
Original file line number Diff line number Diff line change
@@ -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/"
}
}
9 changes: 9 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion docs/integracion-generica.md
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/master/tests/TestingHttpConsumerFactory.php>
en <https://github.com/phpcfdi/sat-estado-cfdi-http-psr/blob/main/tests/TestingHttpConsumerFactory.php>


## Implementando HttpConsumerFactoryInterface
18 changes: 18 additions & 0 deletions infection.json.dist
Original file line number Diff line number Diff line change
@@ -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"
}
8 changes: 7 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<?xml version="1.0"?>
<ruleset name="EngineWorks">
<description>The EngineWorks (PSR-2 based) coding standard.</description>

<file>src</file>
<file>tests</file>

<arg name="tab-width" value="4"/>
<arg name="encoding" value="utf-8"/>
<arg name="report-width" value="auto"/>
<arg name="extensions" value="php"/>
<rule ref="PSR2"/>
<arg name="cache" value="build/phpcs.cache"/>

<rule ref="PSR12"/>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="Generic.CodeAnalysis.EmptyStatement"/>
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
5 changes: 5 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
parameters:
level: max
paths:
- src/
- tests/
16 changes: 8 additions & 8 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -2,17 +2,17 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
cacheResultFile="build/phpunit.result.cache"
bootstrap="tests/bootstrap.php"
colors="true"
verbose="true"
bootstrap="tests/bootstrap.php">
>
<testsuites>
<testsuite name="Default">
<directory>./tests/</directory>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<coverage>
<include>
<directory suffix=".php">./src/</directory>
</whitelist>
</filter>
</include>
</coverage>
</phpunit>
15 changes: 15 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<psalm xmlns="https://getpsalm.org/schema/config"
resolveFromConfigFile="true"
totallyTyped="true">
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>

<issueHandlers>
<LessSpecificReturnType errorLevel="info" />
</issueHandlers>
</psalm>
10 changes: 7 additions & 3 deletions src/HttpConsumerClient.php
Original file line number Diff line number Diff line change
@@ -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
{
3 changes: 0 additions & 3 deletions src/HttpConsumerFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<?php

declare(strict_types=1);
/**
*
*/

namespace PhpCfdi\SatEstadoCfdi\HttpPsr;

41 changes: 24 additions & 17 deletions src/Internal/SoapXml.php
Original file line number Diff line number Diff line change
@@ -20,43 +20,50 @@ public function __construct(string $uri)
$this->uri = $uri;
}

public function uri(): string
{
return $this->uri;
}

/**
* Extract the information from expected soap response
*
* @param string $xmlResponse
* @param string $elementName
* @return array<string, string>
*/
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() ?: '';
}
33 changes: 33 additions & 0 deletions tests/Unit/HttpConsumerClientTest.php
Original file line number Diff line number Diff line change
@@ -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));
}
}
63 changes: 63 additions & 0 deletions tests/Unit/SoapXmlTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace PhpCfdi\SatEstadoCfdi\Tests\HttpPsr\Unit;

use PhpCfdi\SatEstadoCfdi\HttpPsr\Internal\SoapXml;
use PhpCfdi\SatEstadoCfdi\Tests\HttpPsr\TestCase;

final class SoapXmlTest extends TestCase
{
public function testExtractDataFromXmlResponse(): void
{
$xml = <<< XML
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ResponseResponse xmlns="http://tempuri.org/">
<Result xmlns:a="http://tempuri.org/a" xmlns:b="http://tempuri.org/b">
<first>x-first</first>
<a:second>x-second</a:second>
<b:third>x-third</b:third>
</Result>
<Result xmlns:a="http://tempuri.org/a" xmlns:b="http://tempuri.org/b">
<first>must be ignored</first>
</Result>
</ResponseResponse>
</s:Body>
</s:Envelope>
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
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<c:Consulta xmlns:c="$xmlns">
<c:expresionImpresa>$expressionXml</c:expresionImpresa>
</c:Consulta>
</s:Body>
</s:Envelope>
XML;

$soapXml = new SoapXml($xmlns);
$createdXml = $soapXml->createXmlRequest($expression);

$this->assertXmlStringEqualsXmlString($expected, $createdXml);
}
}
1 change: 1 addition & 0 deletions tools/infection
1 change: 1 addition & 0 deletions tools/php-cs-fixer
1 change: 1 addition & 0 deletions tools/phpcbf
1 change: 1 addition & 0 deletions tools/phpcs
1 change: 1 addition & 0 deletions tools/phpstan
1 change: 1 addition & 0 deletions tools/psalm

0 comments on commit 089eae0

Please sign in to comment.