diff --git a/examples/AccountsApi/AccountsApiExample.php b/examples/AccountsApi/AccountsApiExample.php index 282504b..03735b4 100644 --- a/examples/AccountsApi/AccountsApiExample.php +++ b/examples/AccountsApi/AccountsApiExample.php @@ -22,6 +22,7 @@ public function __construct() public function runAllExamples() { $this + ->createMerchant() ->createAccount() ->getAccounts() ->getCategories() @@ -105,6 +106,15 @@ public function createAccount() return $this; } + public function createMerchant() + { + $merchantConfig = $this->getNewMerchantConfig(); + $newMerchant = $this->TpayApi->accounts()->createMerchant($merchantConfig); + var_dump($newMerchant); + + return $this; + } + private function getNewAccountConfig() { $offerCode = 'PTON8'; @@ -148,6 +158,43 @@ private function getNewAccountConfig() 'notifyByEmail' => true, ]; } + + private function getNewMerchantConfig() + { + $offerCode = 'PTON8'; + $pos = [ + 'name' => 'Przykladowe Zakupy Online', + 'url' => 'https://przykladowezakupy.pl', + ]; + $address1 = [ + 'name' => 'Example Sp. z o.o.', + 'street' => 'Ul. Jelenia', + 'houseNumber' => '123', + 'postalCode' => '54-134', + 'city' => 'Warszawa', + 'country' => 'PL', + 'isInvoice' => true, + 'isMain' => true, + 'isCorrespondence' => true, + ]; + $contactPerson = [ + 'name' => 'Jan', + 'surname' => 'Kowalski', + 'phone' => '(0) 111222333', + 'email' => 'jan.kowalski@example.com', + ]; + + return [ + 'offerCode' => $offerCode, + 'email' => 'merchant@example.com', + 'taxId' => '7773061579', + 'legalForm' => 3, + 'categoryId' => 62, + 'website' => [$pos], + 'address' => [$address1], + 'contactPerson' => [$contactPerson], + ]; + } } (new AccountsApiExample())->runAllExamples(); diff --git a/src/Api/Accounts/AccountsApi.php b/src/Api/Accounts/AccountsApi.php index 54d016e..0745ac1 100644 --- a/src/Api/Accounts/AccountsApi.php +++ b/src/Api/Accounts/AccountsApi.php @@ -4,6 +4,7 @@ use Tpay\OpenApi\Api\ApiAction; use Tpay\OpenApi\Model\Objects\RequestBody\Account; +use Tpay\OpenApi\Model\Objects\RequestBody\Merchant; class AccountsApi extends ApiAction { @@ -60,12 +61,24 @@ public function getBalanceByAccountId($accountId) return $this->run(static::GET, sprintf('/accounts/%s/balance', $accountId)); } - /** @param array $fields */ + /** + * @deprecated Use createMerchant() instead + * + * @param array $fields + */ public function createAccount($fields) { + trigger_error(sprintf('Method %s is deprecated.', __METHOD__), E_USER_DEPRECATED); + return $this->run(static::POST, '/accounts', $fields, new Account()); } + /** @param array $fields */ + public function createMerchant($fields) + { + return $this->run(static::POST, '/v1/accounts/merchant', $fields, new Merchant()); + } + public function getMcc() { return $this->run(static::GET, '/accounts/mcc'); diff --git a/src/Factory/ArrayObjectFactory.php b/src/Factory/ArrayObjectFactory.php new file mode 100644 index 0000000..983d97c --- /dev/null +++ b/src/Factory/ArrayObjectFactory.php @@ -0,0 +1,56 @@ +getName())); + } + } + + if ($parentObject instanceof Account) { + switch ($fieldName) { + case 'address': + return new AccountAddress(); + case 'website': + return new AccountPointOfSale(); + case 'person': + return new Person(); + default: + throw new InvalidArgumentException(sprintf('Unsupported field "%s" in %s', $fieldName, $parentObject->getName())); + } + } + + throw new InvalidArgumentException(sprintf('Field %s as array is not supported in %s object', $fieldName, $parentObject->getName())); + } +} diff --git a/src/Manager/Manager.php b/src/Manager/Manager.php index 3624987..751b551 100644 --- a/src/Manager/Manager.php +++ b/src/Manager/Manager.php @@ -29,6 +29,7 @@ public function setFields($fields, $strictCheck = true) $this->requestBody->strictCheck = $strictCheck; $this->requestBody->setObjectValues($this->requestBody, $fields); $this->ObjectsValidator->isSetRequiredFields($this->requestBody); + $this->ObjectsValidator->checkUniqueFields($this->requestBody); return $this; } diff --git a/src/Model/Fields/Address/FlatNumber.php b/src/Model/Fields/Address/FlatNumber.php new file mode 100644 index 0000000..934e741 --- /dev/null +++ b/src/Model/Fields/Address/FlatNumber.php @@ -0,0 +1,15 @@ + Country::class, 'friendlyName' => FriendlyName::class, 'houseNumber' => HouseNumber::class, + 'roomNumber' => RoomNumber::class, 'isCorrespondence' => IsCorrespondence::class, 'isInvoice' => IsInvoice::class, 'isMain' => IsMain::class, 'name' => Name::class, 'phone' => Phone::class, 'postalCode' => PostalCode::class, - 'roomNumber' => RoomNumber::class, 'street' => Street::class, ]; @@ -45,6 +45,9 @@ class Address extends Objects /** @var HouseNumber */ public $houseNumber; + /** @var RoomNumber */ + public $roomNumber; + /** @var IsCorrespondence */ public $isCorrespondence; @@ -63,9 +66,6 @@ class Address extends Objects /** @var PostalCode */ public $postalCode; - /** @var RoomNumber */ - public $roomNumber; - /** @var Street */ public $street; diff --git a/src/Model/Objects/Accounts/PointOfSale.php b/src/Model/Objects/Accounts/PointOfSale.php index 06d95ef..0a0382f 100644 --- a/src/Model/Objects/Accounts/PointOfSale.php +++ b/src/Model/Objects/Accounts/PointOfSale.php @@ -35,18 +35,18 @@ class PointOfSale extends Objects /** @var Name */ public $name; - /** @var PointOfSaleDate */ - public $date; - - /** @var PointOfSaleSettings */ - public $settings; - /** @var Url */ public $url; /** @var Description */ public $description; + /** @var PointOfSaleDate */ + public $date; + + /** @var PointOfSaleSettings */ + public $settings; + public function getRequiredFields() { return [ diff --git a/src/Model/Objects/Merchant/Address.php b/src/Model/Objects/Merchant/Address.php new file mode 100644 index 0000000..8e920d5 --- /dev/null +++ b/src/Model/Objects/Merchant/Address.php @@ -0,0 +1,78 @@ + City::class, + 'country' => Country::class, + 'houseNumber' => HouseNumber::class, + 'flatNumber' => FlatNumber::class, + 'isCorrespondence' => IsCorrespondence::class, + 'isInvoice' => IsInvoice::class, + 'isMain' => IsMain::class, + 'name' => Name::class, + 'phone' => Phone::class, + 'postalCode' => PostalCode::class, + 'street' => Street::class, + ]; + + /** @var City */ + public $city; + + /** @var Country */ + public $country; + + /** @var HouseNumber */ + public $houseNumber; + + /** @var FlatNumber */ + public $flatNumber; + + /** @var IsCorrespondence */ + public $isCorrespondence; + + /** @var IsInvoice */ + public $isInvoice; + + /** @var IsMain */ + public $isMain; + + /** @var Name */ + public $name; + + /** @var Phone */ + public $phone; + + /** @var PostalCode */ + public $postalCode; + + /** @var Street */ + public $street; + + public function getRequiredFields() + { + return [ + $this->name, + $this->street, + $this->houseNumber, + $this->postalCode, + $this->city, + $this->country, + ]; + } +} diff --git a/src/Model/Objects/Merchant/ContactPerson.php b/src/Model/Objects/Merchant/ContactPerson.php new file mode 100644 index 0000000..ed82296 --- /dev/null +++ b/src/Model/Objects/Merchant/ContactPerson.php @@ -0,0 +1,31 @@ + Name::class, + 'surname' => Surname::class, + 'phone' => Phone::class, + 'email' => Email::class, + ]; + + /** @var Name */ + public $name; + + /** @var Surname */ + public $surname; + + /** @var Phone */ + public $phone; + + /** @var Email */ + public $email; +} diff --git a/src/Model/Objects/Merchant/PointOfSale.php b/src/Model/Objects/Merchant/PointOfSale.php new file mode 100644 index 0000000..268b8e3 --- /dev/null +++ b/src/Model/Objects/Merchant/PointOfSale.php @@ -0,0 +1,29 @@ + Name::class, + 'url' => Url::class, + ]; + + /** @var Name */ + public $name; + + /** @var Url */ + public $url; + + public function getRequiredFields() + { + return [ + $this->name, + $this->url, + ]; + } +} diff --git a/src/Model/Objects/Objects.php b/src/Model/Objects/Objects.php index 283c9e8..67d2464 100644 --- a/src/Model/Objects/Objects.php +++ b/src/Model/Objects/Objects.php @@ -4,17 +4,23 @@ use InvalidArgumentException; use ReflectionClass; +use Tpay\OpenApi\Factory\ArrayObjectFactory; use Tpay\OpenApi\Model\Fields\Field; class Objects implements ObjectsInterface { const OBJECT_FIELDS = []; + const UNIQUE_FIELDS = []; public $strictCheck = true; + /** @var ArrayObjectFactory */ + private $factory; + public function __construct() { $this->injectObjectFields(static::OBJECT_FIELDS); + $this->factory = new ArrayObjectFactory(); } /** @return array */ @@ -85,6 +91,10 @@ private function setObjectsInArray($object, $fieldValue, $fieldName) $this->setObjectValues($object->{$fieldName}->{$field}, $value); } if (is_array($object->{$fieldName})) { + if (!isset($object->{$fieldName}[$field])) { + $object->{$fieldName}[] = $this->factory->create($fieldName, $object); + } + $this->setObjectValues($object->{$fieldName}[$field], $value); } } else { diff --git a/src/Model/Objects/ObjectsValidator.php b/src/Model/Objects/ObjectsValidator.php index a689e53..e773cee 100644 --- a/src/Model/Objects/ObjectsValidator.php +++ b/src/Model/Objects/ObjectsValidator.php @@ -7,6 +7,18 @@ class ObjectsValidator { + /** @param Objects $objectClass */ + public function checkUniqueFields($objectClass) + { + foreach ($objectClass::UNIQUE_FIELDS as $collectionName => $fieldRules) { + $collection = isset($objectClass->{$collectionName}) ? $objectClass->{$collectionName} : []; + + foreach ($fieldRules as $fieldName => $uniqueValue) { + $this->validateUniqueField($collection, $fieldName, $uniqueValue); + } + } + } + /** * @param Objects $objectClass * @@ -38,4 +50,41 @@ public function isSetRequiredFields($objectClass) return true; } + + /** + * @param array $objects + * @param mixed $fieldName + * @param mixed $uniqueValue + * + * @throws UnexpectedValueException + */ + private function validateUniqueField(array $objects, $fieldName, $uniqueValue) + { + $count = 0; + + foreach ($objects as $object) { + if (!$object instanceof Objects) { + continue; + } + + if (!property_exists($object, $fieldName)) { + continue; + } + + $field = $object->{$fieldName}; + + if ($field instanceof Field && $field->getValue() === $uniqueValue) { + $count++; + } + + if ($count > 1) { + throw new UnexpectedValueException(sprintf( + 'Field "%s" with value "%s" must be unique across %s objects', + $fieldName, + var_export($uniqueValue, true), + $object->getName() + )); + } + } + } } diff --git a/src/Model/Objects/RequestBody/Merchant.php b/src/Model/Objects/RequestBody/Merchant.php new file mode 100644 index 0000000..fdb9fc4 --- /dev/null +++ b/src/Model/Objects/RequestBody/Merchant.php @@ -0,0 +1,82 @@ + OfferCode::class, + 'email' => Email::class, + 'taxId' => TaxId::class, + 'regon' => Regon::class, + 'krs' => Krs::class, + 'legalForm' => LegalForm::class, + 'categoryId' => CategoryId::class, + 'address' => [Address::class], + 'website' => [PointOfSale::class], + 'contactPerson' => [ContactPerson::class], + 'merchantApiConsent' => MerchantApiConsent::class, + ]; + const UNIQUE_FIELDS = [ + 'address' => ['isMain' => true], + ]; + + /** @var OfferCode */ + public $offerCode; + + /** @var Email */ + public $email; + + /** @var TaxId */ + public $taxId; + + /** @var Regon */ + public $regon; + + /** @var Krs */ + public $krs; + + /** @var LegalForm */ + public $legalForm; + + /** @var CategoryId */ + public $categoryId; + + /** @var Address */ + public $address; + + /** @var PointOfSale */ + public $website; + + /** @var ContactPerson */ + public $contactPerson; + + /** @var MerchantApiConsent */ + public $merchantApiConsent; + + public function getRequiredFields() + { + return [ + $this->offerCode, + $this->email, + $this->taxId, + $this->legalForm, + $this->categoryId, + $this->address, + $this->website, + ]; + } +} diff --git a/tests/Api/Accounts/AccountsApiTest.php b/tests/Api/Accounts/AccountsApiTest.php new file mode 100644 index 0000000..763b624 --- /dev/null +++ b/tests/Api/Accounts/AccountsApiTest.php @@ -0,0 +1,601 @@ +createAccountsApiWithCurlMock('ok'); + + $result = $transactionsApi->createMerchant($merchantData); + + self::assertSame('ok', $result); + } + + /** @dataProvider invalidMerchantData */ + public function testCreatingInvalidMerchant(array $merchantData, $exception, $exceptionMessage) + { + $transactionsApi = $this->createAccountsApiWithCurlMock('error'); + + $this->expectException($exception); + $this->expectExceptionMessage($exceptionMessage); + $transactionsApi->createMerchant($merchantData); + } + + public function validMerchantData() + { + yield 'One Address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + 'isInvoice' => true, + 'isCorrespondence' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + ]; + + yield 'Different Addresses' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica2', + 'houseNumber' => '456', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => false, + 'isInvoice' => true, + ], + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica3', + 'houseNumber' => '789', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => false, + 'isCorrespondence' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + ]; + + yield 'Many websites' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + [ + 'name' => 'www.example2.com', + 'url' => 'https://www.example2.com', + ], + [ + 'name' => 'www.example3.com', + 'url' => 'https://www.example3.com', + ], + ], + ], + ]; + } + + public function invalidMerchantData() + { + yield 'No Offer Code' => [ + [ + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + 'isInvoice' => true, + 'isCorrespondence' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Account\OfferCode" is required in object Merchant', + ]; + + yield 'No email address' => [ + [ + 'offerCode' => 'XXXXX', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Person\Email" is required in object Merchant', + ]; + + yield 'No legalForm' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@example.com', + 'taxId' => '1234567890', + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Account\LegalForm" is required in object Merchant', + ]; + + yield 'No categoryId' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@example.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Identifiers\CategoryId" is required in object Merchant', + ]; + + yield 'Empty address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@example.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 0, + 'address' => [ + ], + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\Name" is required in object Address', + ]; + + yield 'No address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@example.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 0, + 'website' => [ + [ + 'name' => 'www.example.com', + 'url' => 'https://www.example.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\Name" is required in object Address', + ]; + + yield 'Empty website' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@example.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 0, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\PointOfSale\Name" is required in object PointOfSale', + ]; + + yield 'No website' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@example.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 0, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'ulica1', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\PointOfSale\Name" is required in object PointOfSale', + ]; + + yield 'No street in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\Street" is required in object Address', + ]; + + yield 'No house number in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'postalCode' => '11-111', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\HouseNumber" is required in object Address', + ]; + + yield 'No postal code in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'city' => 'Poznań', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\PostalCode" is required in object Address', + ]; + + yield 'No city in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\City" is required in object Address', + ]; + + yield 'No country in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Warszawa', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "Tpay\OpenApi\Model\Fields\Address\Country" is required in object Address', + ]; + + yield 'Too long country in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Warszawa', + 'country' => 'Polska', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => InvalidArgumentException::class, + 'exceptionMessage' => 'Value of field Tpay\OpenApi\Model\Fields\Address\Country is too long. Max allowed 2', + ]; + + yield 'Too short country in address' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Warszawa', + 'country' => 'P', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => InvalidArgumentException::class, + 'exceptionMessage' => 'Value of field Tpay\OpenApi\Model\Fields\Address\Country is too short. Min required 2', + ]; + + yield 'Multi main addresses' => [ + [ + 'offerCode' => 'XXXXX', + 'email' => 'admin@exmaple.com', + 'taxId' => '1234567890', + 'legalForm' => 1, + 'categoryId' => 2, + 'address' => [ + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Warszawa', + 'country' => 'PL', + 'isMain' => true, + ], + [ + 'name' => 'Example Sp.z.o.o', + 'street' => 'glowna', + 'houseNumber' => '123', + 'postalCode' => '11-111', + 'city' => 'Warszawa', + 'country' => 'PL', + 'isMain' => true, + ], + ], + 'website' => [ + [ + 'name' => 'www.example1.com', + 'url' => 'https://www.example1.com', + ], + ], + ], + 'exception' => UnexpectedValueException::class, + 'exceptionMessage' => 'Field "isMain" with value "true" must be unique across Address objects', + ]; + } + + private function createAccountsApiWithCurlMock($response) + { + $accessToken = $this->createMock(AccessToken::class); + + $token = $this->createMock(Token::class); + $token->access_token = $accessToken; + + $transactionsApi = new AccountsApi($token, false); + + CurlMock::setConsecutiveReturnedTransfers(json_encode($response)); + + return $transactionsApi; + } +} diff --git a/tests/Factory/ArrayObjectFactoryTest.php b/tests/Factory/ArrayObjectFactoryTest.php new file mode 100644 index 0000000..2c958a0 --- /dev/null +++ b/tests/Factory/ArrayObjectFactoryTest.php @@ -0,0 +1,110 @@ +create($fieldName, $object); + + $this->assertInstanceOf($expectedResult, $result); + } + + /** @dataProvider invalidObjectProvider */ + public function testInvalidCreate($fieldName, $object, $exception, $exceptionMessage) + { + $factory = new ArrayObjectFactory(); + + $this->expectException($exception); + $this->expectExceptionMessage($exceptionMessage); + + $factory->create($fieldName, $object); + } + + public function validObjectProvider() + { + yield 'merchant Address' => [ + 'fieldName' => 'address', + 'object' => new Merchant(), + 'expectedResult' => MerchantAddress::class, + ]; + + yield 'merchant POS' => [ + 'fieldName' => 'website', + 'object' => new Merchant(), + 'expectedResult' => MerchantPointOfSale::class, + ]; + + yield 'merchant contactPerson' => [ + 'fieldName' => 'contactPerson', + 'object' => new Merchant(), + 'expectedResult' => ContactPerson::class, + ]; + + yield 'account Address' => [ + 'fieldName' => 'address', + 'object' => new Account(), + 'expectedResult' => AccountAddress::class, + ]; + + yield 'account POS' => [ + 'fieldName' => 'website', + 'object' => new Account(), + 'expectedResult' => AccountPointOfSale::class, + ]; + + yield 'account contactPerson' => [ + 'fieldName' => 'person', + 'object' => new Account(), + 'expectedResult' => Person::class, + ]; + } + + public function invalidObjectProvider() + { + yield 'merchant non array field' => [ + 'fieldName' => 'email', + 'object' => new Merchant(), + 'exception' => InvalidArgumentException::class, + 'exceptionMessage' => 'Unsupported field "email" in Merchant', + ]; + + yield 'account non array field' => [ + 'fieldName' => 'taxId', + 'object' => new Account(), + 'exception' => InvalidArgumentException::class, + 'exceptionMessage' => 'Unsupported field "taxId" in Account', + ]; + + yield 'unsupported object' => [ + 'fieldName' => 'amount', + 'object' => new Refund(), + 'exception' => InvalidArgumentException::class, + 'exceptionMessage' => 'Field amount as array is not supported in Refund object', + ]; + + yield 'invalid object type' => [ + 'fieldName' => 'amount', + 'object' => new StdClass(), + 'exception' => InvalidArgumentException::class, + 'exceptionMessage' => 'Parent object must extend Tpay\OpenApi\Model\Objects\Objects, got stdClass', + ]; + } +}