diff --git a/src/Apis/PaymentApiConfigBearerAuth.php b/src/Apis/PaymentApiConfigBearerAuth.php new file mode 100644 index 00000000..b0d166e4 --- /dev/null +++ b/src/Apis/PaymentApiConfigBearerAuth.php @@ -0,0 +1,17 @@ +setFirstname($firstname)->setLastname($lastname); + return self::getCustomer()->setFirstname($firstname)->setLastname($lastname); } /** @@ -58,7 +71,7 @@ public static function createNotRegisteredB2bCustomer( ->setFunction('OWNER') ->setCommercialSector($commercialSector); - return (new Customer()) + return self::getCustomer() ->setFirstname($firstname) ->setLastname($lastname) ->setBirthDate($birthDate) @@ -89,9 +102,17 @@ public static function createRegisteredB2bCustomer( ->setCommercialRegisterNumber($commercialRegisterNumber) ->setCommercialSector($commercialSector); - return (new Customer()) + return self::getCustomer() ->setCompany($company) ->setBillingAddress($billingAddress) ->setCompanyInfo($companyInfo); } + + /** + * @return Customer + */ + protected static function getCustomer(): Customer + { + return (self::$version == 2) ? new CustomerV2() : new Customer(); + } } diff --git a/src/Resources/V2/Customer.php b/src/Resources/V2/Customer.php new file mode 100644 index 00000000..935d3095 --- /dev/null +++ b/src/Resources/V2/Customer.php @@ -0,0 +1,21 @@ + 0; + } } diff --git a/src/Services/ResourceService.php b/src/Services/ResourceService.php index 6de8c083..7accd592 100755 --- a/src/Services/ResourceService.php +++ b/src/Services/ResourceService.php @@ -58,6 +58,7 @@ use UnzerSDK\Resources\TransactionTypes\Chargeback; use UnzerSDK\Resources\TransactionTypes\Payout; use UnzerSDK\Resources\TransactionTypes\Shipment; +use UnzerSDK\Resources\V2\Customer as CustomerV2; use UnzerSDK\Resources\V2\Paypage as PaypageV2; use UnzerSDK\Traits\CanRecur; use UnzerSDK\Unzer; @@ -119,8 +120,8 @@ public function send( string $httpMethod = HttpAdapterInterface::REQUEST_GET, string $apiVersion = Unzer::API_VERSION ): stdClass { - $configClass = $resource->getApiConfig(); - if (!$resource instanceof Token && $configClass::getAuthorizationMethod() === AuthorizationMethods::BEARER) { + $apiConfig = $resource->getApiConfig(); + if (!$resource instanceof Token && $apiConfig::getAuthorizationMethod() === AuthorizationMethods::BEARER) { $this->unzer->prepareJwtToken(); } @@ -648,7 +649,9 @@ public function fetchCustomer($customer): Customer $customerObject = $customer; if (is_string($customer)) { - $customerObject = (new Customer())->setId($customer); + $isUUID = IdService::isUUDIResource($customer); + $customerObject = $isUUID ? new CustomerV2() : new Customer(); + $customerObject->setId($customer); } $this->fetchResource($customerObject->setParentResource($this->unzer)); @@ -658,7 +661,7 @@ public function fetchCustomer($customer): Customer /** * {@inheritDoc} */ - public function fetchCustomerByExtCustomerId(string $customerId): Customer + public function fetchCustomerByExtCustomerId(string $customerId, int $version = 1): Customer { $customerObject = (new Customer())->setCustomerId($customerId); $this->fetchResource($customerObject->setParentResource($this->unzer)); diff --git a/src/Unzer.php b/src/Unzer.php index 733b7e31..45608cfb 100644 --- a/src/Unzer.php +++ b/src/Unzer.php @@ -485,9 +485,9 @@ public function fetchCustomer($customer): Customer /** * {@inheritDoc} */ - public function fetchCustomerByExtCustomerId(string $customerId): Customer + public function fetchCustomerByExtCustomerId(string $customerId, int $version = 1): Customer { - return $this->resourceService->fetchCustomerByExtCustomerId($customerId); + return $this->resourceService->fetchCustomerByExtCustomerId($customerId, $version); } /** diff --git a/test/integration/Resources/CustomerV2Test.php b/test/integration/Resources/CustomerV2Test.php new file mode 100755 index 00000000..d76bac94 --- /dev/null +++ b/test/integration/Resources/CustomerV2Test.php @@ -0,0 +1,457 @@ +getMinimalCustomer(); + $this->assertEmpty($customer->getId()); + $this->getUnzerObject()->createCustomer($customer); + $this->assertNotEmpty($customer->getId()); + + $geoLocation = $customer->getGeoLocation(); + $this->assertNull($geoLocation->getClientIp()); + $this->assertNull($geoLocation->getCountryCode()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $exposeArray = $customer->expose(); + $exposeArray['salutation'] = Salutations::UNKNOWN; + $this->assertEquals($exposeArray, $fetchedCustomer->expose()); + + $geoLocation = $fetchedCustomer->getGeoLocation(); + $this->assertNotEmpty($geoLocation->getClientIp()); + $this->assertNotEmpty($geoLocation->getCountryCode()); + + return $customer; + } + + /** + * Max customer should be creatable via the sdk. + * + * @test + * + * @return Customer + */ + public function maxCustomerCanBeCreatedAndFetched(): Customer + { + $customer = $this->getMaximumCustomer(); + $this->assertEmpty($customer->getId()); + $this->getUnzerObject()->createCustomer($customer); + $this->assertNotEmpty($customer->getId()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals($customer->expose(), $fetchedCustomer->expose()); + + return $customer; + } + + /** + * Verify shipping type can be set for shipping address of customer resource. + * + * @test + */ + public function customerWithShippingTypeCanBeCreatedAndFetched() + { + $customer = $this->getMaximumCustomerInclShippingAddress(); + $customer->getShippingAddress()->setShippingType('shippingType'); + + $this->getUnzerObject()->createCustomer($customer); + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals('shippingType', $fetchedCustomer->getShippingAddress()->getShippingType()); + } + + /** + * @param Customer $customer + * + * @depends maxCustomerCanBeCreatedAndFetched + * + * @test + */ + public function customerCanBeFetchedById(Customer $customer): void + { + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals($customer->getId(), $fetchedCustomer->getId()); + } + + /** + * @depends maxCustomerCanBeCreatedAndFetched + * + * @test + */ + public function customerCanBeFetchedByCustomerId(): void + { + $customerId = 'c' . self::generateRandomId(); + $customer = $this->getMaximumCustomer()->setCustomerId($customerId); + $this->getUnzerObject()->createCustomer($customer); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomerByExtCustomerId($customer->getCustomerId()); + $this->assertEquals($customer->expose(), $fetchedCustomer->expose()); + } + + /** + * @param Customer $customer + * + * @depends maxCustomerCanBeCreatedAndFetched + * + * @test + */ + public function customerCanBeFetchedByObject(Customer $customer): void + { + $customerToFetch = (new Customer())->setId($customer->getId()); + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customerToFetch); + $this->assertEquals($customer->getId(), $fetchedCustomer->getId()); + } + + /** + * @param Customer $customer + * + * @depends maxCustomerCanBeCreatedAndFetched + * + * @test + */ + public function customerCanBeFetchedByObjectWithData(Customer $customer): void + { + $customerToFetch = $this->getMinimalCustomer()->setId($customer->getId()); + $this->assertNotEquals($customer->getFirstname(), $customerToFetch->getFirstname()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customerToFetch); + $this->assertEquals($customer->getFirstname(), $fetchedCustomer->getFirstname()); + } + + /** + * Customer can be referenced by payment. + * + * @test + */ + public function transactionShouldCreateAndReferenceCustomerIfItDoesNotExistYet(): void + { + $customerId = 'c' . self::generateRandomId(); + $customer = $this->getMaximumCustomerInclShippingAddress()->setCustomerId($customerId); + + /** @var Paypal $paypal */ + $paypal = $this->getUnzerObject()->createPaymentType(new Paypal()); + $authorization = $paypal->authorize(12.0, 'EUR', self::RETURN_URL, $customer); + + $secPayment = $this->getUnzerObject()->fetchPayment($authorization->getPayment()->getId()); + + /** @var Customer $secCustomer */ + $secCustomer = $secPayment->getCustomer(); + $this->assertNotNull($secCustomer); + $this->assertEquals($customer->expose(), $secCustomer->expose()); + } + + /** + * Customer can be referenced by payment. + * + * @test + */ + public function transactionShouldReferenceCustomerIfItExist(): void + { + $customer = $this->getMaximumCustomer(); + $this->getUnzerObject()->createCustomer($customer); + + /** @var Paypal $paypal */ + $paypal = $this->getUnzerObject()->createPaymentType(new Paypal()); + $authorization = $paypal->authorize(12.0, 'EUR', self::RETURN_URL, $customer); + + $secPayment = $this->getUnzerObject()->fetchPayment($authorization->getPayment()->getId()); + + /** @var Customer $secCustomer */ + $secCustomer = $secPayment->getCustomer(); + $this->assertNotNull($secCustomer); + $this->assertEquals($customer->expose(), $secCustomer->expose()); + } + + /** + * Customer can be referenced by payment. + * + * @test + */ + public function transactionShouldReferenceCustomerIfItExistAndItsIdHasBeenPassed(): void + { + $customer = $this->getMaximumCustomer(); + $this->getUnzerObject()->createCustomer($customer); + + /** @var Paypal $paypal */ + $paypal = $this->getUnzerObject()->createPaymentType(new Paypal()); + $authorization = $paypal->authorize(12.0, 'EUR', self::RETURN_URL, $customer->getId()); + + $secPayment = $this->getUnzerObject()->fetchPayment($authorization->getPayment()->getId()); + + /** @var Customer $secCustomer */ + $secCustomer = $secPayment->getCustomer(); + $this->assertNotNull($secCustomer); + $this->assertEquals($customer->expose(), $secCustomer->expose()); + } + + /** + * Customer can be updated. + * + * @depends maxCustomerCanBeCreatedAndFetched + * + * @test + * + * @param Customer $customer + */ + public function customerShouldBeUpdateable(Customer $customer): void + { + $this->assertEquals('Peter', $customer->getFirstname()); + $customer->setFirstname('Not Peter'); + $this->getUnzerObject()->updateCustomer($customer); + $this->assertEquals('Not Peter', $customer->getFirstname()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals($customer->getId(), $fetchedCustomer->getId()); + $this->assertEquals('Not Peter', $fetchedCustomer->getFirstname()); + } + + /** + * Customer can be deleted. + * + * @depends maxCustomerCanBeCreatedAndFetched + * + * @test + * + * @param Customer $customer + */ + public function customerShouldBeDeletableById(Customer $customer): void + { + $this->assertNotNull($customer); + $this->assertNotNull($customer->getId()); + + $this->getUnzerObject()->deleteCustomer($customer->getId()); + + $this->expectException(UnzerApiException::class); + $this->expectExceptionCode(ApiResponseCodes::API_ERROR_CUSTOMER_DOES_NOT_EXIST); + $this->getUnzerObject()->fetchCustomer($customer->getId()); + } + + /** + * Customer can be deleted. + * + * @test + */ + public function customerShouldBeDeletableByObject(): void + { + $customer = $this->getUnzerObject()->createCustomer($this->getMaximumCustomer()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertNotNull($customer); + $this->assertNotNull($customer->getId()); + + $this->getUnzerObject()->deleteCustomer($customer); + + $this->expectException(UnzerApiException::class); + $this->expectExceptionCode(ApiResponseCodes::API_ERROR_CUSTOMER_DOES_NOT_EXIST); + $this->getUnzerObject()->fetchCustomer($fetchedCustomer->getId()); + } + + /** + * Verify an Exception is thrown if the customerId already exists. + * + * @test + */ + public function apiShouldReturnErrorIfCustomerAlreadyExists(): void + { + $customerId = str_replace(' ', '', microtime()); + + // create customer with api + $customer = $this->getUnzerObject()->createCustomer($this->getMaximumCustomer()->setCustomerId($customerId)); + $this->assertNotEmpty($customer->getCustomerId()); + + $this->expectException(UnzerApiException::class); + $this->expectExceptionCode(ApiResponseCodes::API_ERROR_CUSTOMER_ID_ALREADY_EXISTS); + + // create new customer with the same customerId + $this->getUnzerObject()->createCustomer($this->getMaximumCustomer()->setCustomerId($customerId)); + } + + /** + * Verify a Customer is fetched and updated when its customerId already exist. + * + * @test + */ + public function customerShouldBeFetchedByCustomerIdAndUpdatedIfItAlreadyExists(): void + { + $customerId = str_replace(' ', '', microtime()); + + try { + // fetch non-existing customer by customerId + $this->getUnzerObject()->fetchCustomerByExtCustomerId($customerId, 2); + $this->assertTrue(false, 'Exception should be thrown here.'); + } catch (UnzerApiException $e) { + $this->assertEquals(ApiResponseCodes::API_ERROR_CUSTOMER_CAN_NOT_BE_FOUND, $e->getCode()); + $this->assertNotNull($e->getErrorId()); + } + + // create customer with api + $customer = $this->getUnzerObject()->createOrUpdateCustomer($this->getMaximumCustomer()->setCustomerId($customerId)); + $this->assertNotEmpty($customer->getCustomerId()); + $this->assertEquals($customerId, $customer->getCustomerId()); + $this->assertEquals('Peter', $customer->getFirstname()); + + $newCustomerData = $this->getMaximumCustomer()->setCustomerId($customerId)->setFirstname('Petra'); + $this->getUnzerObject()->createOrUpdateCustomer($newCustomerData); + + $this->assertEquals('Petra', $newCustomerData->getFirstname()); + $this->assertEquals($customerId, $newCustomerData->getCustomerId()); + $this->assertEquals($customer->getId(), $newCustomerData->getId()); + } + + /** + * Verify customer address can take a name as long as both first and lastname concatenated. + * + * @test + */ + public function addressNameCanHoldFirstAndLastNameConcatenated(): void + { + $customerId = 'c' . self::generateRandomId(); + $customer = $this->getMaximumCustomerInclShippingAddress()->setCustomerId($customerId); + $longName = 'firstfirstfirstfirstfirstfirstfirstfirst lastlastlastlastlastlastlastlastlastlast'; + $customer->getShippingAddress()->setName($longName); + $this->getUnzerObject()->createCustomer($customer); + $this->assertEquals($longName, $customer->getShippingAddress()->getName()); + + $veryLongName = $longName . 'X'; + $customer->getShippingAddress()->setName($veryLongName); + $this->expectException(UnzerApiException::class); + $this->expectExceptionCode(ApiResponseCodes::API_ERROR_ADDRESS_NAME_TO_LONG); + $this->getUnzerObject()->updateCustomer($customer); + } + + /** + * Not registered B2B customer should be creatable. + * + * @test + * + * @return Customer + */ + public function minNotRegisteredB2bCustomerCanBeCreatedAndFetched(): Customer + { + $customer = $this->getMinimalNotRegisteredB2bCustomer(); + $this->assertEmpty($customer->getId()); + $this->getUnzerObject()->createCustomer($customer); + $this->assertNotEmpty($customer->getId()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $exposeArray = $customer->expose(); + $exposeArray['salutation'] = Salutations::UNKNOWN; + $this->assertEquals($exposeArray, $fetchedCustomer->expose()); + + return $customer; + } + + /** + * Max not registered customer should be creatable. + * + * @test + */ + public function maxNotRegisteredB2bCustomerCanBeCreatedAndFetched(): void + { + $customer = $this->getMaximalNotRegisteredB2bCustomer(); + $this->assertEmpty($customer->getId()); + $this->getUnzerObject()->createCustomer($customer); + $this->assertNotEmpty($customer->getId()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals($customer->expose(), $fetchedCustomer->expose()); + } + + /** + * Registered B2B customer should be creatable. + * + * @test + * + * @return Customer + */ + public function minRegisteredB2bCustomerCanBeCreatedAndFetched(): Customer + { + $customer = $this->getMinimalRegisteredB2bCustomer(); + $this->assertEmpty($customer->getId()); + $this->getUnzerObject()->createCustomer($customer); + $this->assertNotEmpty($customer->getId()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $exposeArray = $customer->expose(); + $exposeArray['salutation'] = Salutations::UNKNOWN; + $this->assertEquals($exposeArray, $fetchedCustomer->expose()); + + return $customer; + } + + /** + * Max registered customer should be creatable. + * + * @test + */ + public function maxRegisteredB2bCustomerCanBeCreatedAndFetched(): void + { + $customer = $this->getMaximalRegisteredB2bCustomer(); + $this->assertEmpty($customer->getId()); + $this->getUnzerObject()->createCustomer($customer); + $this->assertNotEmpty($customer->getId()); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals($customer->expose(), $fetchedCustomer->expose()); + } + + /** + * Customer should contain clientIp set via header. + * + * @test + */ + public function customerShouldContainClientIpSetViaHeader() + { + $customer = $this->getMinimalCustomer(); + $clientIp = '123.123.123.123'; + $this->getUnzerObject()->setClientIp($clientIp); + $this->getUnzerObject()->createCustomer($customer); + + $fetchedCustomer = $this->getUnzerObject()->fetchCustomer($customer->getId()); + $this->assertEquals($clientIp, $fetchedCustomer->getGeoLocation()->getClientIp()); + } +} diff --git a/test/unit/Services/IdServiceTest.php b/test/unit/Services/IdServiceTest.php new file mode 100644 index 00000000..c3b1d114 --- /dev/null +++ b/test/unit/Services/IdServiceTest.php @@ -0,0 +1,58 @@ +assertTrue($isUUID); + } + + /** + * @test + * + * @dataProvider invalidUUIDsDP + * + * @param string $id + */ + public function shortIdShouldReturnFalse(string $id) + { + $isUUID = IdService::isUUDIResource($id); + $this->assertFalse($isUUID); + } + + public function validUUIDsDP(): array + { + return [ + ['s-bsk-123e4567-e89b-12d3-a456-426614174000'], + ['s-cst-123e4567-e89b-12d3-a456-426614174001'], + ['p-bsk-123e4567-e89b-12d3-a456-426614174000'], + ['p-cst-123e4567-e89b-12d3-a456-426614174001'], + ]; + } + + public function invalidUUIDsDP(): array + { + return [ + [''], + ['s-cst'], + ['s-bsk-123e4567-e89b-12d3-a456-426614174000-'], + ['-s-bsk-123e4567-e89b-12d3-a456-426614174000'], + ['s-bskt-123e4567-e89b-12d3-a456-426614174000'], + ['a-bsk-123e4567-e89b-12d3-a456-426614174000'], + ['s-cst-123456abcdef'], + ]; + } +} diff --git a/test/unit/Services/ResourceServiceTest.php b/test/unit/Services/ResourceServiceTest.php index a3d2774c..d88dbf30 100755 --- a/test/unit/Services/ResourceServiceTest.php +++ b/test/unit/Services/ResourceServiceTest.php @@ -55,6 +55,7 @@ use UnzerSDK\Resources\TransactionTypes\Charge; use UnzerSDK\Resources\TransactionTypes\Payout; use UnzerSDK\Resources\TransactionTypes\Shipment; +use UnzerSDK\Resources\V2\Customer as CustomerV2; use UnzerSDK\Services\HttpService; use UnzerSDK\Services\IdService; use UnzerSDK\Services\ResourceService; @@ -66,9 +67,7 @@ class ResourceServiceTest extends BasePaymentTest { - // - - /**^^ + /** * Verify setters and getters work properly. * * @test @@ -93,7 +92,7 @@ public function gettersAndSettersShouldWorkProperly(): void * * @param string $method * @param string $uri - * @param bool $appendId + * @param bool $appendId */ public function sendShouldCallSendOnHttpService(string $method, string $uri, bool $appendId): void { @@ -128,7 +127,7 @@ public function sendShouldCallSendOnHttpService(string $method, string $uri, boo * * @param string $method * @param string $uri - * @param bool $appendId + * @param bool $appendId */ public function AuthTokenShouldBeRequestedAutomatically(string $method, string $uri, bool $appendId): void { @@ -151,9 +150,47 @@ public function AuthTokenShouldBeRequestedAutomatically(string $method, string $ $this->assertEquals('paypage response', $response->response); } - // + /** + * Verify send will call send on httpService. + * + * @group CC-1309 + * @group CC-1376 + * + * @test + * + * @dataProvider customerV2CreationShouldCallV2EnpointDP + * + * @param string $method + * @param string $uri + * @param bool $appendId + */ + public function customerV2CreationShouldCallV2Enpoint(string $uri, bool $appendId): void + { + $unzer = new Unzer('s-priv-1234'); + $httpMethod = HttpAdapterInterface::REQUEST_POST; + $customer = new CustomerV2(); + $customer->setParentResource($unzer); + + //prepare http service mock. + $method = 'send'; + $httpSrvMock = $this->getMockBuilder(HttpService::class)->setMethods([$method])->getMock(); + $resourceSrv = new ResourceService($unzer); + + /** @var HttpService $httpSrvMock */ + $unzer->setHttpService($httpSrvMock); + + $httpSrvMock->expects($this->exactly(2))->method($method)->withConsecutive( + ['/auth/token'], + [$uri, $customer, $method] + ) + ->willReturnOnConsecutiveCalls( + '{"accessToken": "jwt.auth.token"}', '{"response": "paypage response"}' + ); + + $response = $resourceSrv->send($customer, $method); + $this->assertEquals('paypage response', $response->response); + } - // /** * Verify getResourceIdFromUrl works correctly. @@ -170,7 +207,8 @@ public function getResourceIdFromUrlShouldIdentifyAndReturnTheIdStringFromAGiven $expected, $uri, $idString - ): void { + ): void + { $this->assertEquals($expected, IdService::getResourceIdFromUrl($uri, $idString)); } @@ -190,9 +228,6 @@ public function getResourceIdFromUrlShouldThrowExceptionIfTheIdCanNotBeFound($ur IdService::getResourceIdFromUrl($uri, $idString); } - // - - // /** * Verify fetchResource calls fetch if its id is set and it has never been fetched before. @@ -400,7 +435,7 @@ public function fetchShouldCallSendWithGetUpdateFetchedAtAndCallHandleResponse() * @dataProvider fetchResourceByUrlShouldFetchTheDesiredResourceDP * * @param string $fetchMethod - * @param mixed $arguments + * @param mixed $arguments * @param string $resourceUrl */ public function fetchResourceByUrlShouldFetchTheDesiredResource($fetchMethod, $arguments, $resourceUrl): void @@ -455,8 +490,8 @@ public function fetchResourceByUrlForAPaymentTypeShouldReturnNullIfTheTypeIsUnkn * @dataProvider fetchShouldCallFetchResourceDP * * @param string $fetchMethod - * @param array $arguments - * @param mixed $callback + * @param array $arguments + * @param mixed $callback */ public function fetchShouldCallFetchResource(string $fetchMethod, array $arguments, $callback): void { @@ -478,9 +513,6 @@ static function ($resource) use ($callback, $unzer) { $this->assertEquals($unzer, $resource->getUnzerObject()); } - // - - // /** * Verify createPaymentType method will set parentResource to Unzer object and call create. @@ -545,9 +577,6 @@ public function updatePaymentTypeShouldCallUpdateMethod(): void $this->assertSame($paymentType, $returnedPaymentType); } - // - - // /** * Verify createCustomer calls create with customer object and the Unzer resource is set. @@ -604,8 +633,8 @@ public function createOrUpdateCustomerShouldFetchAndUpdateCustomerIfItAlreadyExi ->with($this->callback(static function ($customerToUpdate) use ($customer) { /** @var Customer $customerToUpdate */ return $customerToUpdate === $customer && - $customerToUpdate->getId() === $customer->getId() && - $customerToUpdate->getEmail() === 'customer@email.de'; + $customerToUpdate->getId() === $customer->getId() && + $customerToUpdate->getEmail() === 'customer@email.de'; })); // Make the call and assertions. @@ -722,9 +751,6 @@ public function deleteCustomerShouldFetchCustomerByIdIfTheIdIsGiven(): void $resourceSrvMock->deleteCustomer('myCustomerId'); } - // - - // /** * Verify fetchAuthorization fetches payment object and returns its authorization. @@ -769,9 +795,6 @@ public function fetchAuthorizationShouldThrowExceptionIfNoAuthorizationIsPresent $resourceSrvMock->fetchAuthorization('paymentId'); } - // - - // /** * Verify fetchPayout fetches payment object and returns its payout. @@ -795,9 +818,6 @@ public function fetchPayoutShouldFetchPaymentAndReturnItsPayout(): void $this->assertSame($payout, $returnedPayout); } - // - - // /** * Verify fetchChargeById fetches payment object and gets and returns the charge object from it. @@ -862,9 +882,6 @@ public function fetchChargeByIdShouldThrowExceptionIfChargeDoesNotExist(): void $resourceSrvMock->fetchChargeById($paymentMock, 'chargeId'); } - // - - // /** * Verify fetchReversalByAuthorization fetches authorization and gets and returns the reversal object from it. @@ -947,14 +964,11 @@ public function fetchRefundShouldGetAndFetchDesiredChargeCancellation(): void /** @noinspection PhpParamsInspection */ $resourceSrvMock->expects($this->once())->method('fetchResource')->with($cancel)->willReturn($cancel); - /** @var Charge $chargeMock*/ + /** @var Charge $chargeMock */ $returnedCancellation = $resourceSrvMock->fetchRefund($chargeMock, 'cancellationId'); $this->assertSame($cancel, $returnedCancellation); } - // - - // /** * Verify fetchShipment fetches payment object and returns the desired shipment from it. @@ -972,14 +986,11 @@ public function fetchShipmentShouldFetchPaymentAndReturnTheDesiredShipmentFromIt /** @noinspection PhpParamsInspection */ $paymentMock->expects($this->once())->method('getShipment')->with('shipmentId', false)->willReturn($shipment); - /** @var Payment $paymentMock */ + /** @var Payment $paymentMock */ $returnedShipment = $resourceSrvMock->fetchShipment('paymentId', 'shipmentId'); $this->assertSame($shipment, $returnedShipment); } - // - - // /** * Verify createMetadata calls create with the given metadata object. @@ -997,9 +1008,6 @@ public function createMetadataShouldCallCreateWithTheGivenMetadataObject(): void $this->assertSame($metadata, $resourceSrvMock->createMetadata($metadata)); } - // - - // /** * Verify createBasket will set parentResource and call create with the given basket. @@ -1147,9 +1155,6 @@ public function fetchBasketShouldNotCallFetchResourcheMethodIfAnyOtherExceptionI $resourceServiceMock->fetchBasket($basket); } - // - - // /** * Verify createRecurring calls fetch for the payment type if it is given the id. @@ -1210,9 +1215,6 @@ public function createRecurringShouldThrowExceptionWhenRecurringPaymentIsNotSupp $resourceService->activateRecurringPayment(new Sofort(), 'returnUrl', null); } - // - - // /** * Data provider for getResourceIdFromUrlShouldIdentifyAndReturnTheIdStringFromAGivenString. @@ -1235,7 +1237,7 @@ public function urlIdStringProvider(): array */ public function failingUrlIdStringProvider(): array { - return[ + return [ ['https://myurl.test/s-test-1234', 'aut'], ['https://myurl.test/authorizep-aut-99988776655', 'foo'], ['https://myurl.test/s-test-1234/z-bar-123456787', 'bar'] @@ -1284,18 +1286,19 @@ public function fetchResourceByUrlShouldFetchTheDesiredResourceDP(): array { return [ 'Authorization' => ['fetchAuthorization', ['s-pay-100746'], 'https://api.unzer.com/v1/payments/s-pay-100746/authorize/s-aut-1/'], - 'Charge' => ['fetchChargeById', ['s-pay-100798', 's-chg-1'], 'https://api.unzer.com/v1/payments/s-pay-100798/charges/s-chg-1/'], - 'Shipment' => ['fetchShipment', ['s-pay-100801', 's-shp-1'], 'https://api.unzer.com/v1/payments/s-pay-100801/shipments/s-shp-1/'], - 'Refund' => ['fetchRefundById', ['s-pay-100802', 's-chg-1', 's-cnl-1'], 'https://api.unzer.com/v1/payments/s-pay-100802/charges/s-chg-1/cancels/s-cnl-1/'], + 'Charge' => ['fetchChargeById', ['s-pay-100798', 's-chg-1'], 'https://api.unzer.com/v1/payments/s-pay-100798/charges/s-chg-1/'], + 'Shipment' => ['fetchShipment', ['s-pay-100801', 's-shp-1'], 'https://api.unzer.com/v1/payments/s-pay-100801/shipments/s-shp-1/'], + 'Refund' => ['fetchRefundById', ['s-pay-100802', 's-chg-1', 's-cnl-1'], 'https://api.unzer.com/v1/payments/s-pay-100802/charges/s-chg-1/cancels/s-cnl-1/'], 'Payment Refund' => ['fetchPaymentRefund', ['s-pay-100802', 's-cnl-1'], 'https://api.unzer.com/v1/payments/s-pay-100802/charges/cancels/s-cnl-1/'], - 'Reversal' => ['fetchReversal', ['s-pay-100803', 's-cnl-1'], 'https://api.unzer.com/v1/payments/s-pay-100803/authorize/s-aut-1/cancels/s-cnl-1/'], + 'Reversal' => ['fetchReversal', ['s-pay-100803', 's-cnl-1'], 'https://api.unzer.com/v1/payments/s-pay-100803/authorize/s-aut-1/cancels/s-cnl-1/'], 'Payment Reversal' => ['fetchPaymentReversal', ['s-pay-100803', 's-cnl-1'], 'https://api.unzer.com/v1/payments/s-pay-100803/authorize/cancels/s-cnl-1/'], - 'Payment' => ['fetchPayment', ['s-pay-100801'], 'https://api.unzer.com/v1/payments/s-pay-100801'], - 'Metadata' => ['fetchMetadata', ['s-mtd-6glqv9axjpnc'], 'https://api.unzer.com/v1/metadata/s-mtd-6glqv9axjpnc/'], - 'Customer' => ['fetchCustomer', ['s-cst-50c14d49e2fe'], 'https://api.unzer.com/v1/customers/s-cst-50c14d49e2fe'], - 'v1Basket' => ['fetchBasket', ['s-bsk-1254'], 'https://api.unzer.com/v1/baskets/s-bsk-1254/'], - 'v2Basket' => ['fetchBasket', ['s-bsk-1254'], 'https://api.unzer.com/v2/baskets/s-bsk-1254/'], - 'Payout' => ['fetchPayout', ['s-pay-100746'], 'https://api.unzer.com/v1/payments/s-pay-100746/payout/s-out-1/'] + 'Payment' => ['fetchPayment', ['s-pay-100801'], 'https://api.unzer.com/v1/payments/s-pay-100801'], + 'Metadata' => ['fetchMetadata', ['s-mtd-6glqv9axjpnc'], 'https://api.unzer.com/v1/metadata/s-mtd-6glqv9axjpnc/'], + 'Customer' => ['fetchCustomer', ['s-cst-50c14d49e2fe'], 'https://api.unzer.com/v1/customers/s-cst-50c14d49e2fe'], + 'v2Customer' => ['fetchCustomer', ['s-cst-123e4567-e89b-12d3-a456-426614174000'], 'https://api.unzer.com/v2/customers/s-cst-123e4567-e89b-12d3-a456-426614174000'], + 'v1Basket' => ['fetchBasket', ['s-bsk-1254'], 'https://api.unzer.com/v1/baskets/s-bsk-1254/'], + 'v2Basket' => ['fetchBasket', ['s-bsk-1254'], 'https://api.unzer.com/v2/baskets/s-bsk-1254/'], + 'Payout' => ['fetchPayout', ['s-pay-100746'], 'https://api.unzer.com/v1/payments/s-pay-100746/payout/s-out-1/'] ]; } @@ -1307,30 +1310,30 @@ public function fetchResourceByUrlShouldFetchTheDesiredResourceDP(): array public function fetchResourceByUrlForAPaymentTypeShouldCallFetchPaymentTypeDP(): array { return [ - 'ALIPAY' => ['s-ali-xen2ybcovn56', 'https://api.unzer.com/v1/types/alipay/s-ali-xen2ybcovn56/'], - 'APPLEPAY' => ['s-apl-xen2ybcovn56', 'https://api.unzer.com/v1/types/appelpay/s-apl-xen2ybcovn56/'], - 'BANCONTACT' => ['s-bct-xen2ybcovn56', 'https://api.unzer.com/v1/types/bancontact/s-bct-xen2ybcovn56/'], - 'CARD' => ['s-crd-xen2ybcovn56', 'https://api.unzer.com/v1/types/card/s-crd-xen2ybcovn56/'], - 'EPS' => ['s-eps-xen2ybcovn56', 'https://api.unzer.com/v1/types/eps/s-eps-xen2ybcovn56/'], - 'GIROPAY' => ['s-gro-xen2ybcovn56', 'https://api.unzer.com/v1/types/giropay/s-gro-xen2ybcovn56/'], - 'HIRE_PURCHASE_DIRECT_DEBIT' => ['s-hdd-xen2ybcovn56', 'https://api.unzer.com/v1/types/hire-purchase-direct-debit/s-hdd-xen2ybcovn56/'], - 'IDEAL' => ['s-idl-xen2ybcovn56', 'https://api.unzer.com/v1/types/ideal/s-idl-xen2ybcovn56/'], - 'INVOICE' => ['s-ivc-xen2ybcovn56', 'https://api.unzer.com/v1/types/invoice/s-ivc-xen2ybcovn56/'], - 'INVOICE_FACTORING' => ['s-ivf-xen2ybcovn56', 'https://api.unzer.com/v1/types/wechatpay/s-ivf-xen2ybcovn56/'], - 'INVOICE_GUARANTEED' => ['s-ivg-xen2ybcovn56', 'https://api.unzer.com/v1/types/invoice-guaranteed/s-ivg-xen2ybcovn56/'], - 'INVOICE_SECURED' => ['s-ivs-xen2ybcovn56', 'https://api.unzer.com/v1/types/invoice-secured/s-ivs-xen2ybcovn56/'], - 'Installment_SECURED' => ['s-ins-xen2ybcovn56', 'https://api.unzer.com/v1/types/installment-secured/s-ins-xen2ybcovn56/'], - 'PAYLATER_INVOICE' => ['s-piv-xen2ybcovn56', 'https://api.unzer.com/v1/types/paylater-invoice/s-piv-xen2ybcovn56/'], - 'PAYPAL' => ['s-ppl-xen2ybcovn56', 'https://api.unzer.com/v1/types/paypal/s-ppl-xen2ybcovn56/'], - 'PIS' => ['s-pis-xen2ybcovn56', 'https://api.unzer.com/v1/types/pis/s-pis-xen2ybcovn56/'], - 'POST_FINANCE_EFINANCE' => ['s-pfe-xen2ybcovn56', 'https://api.unzer.com/v1/types/pfe/s-pfe-xen2ybcovn56/'], - 'POST_FINANCE_CARD' => ['s-pfc-xen2ybcovn56', 'https://api.unzer.com/v1/types/pfc/s-pfc-xen2ybcovn56/'], - 'PREPAYMENT' => ['s-ppy-xen2ybcovn56', 'https://api.unzer.com/v1/types/prepayment/s-ppy-xen2ybcovn56/'], - 'PRZELEWY24' => ['s-p24-xen2ybcovn56', 'https://api.unzer.com/v1/types/przelewy24/s-p24-xen2ybcovn56/'], - 'SEPA_DIRECT_DEBIT' => ['s-sdd-xen2ybcovn56', 'https://api.unzer.com/v1/types/direct-debit/s-sdd-xen2ybcovn56/'], + 'ALIPAY' => ['s-ali-xen2ybcovn56', 'https://api.unzer.com/v1/types/alipay/s-ali-xen2ybcovn56/'], + 'APPLEPAY' => ['s-apl-xen2ybcovn56', 'https://api.unzer.com/v1/types/appelpay/s-apl-xen2ybcovn56/'], + 'BANCONTACT' => ['s-bct-xen2ybcovn56', 'https://api.unzer.com/v1/types/bancontact/s-bct-xen2ybcovn56/'], + 'CARD' => ['s-crd-xen2ybcovn56', 'https://api.unzer.com/v1/types/card/s-crd-xen2ybcovn56/'], + 'EPS' => ['s-eps-xen2ybcovn56', 'https://api.unzer.com/v1/types/eps/s-eps-xen2ybcovn56/'], + 'GIROPAY' => ['s-gro-xen2ybcovn56', 'https://api.unzer.com/v1/types/giropay/s-gro-xen2ybcovn56/'], + 'HIRE_PURCHASE_DIRECT_DEBIT' => ['s-hdd-xen2ybcovn56', 'https://api.unzer.com/v1/types/hire-purchase-direct-debit/s-hdd-xen2ybcovn56/'], + 'IDEAL' => ['s-idl-xen2ybcovn56', 'https://api.unzer.com/v1/types/ideal/s-idl-xen2ybcovn56/'], + 'INVOICE' => ['s-ivc-xen2ybcovn56', 'https://api.unzer.com/v1/types/invoice/s-ivc-xen2ybcovn56/'], + 'INVOICE_FACTORING' => ['s-ivf-xen2ybcovn56', 'https://api.unzer.com/v1/types/wechatpay/s-ivf-xen2ybcovn56/'], + 'INVOICE_GUARANTEED' => ['s-ivg-xen2ybcovn56', 'https://api.unzer.com/v1/types/invoice-guaranteed/s-ivg-xen2ybcovn56/'], + 'INVOICE_SECURED' => ['s-ivs-xen2ybcovn56', 'https://api.unzer.com/v1/types/invoice-secured/s-ivs-xen2ybcovn56/'], + 'Installment_SECURED' => ['s-ins-xen2ybcovn56', 'https://api.unzer.com/v1/types/installment-secured/s-ins-xen2ybcovn56/'], + 'PAYLATER_INVOICE' => ['s-piv-xen2ybcovn56', 'https://api.unzer.com/v1/types/paylater-invoice/s-piv-xen2ybcovn56/'], + 'PAYPAL' => ['s-ppl-xen2ybcovn56', 'https://api.unzer.com/v1/types/paypal/s-ppl-xen2ybcovn56/'], + 'PIS' => ['s-pis-xen2ybcovn56', 'https://api.unzer.com/v1/types/pis/s-pis-xen2ybcovn56/'], + 'POST_FINANCE_EFINANCE' => ['s-pfe-xen2ybcovn56', 'https://api.unzer.com/v1/types/pfe/s-pfe-xen2ybcovn56/'], + 'POST_FINANCE_CARD' => ['s-pfc-xen2ybcovn56', 'https://api.unzer.com/v1/types/pfc/s-pfc-xen2ybcovn56/'], + 'PREPAYMENT' => ['s-ppy-xen2ybcovn56', 'https://api.unzer.com/v1/types/prepayment/s-ppy-xen2ybcovn56/'], + 'PRZELEWY24' => ['s-p24-xen2ybcovn56', 'https://api.unzer.com/v1/types/przelewy24/s-p24-xen2ybcovn56/'], + 'SEPA_DIRECT_DEBIT' => ['s-sdd-xen2ybcovn56', 'https://api.unzer.com/v1/types/direct-debit/s-sdd-xen2ybcovn56/'], 'SEPA_DIRECT_DEBIT_GUARANTEED' => ['s-ddg-xen2ybcovn56', 'https://api.unzer.com/v1/types/direct-debit-guaranteed/s-ddg-xen2ybcovn56/'], - 'SOFORT' => ['s-sft-xen2ybcovn56', 'https://api.unzer.com/v1/types/sofort/s-sft-xen2ybcovn56/'], - 'WECHATPAY' => ['s-wcp-xen2ybcovn56', 'https://api.unzer.com/v1/types/wechatpay/s-wcp-xen2ybcovn56/'] + 'SOFORT' => ['s-sft-xen2ybcovn56', 'https://api.unzer.com/v1/types/sofort/s-sft-xen2ybcovn56/'], + 'WECHATPAY' => ['s-wcp-xen2ybcovn56', 'https://api.unzer.com/v1/types/wechatpay/s-wcp-xen2ybcovn56/'] ]; } @@ -1340,10 +1343,10 @@ public function fetchResourceByUrlForAPaymentTypeShouldCallFetchPaymentTypeDP(): public function sendShouldCallSendOnHttpServiceDP(): array { return [ - HttpAdapterInterface::REQUEST_GET => [HttpAdapterInterface::REQUEST_GET, '/my/get/uri', true], - HttpAdapterInterface::REQUEST_PATCH => [HttpAdapterInterface::REQUEST_PATCH, '/my/patch/uri', true], - HttpAdapterInterface::REQUEST_POST => [HttpAdapterInterface::REQUEST_POST, '/my/post/uri', false], - HttpAdapterInterface::REQUEST_PUT => [HttpAdapterInterface::REQUEST_PUT, '/my/put/uri', true], + HttpAdapterInterface::REQUEST_GET => [HttpAdapterInterface::REQUEST_GET, '/my/get/uri', true], + HttpAdapterInterface::REQUEST_PATCH => [HttpAdapterInterface::REQUEST_PATCH, '/my/patch/uri', true], + HttpAdapterInterface::REQUEST_POST => [HttpAdapterInterface::REQUEST_POST, '/my/post/uri', false], + HttpAdapterInterface::REQUEST_PUT => [HttpAdapterInterface::REQUEST_PUT, '/my/put/uri', true], HttpAdapterInterface::REQUEST_DELETE => [HttpAdapterInterface::REQUEST_DELETE, '/my/delete/uri', true], ]; } @@ -1354,7 +1357,7 @@ public function sendShouldCallSendOnHttpServiceDP(): array public function AuthTokenShouldBeRequestedAutomaticallyDP(): array { return [ - HttpAdapterInterface::REQUEST_POST => [HttpAdapterInterface::REQUEST_POST, '/auth/token', false], + HttpAdapterInterface::REQUEST_POST => [HttpAdapterInterface::REQUEST_POST, '/auth/token', false], ]; } @@ -1363,22 +1366,22 @@ public function AuthTokenShouldBeRequestedAutomaticallyDP(): array */ public function fetchShouldCallFetchResourceDP(): array { - $fetchPaymentCB = static function ($payment) { + $fetchPaymentCB = static function ($payment) { return $payment instanceof Payment && $payment->getId() === 'myPaymentId'; }; $fetchPaymentByOrderIdCB = static function ($payment) { return $payment instanceof Payment && $payment->getOrderId() === 'myOrderId'; }; - $fetchKeypairCB = static function ($keypair) { + $fetchKeypairCB = static function ($keypair) { return $keypair instanceof Keypair; }; - $fetchCustomerCB = static function ($customer) { + $fetchCustomerCB = static function ($customer) { return $customer instanceof Customer && $customer->getId() === 'myCustomerId'; }; - $fetchMetadataCB = static function ($metadata) { + $fetchMetadataCB = static function ($metadata) { return $metadata instanceof Metadata && $metadata->getId() === 's-mtd-1234'; }; - $fetchBasketCB = static function ($basket) { + $fetchBasketCB = static function ($basket) { return $basket instanceof Basket && $basket->getId() === 'myBasketId'; }; @@ -1452,5 +1455,10 @@ public function fetchShouldCallFetchResourceDP(): array ]; } - // + public function customerV2CreationShouldCallV2EnpointDP() + { + return [ + 'Customer' => ['/customers', false] + ]; + } }