Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tests and api orders status #99

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/code-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: PHPUnit Coverage Report

on:
push:
branches: [develop, master]
branches: [develop, main]
pull_request:
branches: [develop, master]
branches: [develop, main]
workflow_dispatch: ~

jobs:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: PHP Lint and unit tests

on:
push:
branches: [master]
branches: [main]
pull_request:
branches: [master]
branches: [main]
workflow_dispatch: ~

jobs:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
CHANGELOG
=========

v2.0.6
-------
* Fix error in throw exception without sprintf

v2.0.5
-------
* Fix endpoint customer-carts
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"name": "alma/alma-php-client",
"description": "PHP API client for the Alma payments API",
"version": "2.0.5",
"version": "2.0.6",
"type": "library",
"require": {
"php": "^5.6 || ~7.0 || ~7.1 || ~7.2 || ~7.3 || ~7.4 || ~8.0 || ~8.1 || ~8.2",
"psr/log": "^1 || ^2 || ^3",
"ext-curl": "*",
"ext-json": "*",
"ext-simplexml": "*"
"ext-simplexml": "*",
"ext-iconv": "*"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
Expand Down
2 changes: 1 addition & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

class Client
{
const VERSION = '2.0.5';
const VERSION = '2.0.6';

const LIVE_MODE = 'live';
const TEST_MODE = 'test';
Expand Down
71 changes: 71 additions & 0 deletions src/Endpoints/Orders.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,30 @@
namespace Alma\API\Endpoints;

use Alma\API\Entities\Order;
use Alma\API\Exceptions\AlmaException;
use Alma\API\Exceptions\MissingKeyException;
use Alma\API\Exceptions\ParametersException;
use Alma\API\Exceptions\RequestException;
use Alma\API\Lib\ArrayUtils;
use Alma\API\RequestError;
use Alma\API\PaginatedResults;

class Orders extends Base
{
/**
* @var ArrayUtils
*/
public $arrayUtils;

const ORDERS_PATH = '/v1/orders';
const ORDERS_PATH_V2 = '/2/orders';

public function __construct($client_context)
{
parent::__construct($client_context);

$this->arrayUtils = new ArrayUtils();
}

/**
* @param string $orderId
Expand Down Expand Up @@ -90,4 +108,57 @@ public function fetch($orderId)
$response = $this->request(self::ORDERS_PATH . "/{$orderId}")->get();
return new Order($response->json);
}

/**
* @param string $orderExternalId
* @param array $orderData
* @return void
* @throws ParametersException
* @throws RequestException
*/
public function sendStatus($orderExternalId, $orderData = array())
{
$this->validateStatusData($orderData);
$label = $this->arrayUtils->slugify($orderData['label']);

try {
$response = $this->request(self::ORDERS_PATH_V2 . "/{$orderExternalId}/status")->setRequestBody(array(
'label' => $label,
'is_shipped' => $orderData['is_shipped'],
))->post();
}catch (AlmaException $e) {
$this->logger->error('Error sending status');
throw new RequestException('Error sending status', $e);
}

if ($response->isError()) {
throw new RequestException($response->errorMessage, null, $response);
}
}

/**
* @param array $orderData
* @return void
* @throws ParametersException
*/
public function validateStatusData($orderData = array())
{
if(count($orderData) == 0) {
throw new ParametersException('Missing in the required parameters (label, is_shipped) when calling orders.sendStatus');
}

try {
$this->arrayUtils->checkMandatoryKeys(['label', 'is_shipped'], $orderData);
} catch (MissingKeyException $e ) {
throw new ParametersException('Error in the required parameters (label, is_shipped) when calling orders.sendStatus',null, $e);
}

if(!is_bool($orderData['is_shipped'])) {
throw new ParametersException('Parameter "is_shipped" must be a boolean');
}

if(!$orderData['label']) {
throw new ParametersException('Missing the required parameter "label" when calling orders.sendStatus');
}
}
}
53 changes: 52 additions & 1 deletion src/Lib/ArrayUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@

namespace Alma\API\Lib;

use Alma\API\Exceptions\AlmaException;
use Alma\API\Exceptions\MissingKeyException;
use Alma\API\Exceptions\ParametersException;

/**
* Class ArrayUtils
Expand Down Expand Up @@ -55,8 +57,57 @@ public function checkMandatoryKeys($keys, $array)
{
foreach ($keys as $key) {
if(!array_key_exists($key, $array)){
throw new MissingKeyException('The key "%s" is missing from the array "%s"', $key, json_encode($array));
throw new MissingKeyException(
sprintf(
'The key "%s" is missing from the array "%s"',
$key,
json_encode($array)
));
}
}
}

/**
* Return the slug of a string to be used in a URL.
*
* @param string $textToSlugify
*
* @throws ParametersException
*
* @return String
*/
public function slugify($textToSlugify){
if(!is_string($textToSlugify)) {
throw new ParametersException('Label must be a string');
}

// trim
$text = trim($textToSlugify, '-');

// replace non letter or digits by -
$text = preg_replace('~[^\pL\d]+~u', '_', $text);

// transliterate
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);

// remove unwanted characters
$text = preg_replace('~[^-\w]+~', '', $text);


// remove duplicated - symbols
$text = preg_replace('~-+~', '-', $text);

// lowercase
$text = strtolower($text);

if (
empty($text)
|| '_' === $text
) {
throw new ParametersException(sprintf('The slug is empty, label "%s"', $textToSlugify));
}

return $text;
}

}
162 changes: 162 additions & 0 deletions tests/Unit/Legacy/Endpoints/OrdersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<?php

