Skip to content

Commit 9297444

Browse files
authored
Merge pull request #104 from alma/develop
Release 2.0.7
2 parents 343b639 + 5c0f150 commit 9297444

11 files changed

Lines changed: 339 additions & 14 deletions

File tree

.github/workflows/code-coverage.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: PHPUnit Coverage Report
22

33
on:
44
push:
5-
branches: [develop, master]
5+
branches: [develop, main]
66
pull_request:
7-
branches: [develop, master]
7+
branches: [develop, main]
88
workflow_dispatch: ~
99

1010
jobs:

.github/workflows/php.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: PHP Lint and unit tests
22

33
on:
44
push:
5-
branches: [master]
5+
branches: [main]
66
pull_request:
7-
branches: [master]
7+
branches: [main]
88
workflow_dispatch: ~
99

1010
jobs:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# See https://pre-commit.com/hooks.html for more hooks
33
repos:
44
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v4.4.0
5+
rev: v4.6.0
66
hooks:
77
- id: check-added-large-files
88
args: ["--maxkb=1024"]

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
v2.0.7
5+
-------
6+
* Add endpoint Order State
7+
8+
49
v2.0.6
510
-------
611
* Fix error in throw exception without sprintf

composer.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
{
22
"name": "alma/alma-php-client",
33
"description": "PHP API client for the Alma payments API",
4-
"version": "2.0.6",
4+
"version": "2.0.7",
55
"type": "library",
66
"require": {
77
"php": "^5.6 || ~7.0 || ~7.1 || ~7.2 || ~7.3 || ~7.4 || ~8.0 || ~8.1 || ~8.2",
88
"psr/log": "^1 || ^2 || ^3",
99
"ext-curl": "*",
1010
"ext-json": "*",
11-
"ext-simplexml": "*"
11+
"ext-simplexml": "*",
12+
"ext-iconv": "*"
1213
},
1314
"require-dev": {
14-
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
15+
"dealerdirect/phpcodesniffer-composer-installer": "^1.0.0",
1516
"phpcompatibility/php-compatibility": "^9.0",
16-
"phpunit/phpunit": "^5 || ^6 || ^7 || ^8 || ^9 || ^10",
17+
"phpunit/phpunit": "^5 || ^6 || ^7 || ^8 || ^9 || ^10 || ^11",
1718
"roave/security-advisories": "@dev",
1819
"squizlabs/php_codesniffer": "^3.3",
1920
"mockery/mockery": "^1.3"

src/Client.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
class Client
3232
{
33-
const VERSION = '2.0.6';
33+
const VERSION = '2.0.7';
3434

3535
const LIVE_MODE = 'live';
3636
const TEST_MODE = 'test';

src/Endpoints/Orders.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,30 @@
2626
namespace Alma\API\Endpoints;
2727

2828
use Alma\API\Entities\Order;
29+
use Alma\API\Exceptions\AlmaException;
30+
use Alma\API\Exceptions\MissingKeyException;
31+
use Alma\API\Exceptions\ParametersException;
32+
use Alma\API\Exceptions\RequestException;
33+
use Alma\API\Lib\ArrayUtils;
2934
use Alma\API\RequestError;
3035
use Alma\API\PaginatedResults;
3136

3237
class Orders extends Base
3338
{
39+
/**
40+
* @var ArrayUtils
41+
*/
42+
public $arrayUtils;
43+
3444
const ORDERS_PATH = '/v1/orders';
45+
const ORDERS_PATH_V2 = '/v2/orders';
46+
47+
public function __construct($client_context)
48+
{
49+
parent::__construct($client_context);
50+
51+
$this->arrayUtils = new ArrayUtils();
52+
}
3553

3654
/**
3755
* @param string $orderId
@@ -90,4 +108,57 @@ public function fetch($orderId)
90108
$response = $this->request(self::ORDERS_PATH . "/{$orderId}")->get();
91109
return new Order($response->json);
92110
}
111+
112+
/**
113+
* @param string $orderExternalId
114+
* @param array $orderData
115+
* @return void
116+
* @throws ParametersException
117+
* @throws RequestException
118+
*/
119+
public function sendStatus($orderExternalId, $orderData = array())
120+
{
121+
$this->validateStatusData($orderData);
122+
$label = $this->arrayUtils->slugify($orderData['status']);
123+
124+
try {
125+
$response = $this->request(self::ORDERS_PATH_V2 . "/{$orderExternalId}/status")->setRequestBody(array(
126+
'status' => $label,
127+
'is_shipped' => $orderData['is_shipped'],
128+
))->post();
129+
}catch (AlmaException $e) {
130+
$this->logger->error('Error sending status');
131+
throw new RequestException('Error sending status', $e);
132+
}
133+
134+
if ($response->isError()) {
135+
throw new RequestException($response->errorMessage, null, $response);
136+
}
137+
}
138+
139+
/**
140+
* @param array $orderData
141+
* @return void
142+
* @throws ParametersException
143+
*/
144+
public function validateStatusData($orderData = array())
145+
{
146+
if(count($orderData) == 0) {
147+
throw new ParametersException('Missing in the required parameters (status, is_shipped) when calling orders.sendStatus');
148+
}
149+
150+
try {
151+
$this->arrayUtils->checkMandatoryKeys(['status', 'is_shipped'], $orderData);
152+
} catch (MissingKeyException $e ) {
153+
throw new ParametersException('Error in the required parameters (status, is_shipped) when calling orders.sendStatus',null, $e);
154+
}
155+
156+
if(!is_bool($orderData['is_shipped'])) {
157+
throw new ParametersException('Parameter "is_shipped" must be a boolean');
158+
}
159+
160+
if(!$orderData['status']) {
161+
throw new ParametersException('Missing the required parameter "status" when calling orders.sendStatus');
162+
}
163+
}
93164
}

src/Lib/ArrayUtils.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626

2727
namespace Alma\API\Lib;
2828

29+
use Alma\API\Exceptions\AlmaException;
2930
use Alma\API\Exceptions\MissingKeyException;
31+
use Alma\API\Exceptions\ParametersException;
3032

3133
/**
3234
* Class ArrayUtils
@@ -64,4 +66,48 @@ public function checkMandatoryKeys($keys, $array)
6466
}
6567
}
6668
}
69+
70+
/**
71+
* Return the slug of a string to be used in a URL.
72+
*
73+
* @param string $textToSlugify
74+
*
75+
* @throws ParametersException
76+
*
77+
* @return String
78+
*/
79+
public function slugify($textToSlugify){
80+
if(!is_string($textToSlugify)) {
81+
throw new ParametersException('Status must be a string');
82+
}
83+
84+
// trim
85+
$text = trim($textToSlugify, '-');
86+
87+
// replace non letter or digits by -
88+
$text = preg_replace('~[^\pL\d]+~u', '_', $text);
89+
90+
// transliterate
91+
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
92+
93+
// remove unwanted characters
94+
$text = preg_replace('~[^-\w]+~', '', $text);
95+
96+
97+
// remove duplicated - symbols
98+
$text = preg_replace('~-+~', '-', $text);
99+
100+
// lowercase
101+
$text = strtolower($text);
102+
103+
if (
104+
empty($text)
105+
|| '_' === $text
106+
) {
107+
throw new ParametersException(sprintf('The slug is empty, status "%s"', $textToSlugify));
108+
}
109+
110+
return $text;
111+
}
112+
67113
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<?php
2+
3+
namespace Alma\API\Tests\Unit\Legacy\Endpoints;
4+
5+
6+
use Alma\API\ClientContext;
7+
use Alma\API\Endpoints\Orders;
8+
9+
use Alma\API\Exceptions\MissingKeyException;
10+
use Alma\API\Exceptions\ParametersException;
11+
use Alma\API\Exceptions\RequestException;
12+
use Alma\API\Lib\ArrayUtils;
13+
use Alma\API\Request;
14+
use Alma\API\Response;
15+
use PHPUnit\Framework\TestCase;
16+
use Psr\Log\LoggerInterface;
17+
18+
class OrdersTest extends TestCase
19+
{
20+
21+
/**
22+
* @var \Mockery\Mock|(\Mockery\MockInterface&Orders)
23+
*/
24+
protected $orderEndpoint;
25+
26+
public function setUp()
27+
{
28+
$this->clientContext = \Mockery::mock(ClientContext::class);
29+
$this->orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
30+
$this->arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
31+
$this->responseMock = \Mockery::mock(Response::class);
32+
$this->requestObject = \Mockery::mock(Request::class);
33+
$loggerMock = \Mockery::mock(LoggerInterface::class);
34+
$loggerMock->shouldReceive('error');
35+
36+
$this->orderEndpoint->arrayUtils = $this->arrayUtils;
37+
$this->externalId = 'Mon external Id';
38+
$this->status = 'Mon Status - 1';
39+
$this->clientContext->logger = $loggerMock;
40+
$this->orderEndpoint->setClientContext($this->clientContext);
41+
42+
}
43+
public function testValidateStatusDataNoOrderData()
44+
{
45+
$this->expectException(ParametersException::class);
46+
$this->expectExceptionMessage('Missing in the required parameters (status, is_shipped) when calling orders.sendStatus');
47+
$this->orderEndpoint->validateStatusData();
48+
}
49+
50+
public function testValidateStatusDataMissingSomeOrderData()
51+
{
52+
$orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
53+
$arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
54+
$arrayUtils->shouldReceive('checkMandatoryKeys')->andThrow(new MissingKeyException());
55+
$orderEndpoint->arrayUtils = $arrayUtils;
56+
57+
$this->expectException(ParametersException::class);
58+
$this->expectExceptionMessage('Error in the required parameters (status, is_shipped) when calling orders.sendStatus');
59+
$orderEndpoint->validateStatusData(array('status'));
60+
}
61+
62+
public function testValidateStatusDataIsShippedNotBool()
63+
{
64+
$orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
65+
$arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
66+
$arrayUtils->shouldReceive('checkMandatoryKeys')->andReturn(null);
67+
$orderEndpoint->arrayUtils = $arrayUtils;
68+
69+
$this->expectException(ParametersException::class);
70+
$this->expectExceptionMessage('Parameter "is_shipped" must be a boolean');
71+
72+
$orderEndpoint->validateStatusData(array(
73+
'status' => $this->status,
74+
'is_shipped' => 'oui',
75+
));
76+
}
77+
78+
public function testValidateStatusDataStatusIsEmpty()
79+
{
80+
$orderEndpoint = \Mockery::mock(Orders::class)->makePartial();
81+
$arrayUtils = \Mockery::mock(ArrayUtils::class)->makePartial();
82+
$arrayUtils->shouldReceive('checkMandatoryKeys')->andReturn(null);
83+
$orderEndpoint->arrayUtils = $arrayUtils;
84+
85+
$this->expectException(ParametersException::class);
86+
$this->expectExceptionMessage('Missing the required parameter "status" when calling orders.sendStatus');
87+
88+
$orderEndpoint->validateStatusData(array(
89+
'status' => '',
90+
'is_shipped' => true,
91+
));
92+
}
93+
94+
public function testSendStatusOK()
95+
{
96+
$this->orderEndpoint->shouldReceive('validateStatusData')->andReturn(null);
97+
98+
$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
99+
$this->requestObject->shouldReceive('setRequestBody')->andReturn($this->requestObject);
100+
101+
$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
102+
$this->orderEndpoint->shouldReceive('request')
103+
->with(Orders::ORDERS_PATH_V2 . "/{$this->externalId}/status")
104+
->once()
105+
->andReturn($this->requestObject);
106+
107+
$this->orderEndpoint->sendStatus($this->externalId , array(
108+
'status' => $this->status,
109+
'is_shipped' => true,
110+
));
111+
}
112+
113+
public function testSendStatusRequestError()
114+
{
115+
$this->orderEndpoint->shouldReceive('validateStatusData')->andReturn(null);
116+
117+
$this->responseMock->shouldReceive('isError')->once()->andReturn(true);
118+
$this->requestObject->shouldReceive('setRequestBody')->andReturn($this->requestObject);
119+
120+
$this->requestObject->shouldReceive('post')->once()->andReturn($this->responseMock);
121+
$this->orderEndpoint->shouldReceive('request')
122+
->with(Orders::ORDERS_PATH_V2 . "/{$this->externalId}/status")
123+
->once()
124+
->andReturn($this->requestObject);
125+
126+
$this->expectException(RequestException::class);
127+
$this->orderEndpoint->sendStatus($this->externalId , array(
128+
'status' => $this->status,
129+
'is_shipped' => true,
130+
));
131+
132+
}
133+
public function testSendStatusWithException()
134+
{
135+
$this->orderEndpoint->shouldReceive('validateStatusData')->andReturn(null);
136+
137+
$this->responseMock->shouldReceive('isError')->once()->andReturn(false);
138+
$this->requestObject->shouldReceive('setRequestBody')->andReturn($this->requestObject);
139+
140+
$this->requestObject->shouldReceive('post')->andThrow(new RequestException());
141+
$this->orderEndpoint->shouldReceive('request')
142+
->with(Orders::ORDERS_PATH_V2 . "/{$this->externalId}/status")
143+
->once()
144+
->andReturn($this->requestObject);
145+
146+
$this->expectException(RequestException::class);
147+
$this->orderEndpoint->sendStatus($this->externalId , array(
148+
'status' => $this->status,
149+
'is_shipped' => true,
150+
));
151+
}
152+
153+
154+
public function tearDown()
155+
{
156+
$this->orderEndpoint = null;
157+
$this->arrayUtils = null;
158+
$this->responseMock = null;
159+
$this->requestObject = null;
160+
}
161+
162+
}

0 commit comments

Comments
 (0)