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