namespace Alma\API\Tests\Unit\Legacy\Endpoints;


use Alma\API\ClientContext;
use Alma\API\Endpoints\Orders;

use Alma\API\Exceptions\MissingKeyException;
use Alma\API\Exceptions\ParametersException;
use Alma\API\Exceptions\RequestException;
use Alma\API\Lib\ArrayUtils;
use Alma\API\Request;
use Alma\API\Response;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;

class OrdersTest extends TestCase
{

/**
* @var \Mockery\Mock|(\Mockery\MockInterface&Orders)
*/
protected $orderEndpoint;

public function setUp()
{
$this->clientContext = \Mockery::mock(ClientContext::class);
$this->orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
$this->arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
$this->responseMock = \Mockery::mock(Response::class);
$this->requestObject = \Mockery::mock(Request::class);
$loggerMock = \Mockery::mock(LoggerInterface::class);
$loggerMock->shouldReceive('error');

$this->orderEndpoint->arrayUtils = $this->arrayUtils;
$this->externalId = 'Mon external Id';
$this->label = 'Mon Label - 1';
$this->clientContext->logger = $loggerMock;
$this->orderEndpoint->setClientContext($this->clientContext);

}
public function testValidateStatusDataNoOrderData()
{
$this->expectException(ParametersException::class);
$this->expectExceptionMessage('Missing in the required parameters (label, is_shipped) when calling orders.sendStatus');
$this->orderEndpoint->validateStatusData();
}

public function testValidateStatusDataMissingSomeOrderData()
{
$orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
$arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
$arrayUtils->shouldReceive('checkMandatoryKeys')->andThrow(new MissingKeyException());
$orderEndpoint->arrayUtils = $arrayUtils;

$this->expectException(ParametersException::class);
$this->expectExceptionMessage('Error in the required parameters (label, is_shipped) when calling orders.sendStatus');
$orderEndpoint->validateStatusData(array('label'));
}

public function testValidateStatusDataIsShippedNotBool()
{
$orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
$arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
$arrayUtils->shouldReceive('checkMandatoryKeys')->andReturn(null);
$orderEndpoint->arrayUtils = $arrayUtils;

$this->expectException(ParametersException::class);
$this->expectExceptionMessage('Parameter "is_shipped" must be a boolean');

$orderEndpoint->validateStatusData(array(
'label' => $this->label,
'is_shipped' => 'oui',
));
}

public function testValidateStatusDataLabelIsEmpty()
{
$orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
$arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
$arrayUtils->shouldReceive('checkMandatoryKeys')->andReturn(null);
$orderEndpoint->arrayUtils = $arrayUtils;

$this->expectException(ParametersException::class);
$this->expectExceptionMessage('Missing the required parameter "label" when calling orders.sendStatus');

$orderEndpoint->validateStatusData(array(
'label' => '',
'is_shipped' => true,
));
}

public function testSendStatusOK()
{
$this->orderEndpoint->shouldReceive('validateStatusData')->andReturn(null);

$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
$this->requestObject->shouldReceive('setRequestBody')->andReturn($this->requestObject);

$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
$this->orderEndpoint->shouldReceive('request')
->with(Orders::ORDERS_PATH_V2 . "/{$this->externalId}/status")
->once()
->andReturn($this->requestObject);

$this->orderEndpoint->sendStatus($this->externalId , array(
'label' => $this->label,
'is_shipped' => true,
));
}

public function testSendStatusRequestError()
{
$this->orderEndpoint->shouldReceive('validateStatusData')->andReturn(null);

$this->responseMock->shouldReceive('isError')->once()->andReturn(true);
$this->requestObject->shouldReceive('setRequestBody')->andReturn($this->requestObject);

$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
$this->orderEndpoint->shouldReceive('request')
->with(Orders::ORDERS_PATH_V2 . "/{$this->externalId}/status")
->once()
->andReturn($this->requestObject);

$this->expectException(RequestException::class);
$this->orderEndpoint->sendStatus($this->externalId , array(
'label' => $this->label,
'is_shipped' => true,
));

}
public function testSendStatusWithException()
{
$this->orderEndpoint->shouldReceive('validateStatusData')->andReturn(null);

$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
$this->requestObject->shouldReceive('setRequestBody')->andReturn($this->requestObject);

$this->requestObject->shouldReceive('post')->andThrow(new RequestException());
$this->orderEndpoint->shouldReceive('request')
->with(Orders::ORDERS_PATH_V2 . "/{$this->externalId}/status")
->once()
->andReturn($this->requestObject);

$this->expectException(RequestException::class);
$this->orderEndpoint->sendStatus($this->externalId , array(
'label' => $this->label,
'is_shipped' => true,
));
}


public function tearDown()
{
$this->orderEndpoint = null;
$this->arrayUtils = null;
$this->responseMock = null;
$this->requestObject = null;
}

}
5 changes: 1 addition & 4 deletions tests/Unit/Legacy/Endpoints/PaymentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Alma\API\Exceptions\ParametersException;
use Alma\API\Exceptions\RequestException;
use Alma\API\Response;
use Mockery;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -514,8 +515,4 @@ public function testFullRefundRequestError()
$payments->fullRefund($id);
}

public function tearDown()
{
Mockery::close();
}
}
Loading