Skip to content

Commit

Permalink
Merge pull request #737 from KhorneHoly/main
Browse files Browse the repository at this point in the history
Check multiple possible datetime formats before throwing an exception
  • Loading branch information
jlevers committed Jun 21, 2024
2 parents 659591f + ef1f443 commit ee73b2a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 7 deletions.
9 changes: 9 additions & 0 deletions src/Exceptions/UnknownDatetimeFormatException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace SellingPartnerApi\Exceptions;

use Exception;

class UnknownDatetimeFormatException extends Exception {}
38 changes: 31 additions & 7 deletions src/Traits/Deserializes.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@
namespace SellingPartnerApi\Traits;

use DateTime;
use DateTimeInterface;
use ReflectionClass;
use SellingPartnerApi\Exceptions\InvalidAttributeTypeException;
use SellingPartnerApi\Exceptions\UnknownDatetimeFormatException;

trait Deserializes
{
use HasComplexArrayTypes;

protected static string $datetimeFormat = 'Y-m-d\TH:i:s\Z';
protected static string $dateFormat = 'Y-m-d';
protected static array $validDatetimeFormats = [
'Y-m-d\TH:i:s\Z',
DATE_ATOM,
'Y-m-d'
];

public static function deserialize(mixed $data): mixed
{
Expand Down Expand Up @@ -71,7 +79,7 @@ protected static function deserializeValue(mixed $value, array|string $type): mi
'float' => (float) $value,
'bool' => (bool) $value,
'string' => (string) $value,
'date', 'datetime' => DateTime::createFromFormat(static::$datetimeFormat, $value),
'date', 'datetime' => static::convertValueToDateTime($value),
'array', 'mixed' => $value,
'null' => null,
default => chr(0),
Expand All @@ -83,12 +91,8 @@ protected static function deserializeValue(mixed $value, array|string $type): mi

if (! class_exists($type) && ! interface_exists($type)) {
throw new InvalidAttributeTypeException("Neither the Class nor Interface `$type` exists");
} elseif ($type == \DateTimeInterface::class) {
if (strlen($value) === 10) {
return DateTime::createFromFormat('Y-m-d', $value);
} else {
return DateTime::createFromFormat(static::$datetimeFormat, $value);
}
} elseif ($type == DateTimeInterface::class) {
return static::convertValueToDateTime($value);
}

$deserialized = $type::deserialize($value);
Expand All @@ -112,4 +116,24 @@ protected static function deserializeValue(mixed $value, array|string $type): mi

throw new InvalidAttributeTypeException("Invalid type `$type`");
}

protected static function convertValueToDateTime(string $value): DateTime
{
foreach (static::$validDatetimeFormats as $validDatetimeFormat) {
try {
$returnValue = DateTime::createFromFormat($validDatetimeFormat, $value);
// Only return a valid object, else try again until failure
if ($returnValue instanceof DateTimeInterface) {
return $returnValue;
}

continue;
} catch (\Exception) {
// continue with the next format if there's one
continue;
}
}

throw new UnknownDatetimeFormatException("The value `$value` uses a unknown DateTime format.");
}
}
38 changes: 38 additions & 0 deletions tests/Seller/ReportsV20210630/Responses/ReportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Seller\ReportsV20210630\Responses;

use SellingPartnerApi\Exceptions\UnknownDatetimeFormatException;
use SellingPartnerApi\Seller\ReportsV20210630\Responses\Report;
use PHPUnit\Framework\TestCase;

class ReportTest extends TestCase
{
public function testDeserialize()
{
$nullResult = Report::deserialize(null);
$this->assertNull($nullResult);
}

public function testDeserializeUnknownDateTime()
{
// German DateTime Format should throw an exception as it is not one of the valid formats
$this->expectException(UnknownDatetimeFormatException::class);
Report::deserialize([
'createdTime' => '20.06.2024 17:15:33'
]);
}

public function testDeserializeDateTime()
{
$now = new \DateTime();
$result = Report::deserialize([
'reportId' => 12345,
'reportType' => 'TEST_REPORT',
'createdTime' => $now->format(DATE_ATOM),
'processingStatus' => 'IN_QUEUE'
]);
$this->assertNotNull($result);
$this->assertInstanceOf(\DateTimeInterface::class, $result->createdTime);
}
}

0 comments on commit ee73b2a

Please sign in to comment.