diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 35acac9..c9157a8 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -11,14 +11,10 @@ jobs: strategy: matrix: php-version: - - "7.4" - - "8.0" - - "8.1" + - "8.2" deps: - "normal" - include: - - deps: "low" - php-version: "7.4" + - "low" steps: - name: "Checkout" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 7f7fb9d..f744fb4 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -11,9 +11,7 @@ jobs: strategy: matrix: php-version: - - "7.4" - - "8.0" - - "8.1" + - "8.2" steps: - name: "Checkout" uses: "actions/checkout@v2" diff --git a/.gitignore b/.gitignore index 469e7c6..923adf2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ composer.lock /.idea /.env* /composer.phar +/.phpunit.cache diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index c51474e..2393b5a 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -20,7 +20,7 @@ 'strict_param' => false, 'array_syntax' => ['syntax' => 'short'], 'concat_space' => ['spacing' => 'one'], - 'phpdoc_align' => [], + 'phpdoc_align' => ['align' => 'left'], 'phpdoc_summary' => false, 'void_return' => false, 'phpdoc_var_without_name' => false, diff --git a/composer.json b/composer.json index fff6b9d..a87b475 100755 --- a/composer.json +++ b/composer.json @@ -4,25 +4,24 @@ "type": "symfony-bundle", "license": "MIT", "require": { - "php": ">=7.4|^8.0", + "php": "^8.2", "ext-json": "*", "guzzlehttp/guzzle": "^6.0|^7.0", - "marc-mabe/php-enum": "^3.0|^4.3", "psr/log": "^1.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0", - "webmozart/assert": "^1.10" + "symfony/http-kernel": "^7.1", + "symfony/property-info": "^7.1", + "symfony/serializer": "^7.1", + "webmozart/assert": "^1.11" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.4", - "matthiasnoback/symfony-config-test": "^4.3", - "phpro/grumphp": "^1.5.0", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^9.5", + "friendsofphp/php-cs-fixer": "^3.64", + "matthiasnoback/symfony-config-test": "^5.2", + "phpro/grumphp": "^2.6", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^10.5", "roave/security-advisories": "dev-master", - "symfony/phpunit-bridge": "6.1.*" + "symfony/phpunit-bridge": "^7.1" }, "autoload": { "psr-4": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 78a21ae..7814aff 100755 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,29 +1,22 @@ + - ./tests - - - - diff --git a/src/Response/Enum/ApmType.php b/src/Response/Enum/ApmType.php index a06d8b8..f38f881 100644 --- a/src/Response/Enum/ApmType.php +++ b/src/Response/Enum/ApmType.php @@ -2,32 +2,10 @@ namespace Answear\FoxPostParcel\Response\Enum; -use MabeEnum\Enum; - -class ApmType extends Enum +enum ApmType: string { - public const UNKNOWN = 'Unknown'; - public const ROLLKON = 'Rollkon'; - public const CLEVERON = 'Cleveron'; - public const KEBA = 'Keba'; - - public static function unknown(): self - { - return static::get(self::UNKNOWN); - } - - public static function rollkon(): self - { - return static::get(self::ROLLKON); - } - - public static function cleveron(): self - { - return static::get(self::CLEVERON); - } - - public static function keba(): self - { - return static::get(self::KEBA); - } + case Unknown = 'Unknown'; + case Rollkon = 'Rollkon'; + case Cleveron = 'Cleveron'; + case Keba = 'Keba'; } diff --git a/src/Response/Enum/DayType.php b/src/Response/Enum/DayType.php index b2172a6..d477a0e 100644 --- a/src/Response/Enum/DayType.php +++ b/src/Response/Enum/DayType.php @@ -4,50 +4,13 @@ namespace Answear\FoxPostParcel\Response\Enum; -use MabeEnum\Enum; - -class DayType extends Enum +enum DayType: string { - public const MONDAY = 'hetfo'; - public const TUESDAY = 'kedd'; - public const WEDNESDAY = 'szerda'; - public const THURSDAY = 'csutortok'; - public const FRIDAY = 'pentek'; - public const SATURDAY = 'szombat'; - public const SUNDAY = 'vasarnap'; - - public static function friday(): self - { - return static::get(static::FRIDAY); - } - - public static function thursday(): self - { - return static::get(static::THURSDAY); - } - - public static function wednesday(): self - { - return static::get(static::WEDNESDAY); - } - - public static function tuesday(): self - { - return static::get(static::TUESDAY); - } - - public static function monday(): self - { - return static::get(static::MONDAY); - } - - public static function sunday(): self - { - return static::get(static::SUNDAY); - } - - public static function saturday(): self - { - return static::get(static::SATURDAY); - } + case Monday = 'hetfo'; + case Tuesday = 'kedd'; + case Wednesday = 'szerda'; + case Thursday = 'csutortok'; + case Friday = 'pentek'; + case Saturday = 'szombat'; + case Sunday = 'vasarnap'; } diff --git a/src/Response/GetParcelShopsResponse.php b/src/Response/GetParcelShopsResponse.php index a023c75..b22a728 100644 --- a/src/Response/GetParcelShopsResponse.php +++ b/src/Response/GetParcelShopsResponse.php @@ -7,18 +7,16 @@ use Answear\FoxPostParcel\Response\Struct\ParcelShop; use Answear\FoxPostParcel\Response\Struct\ParcelShopCollection; -class GetParcelShopsResponse +readonly class GetParcelShopsResponse { - public ParcelShopCollection $parcelShopCollection; - - public function __construct(ParcelShopCollection $parcelShopCollection) - { - $this->parcelShopCollection = $parcelShopCollection; + public function __construct( + public ParcelShopCollection $parcelShopCollection, + ) { } public static function fromArray(array $arrayResponse): self { - return new self(new ParcelShopCollection(\array_map(fn($pointData) => ParcelShop::fromArray($pointData), $arrayResponse))); + return new self(new ParcelShopCollection(\array_map(static fn($pointData) => ParcelShop::fromArray($pointData), $arrayResponse))); } public function getParcelShopCollection(): ParcelShopCollection diff --git a/src/Response/Struct/Address.php b/src/Response/Struct/Address.php index 6684511..4ec6405 100644 --- a/src/Response/Struct/Address.php +++ b/src/Response/Struct/Address.php @@ -4,13 +4,16 @@ use Webmozart\Assert\Assert; -class Address +readonly class Address { - public string $zipCode; - public string $city; - public string $street; - public string $fullAddress; - public ?string $addressDescription; + public function __construct( + public string $zipCode, + public string $city, + public string $street, + public string $fullAddress, + public ?string $addressDescription, + ) { + } public static function fromArray(array $parcelShopData): self { @@ -20,14 +23,12 @@ public static function fromArray(array $parcelShopData): self Assert::stringNotEmpty($parcelShopData['address']); Assert::string($parcelShopData['findme']); - $address = new self(); - - $address->zipCode = $parcelShopData['zip']; - $address->city = $parcelShopData['city']; - $address->street = $parcelShopData['street']; - $address->fullAddress = $parcelShopData['address']; - $address->addressDescription = empty($parcelShopData['findme']) ? null : $parcelShopData['findme']; - - return $address; + return new self( + $parcelShopData['zip'], + $parcelShopData['city'], + $parcelShopData['street'], + $parcelShopData['address'], + empty($parcelShopData['findme']) ? null : $parcelShopData['findme'] + ); } } diff --git a/src/Response/Struct/Coordinates.php b/src/Response/Struct/Coordinates.php index f47aba5..bcabbf3 100644 --- a/src/Response/Struct/Coordinates.php +++ b/src/Response/Struct/Coordinates.php @@ -6,17 +6,13 @@ use Webmozart\Assert\Assert; -class Coordinates +readonly class Coordinates { - public float $latitude; - public float $longitude; - - public function __construct(float $latitude, float $longitude) - { + public function __construct( + public float $latitude, + public float $longitude, + ) { Assert::range($latitude, -90, 90); Assert::range($longitude, -180, 180); - - $this->latitude = $latitude; - $this->longitude = $longitude; } } diff --git a/src/Response/Struct/ParcelShop.php b/src/Response/Struct/ParcelShop.php index 23bba89..02c6ced 100644 --- a/src/Response/Struct/ParcelShop.php +++ b/src/Response/Struct/ParcelShop.php @@ -5,19 +5,22 @@ use Answear\FoxPostParcel\Response\Enum\ApmType; use Webmozart\Assert\Assert; -class ParcelShop +readonly class ParcelShop { - public int $placeId; - public string $operatorId; - public string $name; - public Coordinates $coordinates; - public Address $address; - public bool $isOutdoor; - public ApmType $apmType; /** - * @var WorkingHours[] + * @param WorkingHours[] $workingHours */ - public array $workingHours = []; + public function __construct( + public int $placeId, + public string $operatorId, + public string $name, + public Coordinates $coordinates, + public Address $address, + public bool $isOutdoor, + public ApmType $apmType, + public array $workingHours, + ) { + } public static function fromArray(array $parcelShopData): self { @@ -30,33 +33,29 @@ public static function fromArray(array $parcelShopData): self Assert::string($parcelShopData['apmType']); Assert::allNotEmpty($parcelShopData['open']); - $parcelShop = new self(); - $address = Address::fromArray($parcelShopData); - - $parcelShop->address = $address; - $parcelShop->placeId = $parcelShopData['place_id']; - $parcelShop->operatorId = $parcelShopData['operator_id']; - $parcelShop->name = $parcelShopData['name']; - $parcelShop->coordinates = new Coordinates($parcelShopData['geolat'], $parcelShopData['geolng']); - $parcelShop->isOutdoor = $parcelShopData['isOutdoor']; - $parcelShop->apmType = self::getApmType($parcelShopData['apmType']); - + $workingHours = []; foreach ($parcelShopData['open'] as $day => $workingHoursString) { - $workingHours = WorkingHours::fromArray($day, $workingHoursString); - if (null !== $workingHours) { - $parcelShop->workingHours[] = $workingHours; - } + $workingHours[] = WorkingHours::fromArray($day, $workingHoursString); } - return $parcelShop; + return new self( + $parcelShopData['place_id'], + $parcelShopData['operator_id'], + $parcelShopData['name'], + new Coordinates($parcelShopData['geolat'], $parcelShopData['geolng']), + Address::fromArray($parcelShopData), + $parcelShopData['isOutdoor'], + self::getApmType($parcelShopData['apmType']), + $workingHours + ); } private static function getApmType(string $apmTypeValue): ApmType { try { - return ApmType::byValue($apmTypeValue); - } catch (\InvalidArgumentException $exception) { - return ApmType::unknown(); + return ApmType::from($apmTypeValue); + } catch (\ValueError) { + return ApmType::Unknown; } } } diff --git a/src/Response/Struct/ParcelShopCollection.php b/src/Response/Struct/ParcelShopCollection.php index 4c2a49d..97cd02b 100644 --- a/src/Response/Struct/ParcelShopCollection.php +++ b/src/Response/Struct/ParcelShopCollection.php @@ -6,22 +6,19 @@ use Webmozart\Assert\Assert; -class ParcelShopCollection implements \Countable, \IteratorAggregate +readonly class ParcelShopCollection implements \Countable, \IteratorAggregate { /** - * @var ParcelShop[] + * @param ParcelShop[] $parcelShops */ - private array $parcelShops; - - public function __construct(array $parcelShops) - { + public function __construct( + public array $parcelShops, + ) { Assert::allIsInstanceOf($parcelShops, ParcelShop::class); - - $this->parcelShops = $parcelShops; } /** - * @return ParcelShop[]|\Traversable + * @return \Traversable */ public function getIterator(): \Traversable { diff --git a/src/Response/Struct/WorkingHours.php b/src/Response/Struct/WorkingHours.php index 4e728f0..a23bf41 100644 --- a/src/Response/Struct/WorkingHours.php +++ b/src/Response/Struct/WorkingHours.php @@ -5,19 +5,14 @@ use Answear\FoxPostParcel\Response\Enum\DayType; use Webmozart\Assert\Assert; -class WorkingHours +readonly class WorkingHours { - public DayType $dayType; - public bool $isOpen; - public ?string $from; - public ?string $to; - - private function __construct(DayType $dayType, bool $isOpen, ?string $from, ?string $to) - { - $this->dayType = $dayType; - $this->from = $from; - $this->to = $to; - $this->isOpen = $isOpen; + private function __construct( + public DayType $dayType, + public bool $isOpen, + public ?string $from, + public ?string $to, + ) { } public static function open(DayType $dayType, string $from, string $to): self @@ -35,13 +30,13 @@ public static function fromArray(string $day, string $workingHoursString): self Assert::stringNotEmpty($day); Assert::stringNotEmpty($workingHoursString); - $dayType = DayType::byValue($day); + $dayType = DayType::from($day); try { [$from, $to] = \preg_split('/(-|–)/', $workingHoursString); return self::open($dayType, $from, $to); - } catch (\Throwable $throwable) { + } catch (\Throwable) { return self::closed($dayType); } } diff --git a/tests/Integration/Command/GetParcelShopsTest.php b/tests/Integration/Command/GetParcelShopsTest.php index 3c218ff..3cdbd1f 100644 --- a/tests/Integration/Command/GetParcelShopsTest.php +++ b/tests/Integration/Command/GetParcelShopsTest.php @@ -9,6 +9,7 @@ use Answear\FoxPostParcel\Tests\Traits\ResponseTrait; use Answear\FoxPostParcel\Tests\Util\FileUtil; use GuzzleHttp\Psr7\Response; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; class GetParcelShopsTest extends TestCase @@ -16,9 +17,7 @@ class GetParcelShopsTest extends TestCase use MockGuzzleTrait; use ResponseTrait; - /** - * @test - */ + #[Test] public function successfullyGetPoints(): void { $command = $this->getCommand(); diff --git a/tests/Traits/MockGuzzleTrait.php b/tests/Traits/MockGuzzleTrait.php index ff3e44b..6094b90 100644 --- a/tests/Traits/MockGuzzleTrait.php +++ b/tests/Traits/MockGuzzleTrait.php @@ -25,7 +25,7 @@ public function setupGuzzleClient(): Client return new Client(['handler' => $handlerStack]); } - public function mockGuzzleResponse(Response $response) + public function mockGuzzleResponse(Response $response): void { $this->guzzleHandler->append($response); } diff --git a/tests/Traits/ResponseTrait.php b/tests/Traits/ResponseTrait.php index 1d15952..6eba580 100644 --- a/tests/Traits/ResponseTrait.php +++ b/tests/Traits/ResponseTrait.php @@ -19,63 +19,57 @@ public function getExpectedParcelShops(): ParcelShopCollection private function getFirstParcelShop(): ParcelShop { - $parcelShop = new ParcelShop(); - $parcelShop->placeId = 630087; - $parcelShop->operatorId = 'hu1510'; - $parcelShop->name = 'Nyíregyháza MOL Vasgyár utca'; - $parcelShop->coordinates = new Coordinates(47.954398, 21.704269); - - $address = new Address(); - $address->zipCode = '4400'; - $address->city = 'Nyíregyháza'; - $address->street = 'Vasgyár utca 18.'; - $address->fullAddress = '4400 Nyíregyháza, Vasgyár utca 18.'; - $address->addressDescription = 'HU1510 számú kültéri automatánk a benzinkút épülete mellett, a Vasgyár utca felől található.'; - - $parcelShop->address = $address; - $parcelShop->isOutdoor = true; - $parcelShop->apmType = ApmType::unknown(); - $parcelShop->workingHours = [ - WorkingHours::open(DayType::monday(), '00:00', '24:00'), - WorkingHours::open(DayType::tuesday(), '00:00', '24:00'), - WorkingHours::open(DayType::wednesday(), '00:00', '24:00'), - WorkingHours::open(DayType::thursday(), '00:00', '24:00'), - WorkingHours::open(DayType::friday(), '00:00', '24:00'), - WorkingHours::open(DayType::saturday(), '00:00', '24:00'), - WorkingHours::open(DayType::sunday(), '00:00', '24:00'), - ]; - - return $parcelShop; + return new ParcelShop( + 630087, + 'hu1510', + 'Nyíregyháza MOL Vasgyár utca', + new Coordinates(47.954398, 21.704269), + new Address( + '4400', + 'Nyíregyháza', + 'Vasgyár utca 18.', + '4400 Nyíregyháza, Vasgyár utca 18.', + 'HU1510 számú kültéri automatánk a benzinkút épülete mellett, a Vasgyár utca felől található.' + ), + true, + ApmType::Unknown, + [ + WorkingHours::open(DayType::Monday, '00:00', '24:00'), + WorkingHours::open(DayType::Tuesday, '00:00', '24:00'), + WorkingHours::open(DayType::Wednesday, '00:00', '24:00'), + WorkingHours::open(DayType::Thursday, '00:00', '24:00'), + WorkingHours::open(DayType::Friday, '00:00', '24:00'), + WorkingHours::open(DayType::Saturday, '00:00', '24:00'), + WorkingHours::open(DayType::Sunday, '00:00', '24:00'), + ] + ); } private function getSecondParcelShop(): ParcelShop { - $parcelShop = new ParcelShop(); - $parcelShop->placeId = 629492; - $parcelShop->operatorId = 'hu1508'; - $parcelShop->name = 'Győr Tesco Szigethy Attila út'; - $parcelShop->coordinates = new Coordinates(47.677188, 17.653352); - - $address = new Address(); - $address->zipCode = '9023'; - $address->city = 'Győr'; - $address->street = 'Szigethy Attila út 112.'; - $address->fullAddress = '9023 Győr, Szigethy Attila út 112.'; - $address->addressDescription = 'HU1508 számú kültéri automatánk az áruház bejáratától balra, a Szigethy út felől található.'; - - $parcelShop->address = $address; - $parcelShop->isOutdoor = true; - $parcelShop->apmType = ApmType::rollkon(); - $parcelShop->workingHours = [ - WorkingHours::open(DayType::monday(), '00:00', '24:00'), - WorkingHours::open(DayType::tuesday(), '00:00', '24:00'), - WorkingHours::open(DayType::wednesday(), '00:00', '24:00'), - WorkingHours::open(DayType::thursday(), '00:00', '24:00'), - WorkingHours::open(DayType::friday(), '00:00', '24:00'), - WorkingHours::open(DayType::saturday(), '00:00', '24:00'), - WorkingHours::open(DayType::sunday(), '00:00', '24:00'), - ]; - - return $parcelShop; + return new ParcelShop( + 629492, + 'hu1508', + 'Győr Tesco Szigethy Attila út', + new Coordinates(47.677188, 17.653352), + new Address( + '9023', + 'Győr', + 'Szigethy Attila út 112.', + '9023 Győr, Szigethy Attila út 112.', + 'HU1508 számú kültéri automatánk az áruház bejáratától balra, a Szigethy út felől található.' + ), + true, + ApmType::Rollkon, + [ + WorkingHours::open(DayType::Monday, '00:00', '24:00'), + WorkingHours::open(DayType::Tuesday, '00:00', '24:00'), + WorkingHours::open(DayType::Wednesday, '00:00', '24:00'), + WorkingHours::open(DayType::Thursday, '00:00', '24:00'), + WorkingHours::open(DayType::Friday, '00:00', '24:00'), + WorkingHours::open(DayType::Saturday, '00:00', '24:00'), + WorkingHours::open(DayType::Sunday, '00:00', '24:00'), + ] + ); } } diff --git a/tests/Unit/Response/Struct/WorkingHoursTest.php b/tests/Unit/Response/Struct/WorkingHoursTest.php index 22d381e..1dbcb63 100644 --- a/tests/Unit/Response/Struct/WorkingHoursTest.php +++ b/tests/Unit/Response/Struct/WorkingHoursTest.php @@ -4,36 +4,36 @@ use Answear\FoxPostParcel\Response\Enum\DayType; use Answear\FoxPostParcel\Response\Struct\WorkingHours; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; class WorkingHoursTest extends TestCase { - /** - * @test - * @dataProvider provideWorkingHoursString - */ + #[Test] + #[DataProvider('provideWorkingHoursString')] public function workingHoursParsedCorrectly(string $workingHoursString, WorkingHours $expectedWorkingHours): void { - $workingHours = WorkingHours::fromArray(DayType::monday()->getValue(), $workingHoursString); + $workingHours = WorkingHours::fromArray(DayType::Monday->value, $workingHoursString); $this->assertEquals($expectedWorkingHours, $workingHours); } - public function provideWorkingHoursString(): iterable + public static function provideWorkingHoursString(): iterable { yield 'working day' => [ '7:00-19:00', - WorkingHours::open(DayType::monday(), '7:00', '19:00'), + WorkingHours::open(DayType::Monday, '7:00', '19:00'), ]; yield 'working day with non breaking hyphen' => [ '7:00–19:00', - WorkingHours::open(DayType::monday(), '7:00', '19:00'), + WorkingHours::open(DayType::Monday, '7:00', '19:00'), ]; yield 'closed' => [ 'zárva', - WorkingHours::closed(DayType::monday()), + WorkingHours::closed(DayType::Monday), ]; } } diff --git a/tests/Util/FileUtil.php b/tests/Util/FileUtil.php index 81c167f..735a73d 100644 --- a/tests/Util/FileUtil.php +++ b/tests/Util/FileUtil.php @@ -13,11 +13,4 @@ public static function getFileContents(string $filePath): string return $contents; } - - public static function decodeJsonFromFile(string $filePath): array - { - $json = self::getFileContents($filePath); - - return \json_decode($json, true, 512, JSON_THROW_ON_ERROR); - } }