diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 5b83952..09fa53b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,12 @@ In summary, [SemVer](https://semver.org/) can be viewed as ` Breaking . Feature **Version `0.x.x` doesn't have to apply any of the SemVer rules** +## Version 0.2.2 2019-08-20 + +- Make sure that when constructing a `DateTime` it fails with an exception. +- Improve code coverage. + + ## Version 0.2.1 2019-08-20 - Make `PackageReader\MetadataContent` tolerant to non-strict CSV contents: diff --git a/src/PackageReader/AbstractPackageReader.php b/src/PackageReader/AbstractPackageReader.php index 3662fd5..5fbf37a 100644 --- a/src/PackageReader/AbstractPackageReader.php +++ b/src/PackageReader/AbstractPackageReader.php @@ -92,13 +92,16 @@ public function count(): int } /** - * @return Generator|string[] + * Generates the list of name => contents and yield only entries that pass name and content filters + * + * @return Generator|string[] pair of file name and contents */ public function fileContents() { for ($i = 0; $i < $this->zip->numFiles; $i++) { $filename = strval($this->zip->getNameIndex($i)); if ('' === $filename) { + /** @codeCoverageIgnore */ continue; // cannot get the file name } if (! $this->filterEntryFilename($filename)) { diff --git a/src/Shared/DateTime.php b/src/Shared/DateTime.php index 70c5550..2bc9ac6 100644 --- a/src/Shared/DateTime.php +++ b/src/Shared/DateTime.php @@ -7,6 +7,7 @@ use DateTimeImmutable; use DateTimeZone; use InvalidArgumentException; +use Throwable; class DateTime { @@ -15,11 +16,17 @@ class DateTime public function __construct($value = null) { + $value = $value ?? 'now'; if (is_int($value)) { - $value = '@' . $value; + $value = sprintf('@%d', $value); } - if (null === $value || is_string($value)) { - $value = new DateTimeImmutable($value ?? 'now'); + if (is_string($value)) { + try { + $value = new DateTimeImmutable($value ?? 'now'); + } catch (Throwable $exception) { + $message = sprintf('Unable to create a Datetime("%s")', strval($value)); + throw new InvalidArgumentException($message, 0, $exception); + } } if (! $value instanceof DateTimeImmutable) { throw new InvalidArgumentException('Unable to create a Datetime'); diff --git a/tests/Unit/PackageReader/CfdiPackageReaderTest.php b/tests/Unit/PackageReader/CfdiPackageReaderTest.php index 6229510..1920bf0 100644 --- a/tests/Unit/PackageReader/CfdiPackageReaderTest.php +++ b/tests/Unit/PackageReader/CfdiPackageReaderTest.php @@ -6,13 +6,14 @@ use PhpCfdi\SatWsDescargaMasiva\PackageReader\CfdiPackageReader; use PhpCfdi\SatWsDescargaMasiva\Tests\TestCase; +use RuntimeException; class CfdiPackageReaderTest extends TestCase { public function testReaderZipWhenTheContentIsInvalid(): void { $zipContents = 'INVALID_ZIP_CONTENT'; - $this->expectException(\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Could not open zip'); CfdiPackageReader::createFromContents($zipContents); } diff --git a/tests/Unit/Services/Download/DownloadTranslatorTest.php b/tests/Unit/Services/Download/DownloadTranslatorTest.php index bd81a85..2f134d2 100644 --- a/tests/Unit/Services/Download/DownloadTranslatorTest.php +++ b/tests/Unit/Services/Download/DownloadTranslatorTest.php @@ -23,6 +23,7 @@ public function testCreateDownloadResultFromSoapResponseWithPackage(): void $result = $translator->createDownloadResultFromSoapResponse($responseBody); $status = $result->getStatus(); + $this->assertGreaterThan(0, $result->getPackageLenght()); $this->assertNotEmpty($result->getPackageContent()); $this->assertEquals($expectedStatusCode, $status->getCode()); $this->assertEquals($expectedMessage, $status->getMessage()); diff --git a/tests/Unit/Shared/DateTimeTest.php b/tests/Unit/Shared/DateTimeTest.php index 9f7cbb8..876f934 100644 --- a/tests/Unit/Shared/DateTimeTest.php +++ b/tests/Unit/Shared/DateTimeTest.php @@ -4,6 +4,7 @@ namespace PhpCfdi\SatWsDescargaMasiva\Tests\Unit\Shared; +use InvalidArgumentException; use PhpCfdi\SatWsDescargaMasiva\Shared\DateTime; use PhpCfdi\SatWsDescargaMasiva\Tests\TestCase; @@ -32,4 +33,24 @@ public function testFormatSatUsesZuluTimeZone(): void $this->assertSame('2019-01-14T04:23:24.000Z', $date->formatSat()); $this->assertSame('2019-01-13T22:23:24.000CST', $date->formatDefaultTimeZone()); } + + public function testCreateDateTimeWithTimestamp(): void + { + $date = new DateTime(316569600); + $this->assertSame('1980-01-13T00:00:00.000Z', $date->formatSat()); + } + + public function testCreateDateTimeWithInvalidStringValue(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Unable to create a Datetime("foo")'); + new DateTime('foo'); + } + + public function testCreateDateTimeWithInvalidArgument(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Unable to create a Datetime'); + new DateTime([]); + } } diff --git a/tests/Unit/Shared/InteractsXmlTraitTest.php b/tests/Unit/Shared/InteractsXmlTraitTest.php index a433238..ce58524 100644 --- a/tests/Unit/Shared/InteractsXmlTraitTest.php +++ b/tests/Unit/Shared/InteractsXmlTraitTest.php @@ -4,6 +4,9 @@ namespace PhpCfdi\SatWsDescargaMasiva\Tests\Unit\Shared; +use DOMDocument; +use InvalidArgumentException; +use PhpCfdi\SatWsDescargaMasiva\Shared\InteractsXmlTrait; use PhpCfdi\SatWsDescargaMasiva\Tests\TestCase; class InteractsXmlTraitTest extends TestCase @@ -43,6 +46,30 @@ public function testFindElementExpectingOne(): void ); } + public function testReadXmlDocumentWithoutContentThrowsException(): void + { + $specimen = new InteractsXmlTraitSpecimen(); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Cannot load an xml with empty content'); + $specimen->readXmlDocument(''); + } + + public function testReadXmlElementWithoutDocumentRootElementThrowsException(): void + { + $specimen = new class() { + use InteractsXmlTrait; + + public function readXmlDocument(string $source): DOMDocument + { + unset($source); + return new DOMDocument(); + } + }; + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Cannot load an xml without document element'); + $specimen->readXmlElement(''); + } + public function testFindElementExpectingNone(): void { $specimen = new InteractsXmlTraitSpecimen(); diff --git a/tests/Unit/Shared/TokenTest.php b/tests/Unit/Shared/TokenTest.php new file mode 100644 index 0000000..66f70fd --- /dev/null +++ b/tests/Unit/Shared/TokenTest.php @@ -0,0 +1,70 @@ +modify('- 1 second'); + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Cannot create a token with expiration lower than creation'); + new Token($created, $expires, ''); + } + + public function testTokenNotExpired(): void + { + $created = new DateTime(); + $expires = $created->modify('+ 5 seconds'); + $token = new Token($created, $expires, ''); + $this->assertFalse($token->isExpired()); + } + + public function testTokenExpired(): void + { + $created = new DateTime('- 10 seconds'); + $expires = $created->modify('+ 5 seconds'); + $token = new Token($created, $expires, ''); + $this->assertTrue($token->isExpired()); + } + + public function testValueNotEmpty(): void + { + $created = new DateTime('- 10 seconds'); + $expires = $created->modify('+ 5 seconds'); + $token = new Token($created, $expires, ''); + $this->assertTrue($token->isValueEmpty()); + } + + public function testValueIsNotEmpty(): void + { + $created = new DateTime('- 10 seconds'); + $expires = $created->modify('+ 5 seconds'); + $token = new Token($created, $expires, 'foo'); + $this->assertFalse($token->isValueEmpty()); + } + + /** + * @param string $created + * @param string $expires + * @param string $value + * @param bool $expected + * @testWith ["- 10 seconds", "+ 10 seconds", "foo", true] + * ["- 10 seconds", "- 1 seconds", "foo", false] + * ["- 10 seconds", "+ 10 seconds", "", false] + * ["- 10 seconds", "- 1 seconds", "", false] + */ + public function testIsValid(string $created, string $expires, string $value, bool $expected): void + { + $token = new Token(new DateTime($created), new DateTime($expires), $value); + $this->assertSame($expected, $token->isValid()); + } +} diff --git a/tests/_files/zip/cfdi.xml b/tests/_files/zip/cfdi.xml index 3284d15..ec430b9 100644 --- a/tests/_files/zip/cfdi.xml +++ b/tests/_files/zip/cfdi.xml @@ -36,6 +36,6 @@ + - diff --git a/tests/_files/zip/cfdi.zip b/tests/_files/zip/cfdi.zip index d9a4fee..cd4c1a0 100644 Binary files a/tests/_files/zip/cfdi.zip and b/tests/_files/zip/cfdi.zip differ diff --git a/tests/_files/zip/metadata.zip b/tests/_files/zip/metadata.zip index 7be8527..adeaf22 100644 Binary files a/tests/_files/zip/metadata.zip and b/tests/_files/zip/metadata.zip differ