diff --git a/lib/Trolley/BalanceGateway.php b/lib/Trolley/BalanceGateway.php index 59a9b61..6f10a53 100644 --- a/lib/Trolley/BalanceGateway.php +++ b/lib/Trolley/BalanceGateway.php @@ -42,14 +42,15 @@ public function __construct($gateway) */ public function search($params, $query) { - $response = $this->_http->get('/v1/balances/'.$params, $query); + $path = $params ? "/v1/balances/{$params}" : '/v1/balances'; + $response = $this->_http->get($path, $query); if ($response['ok']) { $pager = [ 'object' => $this, - 'method' => 'search', - 'methodArgs' => $query + 'method' => 'searchPage', + 'methodArgs' => array_merge($query, ['params' => $params]) ]; $items = array_map(function ($item) { @@ -63,6 +64,51 @@ public function search($params, $query) throw new Exception\DownForMaintenance(); } } + + public function searchPage($query) + { + $params = isset($query['params']) ? $query['params'] : ''; + unset($query['params']); + return $this->search($params, $query); + } + + public function all($query = []) + { + $response = $this->_http->get('/v1/balances', $query); + return $this->balancesCollection($response, 'all', $query); + } + + public function paymentrails($query = []) + { + $response = $this->_http->get('/v1/balances/paymentrails', $query); + return $this->balancesCollection($response, 'paymentrails', $query); + } + + public function paypal($query = []) + { + $response = $this->_http->get('/v1/balances/paypal', $query); + return $this->balancesCollection($response, 'paypal', $query); + } + + private function balancesCollection($response, $method, $query) + { + if ($response['ok']) { + $pager = [ + 'object' => $this, + 'method' => $method, + 'methodArgs' => $query + ]; + + $items = array_map(function ($item) { + return Balance::factory($item); + }, $response['balances']); + return new ResourceCollection($response, $items, $pager); + } else if ($response['errors']) { + throw new Exception\Standard($response['errors']); + } else { + throw new Exception\DownForMaintenance(); + } + } } class_alias('Trolley\BalanceGateway', 'Trolley_BalanceGateway'); diff --git a/lib/Trolley/Batch.php b/lib/Trolley/Batch.php index 5189309..336cfc5 100644 --- a/lib/Trolley/Batch.php +++ b/lib/Trolley/Batch.php @@ -26,7 +26,9 @@ class Batch extends Base "status" => "", "totalPayments" => "", "updatedAt" => "", - "payments" => "" + "payments" => "", + "quoteExpiredAt" => "", + "tags" => "" ]; /** @@ -240,7 +242,9 @@ protected function _initialize($attributes) { "status", "totalPayments", "updatedAt", - "payments" => 'Trolley\Payment::factoryArray' + "payments" => 'Trolley\Payment::factoryArray', + "quoteExpiredAt", + "tags" ]; foreach ($fields as $key => $field) { diff --git a/lib/Trolley/BatchGateway.php b/lib/Trolley/BatchGateway.php index 02473a8..797e4d4 100644 --- a/lib/Trolley/BatchGateway.php +++ b/lib/Trolley/BatchGateway.php @@ -67,7 +67,7 @@ public function search($query) * Fetch a Batch by ID */ public function find($id) { - $response = $this->_http->get('/v1/batches/' . $id, null); + $response = $this->_http->get("/v1/batches/{$id}", null); if ($response['ok']) { return Batch::factory($response['batch']); @@ -92,7 +92,7 @@ public function create($attrib, $payments = []) { } public function update($batchId, $attrib) { - $response = $this->_http->patch('/v1/batches/' . $batchId, $attrib); + $response = $this->_http->patch("/v1/batches/{$batchId}", $attrib); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -103,7 +103,7 @@ public function update($batchId, $attrib) { } public function delete($batchId) { - $response = $this->_http->delete('/v1/batches/' . $batchId); + $response = $this->_http->delete("/v1/batches/{$batchId}"); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -125,7 +125,7 @@ public function deleteMultiple($batchIds) { } public function summary($batchId) { - $response = $this->_http->get('/v1/batches/' . $batchId . '/summary'); + $response = $this->_http->get("/v1/batches/{$batchId}/summary"); if ($response['ok']) { return BatchSummary::factory($response['batchSummary']); } else if ($response['errors']){ @@ -136,7 +136,7 @@ public function summary($batchId) { } public function generateQuote($batchId) { - $response = $this->_http->post('/v1/batches/' . $batchId . '/generate-quote'); + $response = $this->_http->post("/v1/batches/{$batchId}/generate-quote"); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -147,7 +147,7 @@ public function generateQuote($batchId) { } public function startProcessing($batchId) { - $response = $this->_http->post('/v1/batches/' . $batchId . '/start-processing'); + $response = $this->_http->post("/v1/batches/{$batchId}/start-processing"); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -158,7 +158,7 @@ public function startProcessing($batchId) { } public function createPayment($batchId, $payment) { - $response = $this->_http->post('/v1/batches/' . $batchId . '/payments', $payment); + $response = $this->_http->post("/v1/batches/{$batchId}/payments", $payment); if ($response['ok']) { return Payment::factory($response['payment']); } else if ($response['errors']){ @@ -169,7 +169,7 @@ public function createPayment($batchId, $payment) { } public function findPayment($batchId, $paymentId) { - $response = $this->_http->get('/v1/batches/' . $batchId . '/payments/' . $paymentId); + $response = $this->_http->get("/v1/batches/{$batchId}/payments/{$paymentId}"); if ($response['ok']) { return Payment::factory($response['payment']); } else if ($response['errors']){ @@ -180,7 +180,7 @@ public function findPayment($batchId, $paymentId) { } public function updatePayment($batchId, $paymentId, $params) { - $response = $this->_http->patch('/v1/batches/' . $batchId . '/payments/' . $paymentId, $params); + $response = $this->_http->patch("/v1/batches/{$batchId}/payments/{$paymentId}", $params); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -191,7 +191,7 @@ public function updatePayment($batchId, $paymentId, $params) { } public function deletePayment($batchId, $paymentId) { - $response = $this->_http->delete('/v1/batches/' . $batchId . '/payments/' . $paymentId); + $response = $this->_http->delete("/v1/batches/{$batchId}/payments/{$paymentId}"); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -202,18 +202,21 @@ public function deletePayment($batchId, $paymentId) { } public function payments($batchId, $params = []) { - return $this->paymentsInternal( - array_merge(['batchId' => $batchId], $params) - ); + $response = $this->_http->get("/v1/batches/{$batchId}/payments", $params); + return $this->paymentsCollection($response, $batchId, $params); } public function paymentsInternal($params) { - $response = $this->_http->get('/v1/batches/' . $params['batchId'] . '/payments', $params); + $response = $this->_http->get("/v1/batches/{$params['batchId']}/payments", $params); + return $this->paymentsCollection($response, $params['batchId'], $params); + } + + private function paymentsCollection($response, $batchId, $params) { if ($response['ok']) { $pager = [ 'object' => $this, 'method' => 'paymentsInternal', - 'methodArgs' => $params, + 'methodArgs' => array_merge($params, ['batchId' => $batchId]), ]; $items = array_map(function ($item) { diff --git a/lib/Trolley/Configuration.php b/lib/Trolley/Configuration.php index 6d5cb39..e408c9b 100644 --- a/lib/Trolley/Configuration.php +++ b/lib/Trolley/Configuration.php @@ -13,7 +13,7 @@ class Configuration { public static $global; - private $_environment = null; + private $_environment = "production"; private $_merchantId = null; private $_publicKey = null; private $_privateKey = null; diff --git a/lib/Trolley/Gateway.php b/lib/Trolley/Gateway.php index 5186ffd..c35b9dd 100644 --- a/lib/Trolley/Gateway.php +++ b/lib/Trolley/Gateway.php @@ -94,6 +94,22 @@ public function balance() { return new BalanceGateway($this); } + + /** + * @return VerificationGateway + */ + public function verification() + { + return new VerificationGateway($this); + } + + /** + * @return VerificationGateway + */ + public function trust() + { + return $this->verification(); + } } class_alias('Trolley\Gateway', 'Trolley_Gateway'); diff --git a/lib/Trolley/InvoicePayment.php b/lib/Trolley/InvoicePayment.php index ec33529..2167342 100644 --- a/lib/Trolley/InvoicePayment.php +++ b/lib/Trolley/InvoicePayment.php @@ -19,7 +19,14 @@ class InvoicePayment extends Base "invoiceId" => "", "invoiceLineId" => "", "paymentId" => "", - "amount" => "" + "amount" => "", + "batchId" => "", + "invoicePayments" => "", + "status" => "", + "memo" => "", + "externalId" => "", + "tags" => "", + "coverFees" => "" ]; /** @@ -95,7 +102,14 @@ protected function _initialize($attributes) { "invoiceId", "invoiceLineId", "paymentId", - "amount" + "amount", + "batchId", + "invoicePayments", + "status", + "memo", + "externalId", + "tags", + "coverFees" ]; foreach ($fields as $key => $field) { diff --git a/lib/Trolley/OfflinePayment.php b/lib/Trolley/OfflinePayment.php index 7fcc5ed..4b448f7 100644 --- a/lib/Trolley/OfflinePayment.php +++ b/lib/Trolley/OfflinePayment.php @@ -33,6 +33,8 @@ class OfflinePayment extends Base "updatedAt" => "", "createdAt" => "", "deletedAt" => "", + "activityCount" => "", + "taxReportable" => "", ]; /** @@ -132,6 +134,8 @@ protected function _initialize($attributes) { "updatedAt", "createdAt", "deletedAt", + "activityCount", + "taxReportable", ]; foreach ($fields as $field) { diff --git a/lib/Trolley/OfflinePaymentGateway.php b/lib/Trolley/OfflinePaymentGateway.php index 9a70cd2..dd636ed 100644 --- a/lib/Trolley/OfflinePaymentGateway.php +++ b/lib/Trolley/OfflinePaymentGateway.php @@ -45,7 +45,7 @@ public function __construct($gateway) public function search($query) { if (isset($query["recipientId"])) { - $response = $this->_http->get('/v1/recipients/'.$query["recipientId"].'/offlinePayments', $query); + $response = $this->_http->get("/v1/recipients/{$query['recipientId']}/offlinePayments", $query); } else { $response = $this->_http->get('/v1/offline-payments', $query); } @@ -70,7 +70,7 @@ public function search($query) } public function create($recipientId, $offlinePaymentBody) { - $response = $this->_http->post('/v1/recipients/' . $recipientId . '/offlinePayments', $offlinePaymentBody); + $response = $this->_http->post("/v1/recipients/{$recipientId}/offlinePayments", $offlinePaymentBody); if ($response['ok']) { return OfflinePayment::factory($response['offlinePayment']); } else if ($response['errors']){ @@ -81,7 +81,7 @@ public function create($recipientId, $offlinePaymentBody) { } public function update($recipientId, $offlinePaymentId, $offlinePaymentBody) { - $response = $this->_http->patch('/v1/recipients/' . $recipientId . '/offlinePayments/' . $offlinePaymentId, $offlinePaymentBody); + $response = $this->_http->patch("/v1/recipients/{$recipientId}/offlinePayments/{$offlinePaymentId}", $offlinePaymentBody); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -92,7 +92,7 @@ public function update($recipientId, $offlinePaymentId, $offlinePaymentBody) { } public function delete($recipientId, $offlinePaymentId) { - $response = $this->_http->delete('/v1/recipients/' . $recipientId . '/offlinePayments/' . $offlinePaymentId); + $response = $this->_http->delete("/v1/recipients/{$recipientId}/offlinePayments/{$offlinePaymentId}"); if ($response['ok']) { return true; } else if ($response['errors']){ diff --git a/lib/Trolley/Payment.php b/lib/Trolley/Payment.php index 6de3ec0..d789568 100644 --- a/lib/Trolley/Payment.php +++ b/lib/Trolley/Payment.php @@ -19,15 +19,19 @@ class Payment extends Base 'id', 'methodDisplay', 'recipient', + 'batch', 'status', 'isSupplyPayment', 'returnedAmount', 'amount', 'currency', + 'category', 'sourceAmount', 'sourceCurrency', + 'sourceCurrencyName', 'targetAmount', 'targetCurrency', + 'targetCurrencyName', 'exchangeRate', 'fees', 'recipientFees', @@ -45,8 +49,20 @@ class Payment extends Base 'checkNumber', 'tags', 'estimatedDeliveryAt', - 'initiatedAt', + 'equivalentWithholdingAmount', + 'equivalentWithholdingCurrency', + 'failureMessage', + 'merchantId', 'returnedAt', + 'returnedNote', + 'returnedReason', + 'settledAt', + 'taxBasisAmount', + 'taxBasisCurrency', + 'withholdingAmount', + 'withholdingCurrency', + 'visibleToRecipient', + 'initiatedAt', ]; /** @@ -85,15 +101,19 @@ protected function _initialize($attributes) { 'id', 'methodDisplay', 'recipient', + 'batch', 'status', 'isSupplyPayment', 'returnedAmount', 'amount', 'currency', + 'category', 'sourceAmount', 'sourceCurrency', + 'sourceCurrencyName', 'targetAmount', 'targetCurrency', + 'targetCurrencyName', 'exchangeRate', 'fees', 'recipientFees', @@ -111,8 +131,20 @@ protected function _initialize($attributes) { 'checkNumber', 'tags', 'estimatedDeliveryAt', - 'initiatedAt', + 'equivalentWithholdingAmount', + 'equivalentWithholdingCurrency', + 'failureMessage', + 'merchantId', 'returnedAt', + 'returnedNote', + 'returnedReason', + 'settledAt', + 'taxBasisAmount', + 'taxBasisCurrency', + 'withholdingAmount', + 'withholdingCurrency', + 'visibleToRecipient', + 'initiatedAt', ]; foreach ($fields as $field) { diff --git a/lib/Trolley/PaymentGateway.php b/lib/Trolley/PaymentGateway.php index 26b7744..8d147d8 100644 --- a/lib/Trolley/PaymentGateway.php +++ b/lib/Trolley/PaymentGateway.php @@ -65,6 +65,18 @@ public function search($id, $query) } } + public function find($paymentId) + { + $response = $this->_http->get("/v1/payments/{$paymentId}"); + if ($response['ok']) { + return Payment::factory($response['payment']); + } else if ($response['errors']){ + throw new Exception\Standard($response['errors']); + } else { + throw new Exception\DownForMaintenance(); + } + } + /** * generic method for validating incoming gateway responses * diff --git a/lib/Trolley/Recipient.php b/lib/Trolley/Recipient.php index 0dbdea4..4c471d0 100644 --- a/lib/Trolley/Recipient.php +++ b/lib/Trolley/Recipient.php @@ -43,6 +43,7 @@ class Recipient extends Base "payoutMethod" => "", "compliance" => "", "accounts" => "", + "tags" => "", "address" => "", ]; @@ -169,7 +170,8 @@ protected function _initialize($attributes) { "merchantId", "payoutMethod", "compliance", - "accounts" => 'Trolley\RecipientAccount::factoryArray', // Specifies factory method + "accounts" => 'Trolley\RecipientAccount::factoryArray', + "tags", // Specifies factory method "address" => 'Trolley\RecipientAddress::factory', ]; diff --git a/lib/Trolley/RecipientAccount.php b/lib/Trolley/RecipientAccount.php index d581848..28e8549 100644 --- a/lib/Trolley/RecipientAccount.php +++ b/lib/Trolley/RecipientAccount.php @@ -39,7 +39,11 @@ class RecipientAccount extends Base "bankRegionCode" => "", "bankPostalCode" => "", "routeType" => "", - "recipientFees" => "" + "recipientFees" => "", + "emailAddress" => "", + "cardDetails" => "", + "mailing" => "", + "phoneNumber" => "" ]; /** @@ -130,7 +134,11 @@ protected function _initialize($attributes) { "bankRegionCode", "bankPostalCode", "routeType", - "recipientFees" + "recipientFees", + "emailAddress", + "cardDetails", + "mailing", + "phoneNumber" ]; foreach ($fields as $field) { diff --git a/lib/Trolley/RecipientAccountGateway.php b/lib/Trolley/RecipientAccountGateway.php index 435baaf..7d48eb2 100644 --- a/lib/Trolley/RecipientAccountGateway.php +++ b/lib/Trolley/RecipientAccountGateway.php @@ -43,7 +43,7 @@ public function __construct($gateway) */ public function all($recipientId) { - $response = $this->_http->get('/v1/recipients/' . $recipientId . '/accounts'); + $response = $this->_http->get("/v1/recipients/{$recipientId}/accounts"); if ($response['ok']) { return array_map(function ($item) { @@ -60,7 +60,7 @@ public function all($recipientId) * Fetch a recipient by ID */ public function find($recipientId, $accountId) { - $response = $this->_http->get('/v1/recipients/' . $recipientId . '/accounts/' . $accountId); + $response = $this->_http->get("/v1/recipients/{$recipientId}/accounts/{$accountId}"); if ($response['ok']) { return RecipientAccount::factory($response['account']); @@ -72,7 +72,7 @@ public function find($recipientId, $accountId) { } public function create($recipientId, $attrib) { - $response = $this->_http->post('/v1/recipients/' . $recipientId . '/accounts', $attrib); + $response = $this->_http->post("/v1/recipients/{$recipientId}/accounts", $attrib); if ($response['ok']) { return RecipientAccount::factory($response['account']); } else if ($response['errors']){ @@ -83,9 +83,9 @@ public function create($recipientId, $attrib) { } public function update($recipientId, $accountId, $attrib) { - $response = $this->_http->patch('/v1/recipients/' . $recipientId . '/accounts/' . $accountId, $attrib); + $response = $this->_http->patch("/v1/recipients/{$recipientId}/accounts/{$accountId}", $attrib); if ($response['ok']) { - return Recipient::factory($response['account']); + return RecipientAccount::factory($response['account']); } else if ($response['errors']){ throw new Exception\Standard($response['errors']); } else { @@ -94,7 +94,7 @@ public function update($recipientId, $accountId, $attrib) { } public function delete($recipientId, $accountId) { - $response = $this->_http->delete('/v1/recipients/' . $recipientId . '/accounts/' . $accountId); + $response = $this->_http->delete("/v1/recipients/{$recipientId}/accounts/{$accountId}"); if ($response['ok']) { return true; } else if ($response['errors']){ diff --git a/lib/Trolley/RecipientGateway.php b/lib/Trolley/RecipientGateway.php index 0d61ffe..1a02b26 100644 --- a/lib/Trolley/RecipientGateway.php +++ b/lib/Trolley/RecipientGateway.php @@ -69,7 +69,7 @@ public function search($query) * Fetch a recipient by ID */ public function find($id) { - $response = $this->_http->get('/v1/recipients/' . $id, null); + $response = $this->_http->get("/v1/recipients/{$id}", null); if ($response['ok']) { return Recipient::factory($response['recipient']); @@ -92,7 +92,7 @@ public function create($attrib) { } public function update($id, $attrib) { - $response = $this->_http->patch('/v1/recipients/' . $id, $attrib); + $response = $this->_http->patch("/v1/recipients/{$id}", $attrib); if ($response['ok']) { return true; } else if ($response['errors']){ @@ -103,7 +103,7 @@ public function update($id, $attrib) { } public function delete($id) { - $response = $this->_http->delete('/v1/recipients/' . $id); + $response = $this->_http->delete("/v1/recipients/{$id}"); if ($response) { return true; } else { @@ -153,7 +153,7 @@ public function getAllLogs($id) { */ public function getAllPayments($recipientId) { - $response = $this->_http->get('/v1/recipients/'.$recipientId.'/payments'); + $response = $this->_http->get("/v1/recipients/{$recipientId}/payments"); if ($response['ok']) { $pager = [ @@ -173,6 +173,32 @@ public function getAllPayments($recipientId) throw new Exception\DownForMaintenance(); } } + + public function getAllOfflinePayments($recipientId, $query = []) + { + $response = $this->_http->get("/v1/recipients/{$recipientId}/offlinePayments", $query); + if ($response['ok']) { + $items = array_map(function ($item) { + return OfflinePayment::factory($item); + }, $response['offlinePayments']); + return new ResourceCollection($response, $items, [ + 'object' => $this, + 'method' => 'getAllOfflinePaymentsPage', + 'methodArgs' => array_merge($query, ['recipientId' => $recipientId]) + ]); + } else if ($response['errors']){ + throw new Exception\Standard($response['errors']); + } else { + throw new Exception\DownForMaintenance(); + } + } + + public function getAllOfflinePaymentsPage($query) + { + $recipientId = $query['recipientId']; + unset($query['recipientId']); + return $this->getAllOfflinePayments($recipientId, $query); + } } class_alias('Trolley\RecipientGateway', 'Trolley_RecipientGateway'); diff --git a/lib/Trolley/ResourceCollection.php b/lib/Trolley/ResourceCollection.php index 946f837..85b2a98 100644 --- a/lib/Trolley/ResourceCollection.php +++ b/lib/Trolley/ResourceCollection.php @@ -56,9 +56,10 @@ public function __construct($response, $items, $pager) /** * returns the current item when iterating with foreach */ + #[\ReturnTypeWillChange] public function current() { - return $this->_items[$this->_index]; + return isset($this->_items[$this->_index]) ? $this->_items[$this->_index] : false; } /** @@ -68,9 +69,10 @@ public function current() */ public function firstItem() { - return $this->_items[0]; + return isset($this->_items[0]) ? $this->_items[0] : false; } + #[\ReturnTypeWillChange] public function key() { return null; @@ -79,6 +81,7 @@ public function key() /** * advances to the next item in the collection when iterating with foreach */ + #[\ReturnTypeWillChange] public function next() { ++$this->_index; @@ -87,6 +90,7 @@ public function next() /** * rewinds the testIterateOverResults collection to the first item when iterating with foreach */ + #[\ReturnTypeWillChange] public function rewind() { $this->_index = 0; @@ -95,12 +99,16 @@ public function rewind() /** * returns whether the current item is valid when iterating with foreach */ + #[\ReturnTypeWillChange] public function valid() { if ($this->_index >= count($this->_items)) { if ($this->_page + 1 >= $this->_maxPages) { return false; } + if (!$this->_hasPager()) { + return false; + } $this->_getNextPage(); } return $this->_index < $this->_records; @@ -119,6 +127,11 @@ private function _getNextPage() ++$this->_page; } + private function _hasPager() + { + return isset($this->_pager['object'], $this->_pager['method'], $this->_pager['methodArgs']); + } + /** * requests the next page of results for the collection * diff --git a/lib/Trolley/VerificationGateway.php b/lib/Trolley/VerificationGateway.php new file mode 100644 index 0000000..6adc166 --- /dev/null +++ b/lib/Trolley/VerificationGateway.php @@ -0,0 +1,65 @@ +_gateway = $gateway; + $this->_config = $gateway->config; + $this->_config->assertHasAccessTokenOrKeys(); + $this->_http = new Http($gateway->config); + } + + public function search($query = []) + { + $response = $this->_http->get('/v1/verifications', $query); + return $this->buildCollection($response, $query); + } + + public function expire($body) + { + $response = $this->_http->patch('/v1/verifications/expire', $body); + return $this->buildCollection($response); + } + + public function trigger($verificationType, $body) + { + $response = $this->_http->post("/v1/verifications/{$verificationType}/trigger", $body); + return $this->buildCollection($response); + } + + public function triggerWatchlist($body) + { + $response = $this->_http->post('/v1/verifications/watchlist/trigger', $body); + return $this->buildCollection($response); + } + + public function trigger_watchlist($body) + { + return $this->triggerWatchlist($body); + } + + private function buildCollection($response, $query = null) + { + if ($response['ok']) { + $pager = $query === null ? [] : [ + 'object' => $this, + 'method' => 'search', + 'methodArgs' => $query + ]; + + return new ResourceCollection($response, $response['verifications'], $pager); + } else if ($response['errors']) { + throw new Exception\Standard($response['errors']); + } else { + throw new Exception\DownForMaintenance(); + } + } +} + +class_alias('Trolley\VerificationGateway', 'Trolley_VerificationGateway'); diff --git a/lib/Trolley/Version.php b/lib/Trolley/Version.php index c2db000..2f2963a 100644 --- a/lib/Trolley/Version.php +++ b/lib/Trolley/Version.php @@ -11,8 +11,8 @@ class Version * class constants */ const MAJOR = 3; - const MINOR = 0; - const TINY = 2; + const MINOR = 1; + const TINY = 0; /** * @ignore diff --git a/tests/unit/ReviewCommentTest.php b/tests/unit/ReviewCommentTest.php new file mode 100644 index 0000000..267cac6 --- /dev/null +++ b/tests/unit/ReviewCommentTest.php @@ -0,0 +1,214 @@ +assertSame('', InvoicePayment::factory([])->amount); + $this->assertSame('', OfflinePayment::factory([])->deletedAt); + $this->assertSame('', RecipientAccount::factory([])->recipientFees); + } + + public function testPaymentAttributesAreUnique() + { + $attributes = $this->attributesFor(Payment::factory([])); + + $this->assertSame(count($attributes), count(array_unique($attributes))); + } + + public function testRecipientOfflinePaymentsPaginationKeepsRecipientId() + { + $http = new FakeHttp([ + [ + 'ok' => true, + 'offlinePayments' => [['id' => 'OP-1']], + 'meta' => ['page' => 1, 'pages' => 3, 'records' => 2], + ], + [ + 'ok' => true, + 'offlinePayments' => [['id' => 'OP-2']], + 'meta' => ['page' => 2, 'pages' => 3, 'records' => 2], + ], + ]); + $gateway = $this->gatewayWithHttp('Trolley\RecipientGateway', $http); + + $ids = []; + foreach ($gateway->getAllOfflinePayments('R-1', ['recipientId' => 'R-wrong', 'pageSize' => 1]) as $payment) { + $ids[] = $payment->id; + } + + $this->assertSame(['OP-1', 'OP-2'], $ids); + $this->assertSame('/v1/recipients/R-1/offlinePayments', $http->requests[1][0]); + $this->assertSame(['page' => 2, 'pageSize' => 1], $http->requests[1][1]); + } + + public function testBalancePaginationHasPager() + { + $http = new FakeHttp([ + [ + 'ok' => true, + 'balances' => [['accountNumber' => 'A-1']], + 'meta' => ['page' => 1, 'pages' => 3, 'records' => 2], + ], + [ + 'ok' => true, + 'balances' => [['accountNumber' => 'A-2']], + 'meta' => ['page' => 2, 'pages' => 3, 'records' => 2], + ], + ]); + $gateway = $this->gatewayWithHttp('Trolley\BalanceGateway', $http); + + $accountNumbers = []; + foreach ($gateway->all(['pageSize' => 1]) as $balance) { + $accountNumbers[] = $balance->accountNumber; + } + + $this->assertSame(['A-1', 'A-2'], $accountNumbers); + $this->assertSame('/v1/balances', $http->requests[1][0]); + $this->assertSame(['page' => 2, 'pageSize' => 1], $http->requests[1][1]); + } + + public function testBalanceSearchPaginationKeepsPathSegment() + { + $http = new FakeHttp([ + [ + 'ok' => true, + 'balances' => [['accountNumber' => 'A-1']], + 'meta' => ['page' => 1, 'pages' => 3, 'records' => 2], + ], + [ + 'ok' => true, + 'balances' => [['accountNumber' => 'A-2']], + 'meta' => ['page' => 2, 'pages' => 3, 'records' => 2], + ], + ]); + $gateway = $this->gatewayWithHttp('Trolley\BalanceGateway', $http); + + $accountNumbers = []; + foreach ($gateway->search('paypal', ['params' => 'wrong', 'pageSize' => 1]) as $balance) { + $accountNumbers[] = $balance->accountNumber; + } + + $this->assertSame(['A-1', 'A-2'], $accountNumbers); + $this->assertSame('/v1/balances/paypal', $http->requests[1][0]); + $this->assertSame(['page' => 2, 'pageSize' => 1], $http->requests[1][1]); + } + + public function testBatchPaymentsPaginationKeepsBatchId() + { + $http = new FakeHttp([ + [ + 'ok' => true, + 'payments' => [['id' => 'P-1']], + 'meta' => ['page' => 1, 'pages' => 3, 'records' => 2], + ], + [ + 'ok' => true, + 'payments' => [['id' => 'P-2']], + 'meta' => ['page' => 2, 'pages' => 3, 'records' => 2], + ], + ]); + $gateway = $this->gatewayWithHttp('Trolley\BatchGateway', $http); + + $ids = []; + foreach ($gateway->payments('B-1', ['batchId' => 'B-wrong', 'pageSize' => 1]) as $payment) { + $ids[] = $payment->id; + } + + $this->assertSame(['P-1', 'P-2'], $ids); + $this->assertSame('/v1/batches/B-1/payments', $http->requests[1][0]); + $this->assertSame(['page' => 2, 'batchId' => 'B-1', 'pageSize' => 1], $http->requests[1][1]); + } + + public function testVerificationSearchPaginationKeepsQuery() + { + $http = new FakeHttp([ + [ + 'ok' => true, + 'verifications' => [['id' => 'V-1']], + 'meta' => ['page' => 1, 'pages' => 3, 'records' => 2], + ], + [ + 'ok' => true, + 'verifications' => [['id' => 'V-2']], + 'meta' => ['page' => 2, 'pages' => 3, 'records' => 2], + ], + ]); + $gateway = $this->gatewayWithHttp('Trolley\VerificationGateway', $http); + + $ids = []; + foreach ($gateway->search(['search' => 'Jane', 'pageSize' => 1]) as $verification) { + $ids[] = $verification['id']; + } + + $this->assertSame(['V-1', 'V-2'], $ids); + $this->assertSame('/v1/verifications', $http->requests[1][0]); + $this->assertSame(['page' => 2, 'search' => 'Jane', 'pageSize' => 1], $http->requests[1][1]); + } + + public function testVerificationMutationCollectionDoesNotPageThroughSearch() + { + $http = new FakeHttp([ + [ + 'ok' => true, + 'verifications' => [['id' => 'V-1']], + 'meta' => ['page' => 1, 'pages' => 3, 'records' => 2], + ], + ]); + $gateway = $this->gatewayWithHttp('Trolley\VerificationGateway', $http); + + $ids = []; + foreach ($gateway->triggerWatchlist(['recipientId' => 'R-1']) as $verification) { + $ids[] = $verification['id']; + } + + $this->assertSame(['V-1'], $ids); + $this->assertSame([['post', '/v1/verifications/watchlist/trigger', ['recipientId' => 'R-1']]], $http->requests); + } + + private function attributesFor($model) + { + $property = new ReflectionProperty($model, '_attributes'); + $property->setAccessible(true); + return $property->getValue($model); + } + + private function gatewayWithHttp($className, $http) + { + $reflection = new ReflectionClass($className); + $gateway = $reflection->newInstanceWithoutConstructor(); + $property = new ReflectionProperty($className, '_http'); + $property->setAccessible(true); + $property->setValue($gateway, $http); + return $gateway; + } +} + +class FakeHttp +{ + public $requests = []; + private $responses; + + public function __construct($responses) + { + $this->responses = $responses; + } + + public function get($path, $query = null) + { + $this->requests[] = [$path, $query]; + return array_shift($this->responses); + } + + public function post($path, $body = null) + { + $this->requests[] = ['post', $path, $body]; + return array_shift($this->responses); + } +}