Skip to content

Commit a32d5f6

Browse files
committed
API-599: replace integration tests by end-to-end tests
1 parent 46c4609 commit a32d5f6

File tree

90 files changed

+750
-12475
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+750
-12475
lines changed

.ci/Jenkinsfile

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateAction
44
import groovy.transform.Field
55

66
String launchUnitTests = "yes"
7-
String launchIntegrationTests = "yes"
7+
String launchEndToEndTests = "yes"
88
String[] pimVersions = ["1.7", "2.0"]
99
String[] supportedPhpVersions = ["5.6", "7.0", "7.1"]
1010
@Field def String verboseOutputs = "yes"
@@ -30,17 +30,17 @@ try {
3030
userInput = input(message: 'Launch tests?', parameters: [
3131
string(defaultValue: pimVersions.join(','), description: 'PIM edition the tests should run on', name: 'requiredPimVersions'),
3232
choice(choices: 'yes\nno', description: 'Run unit tests and code style checks', name: 'launchUnitTests'),
33-
choice(choices: 'yes\nno', description: 'Run integration tests', name: 'launchIntegrationTests'),
33+
choice(choices: 'yes\nno', description: 'Run end-to-end tests', name: 'launchEndToEndTests'),
3434
choice(choices: 'no\nyes', description: 'Enable Verbose mode', name: 'verboseOutputs'),
3535
string(defaultValue: '50', description: 'Number of dots per line', name: 'dotsperline'),
36-
string(defaultValue: clients.join(','), description: 'Clients used to run integration tests (comma separated values)', name: 'clients'),
36+
string(defaultValue: clients.join(','), description: 'Clients used to run end-to-end tests (comma separated values)', name: 'clients'),
3737
choice(choices: 'no\nyes', description: 'Enable Verbose mode', name: 'verboseOutputs'),
3838
string(defaultValue: '50', description: 'Number of dots per line', name: 'dotsperline'),
3939
])
4040

4141
pimVersions = userInput['requiredPimVersions'].tokenize(',')
4242
launchUnitTests = userInput['launchUnitTests']
43-
launchIntegrationTests = userInput['launchIntegrationTests']
43+
launchEndToEndTests = userInput['launchEndToEndTests']
4444
clients = userInput['clients'].tokenize(',')
4545
verboseOutputs = userInput['verboseOutputs']
4646
dotsPerLine = userInput['dotsperline']
@@ -60,7 +60,7 @@ try {
6060
}
6161
}
6262

63-
if (launchIntegrationTests.equals("yes")) {
63+
if (launchEndToEndTests.equals("yes")) {
6464
for (pimVersion in pimVersions) {
6565
String currentPimVersion = pimVersion
6666

@@ -117,7 +117,7 @@ try {
117117
}
118118
}
119119

120-
if (launchIntegrationTests.equals("yes")) {
120+
if (launchEndToEndTests.equals("yes")) {
121121
for (pimVersion in pimVersions) {
122122
String currentPimVersion = pimVersion
123123
stage("Integration tests ${currentPimVersion}") {
@@ -270,7 +270,7 @@ void runPhpSpecTest(String phpVersion, String client, String psrImplem) {
270270
}
271271

272272
/**
273-
* Run integration tests of the PHP client, for a given PHP version, HTTP client, PSR7 implementation and a PIM version.
273+
* Run end-to-end tests of the PHP client, for a given PHP version, HTTP client, PSR7 implementation and a PIM version.
274274
* First, it starts the PIM. The configuration of the PIM (composer, parameters) is already done in the checkout step.
275275
* Then, it launches the PHPUnit tests.
276276
*
@@ -298,7 +298,7 @@ void runIntegrationTest(String phpVersion, String client, String psrImplem, Stri
298298
}
299299

300300
/**
301-
* Run integration tests of the PHP client, for a given PHP version, HTTP client and PSR7 implementation on PIM version 1.7.
301+
* Run end-to-end tests of the PHP client, for a given PHP version, HTTP client and PSR7 implementation on PIM version 1.7.
302302
*
303303
* 1) Ask to use Kubernetes PIM 1.7 pod template with specific data images (Depending on phpVersion, client, psrImplem)
304304
* 2) Scan all PHP test files in folder "tests/v1_7/Api" and "tests/Common/Api"
@@ -323,7 +323,7 @@ def runPim17IntegrationTest(String phpVersion, String client, String psrImplem)
323323
def messages = new net.sf.json.JSONArray()
324324
def files = []
325325

326-
// Find and store PHP test integration files to launch them in parallels
326+
// Find and store PHP test end-to-end files to launch them in parallels
327327
files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/v1_7/Api -name "*Integration.php"').tokenize('\n')
328328
files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/Common/Api -name "*Integration.php"').tokenize('\n')
329329

@@ -358,7 +358,7 @@ def runPim17IntegrationTest(String phpVersion, String client, String psrImplem)
358358
}
359359

360360
/**
361-
* Run integration tests of the PHP client, for a given PHP version, HTTP client and PSR7 implementation on PIM version 2.0.
361+
* Run end-to-end tests of the PHP client, for a given PHP version, HTTP client and PSR7 implementation on PIM version 2.0.
362362
*
363363
* 1) Ask to use Kubernetes PIM 2.0 pod template with specific data images (Depending on phpVersion, client, psrImplem)
364364
* 2) Scan all PHP test files in folder "tests/v2_0/Api" and "tests/Common/Api"
@@ -382,7 +382,7 @@ def runPim2IntegrationTest(String phpVersion, String client, String psrImplem, S
382382
def messages = new net.sf.json.JSONArray()
383383
def files = []
384384

385-
// Find and store PHP test integration files to launch them in parallels
385+
// Find and store PHP test end-to-end files to launch them in parallels
386386
files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/v2_0/Api -name "*Integration.php"').tokenize('\n')
387387
files += sh (returnStdout: true, script: 'find /home/jenkins/php-api-client/tests/Common/Api -name "*Integration.php"').tokenize('\n')
388388
for (file in files) {

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"friendsofphp/php-cs-fixer": "^v2.3",
3434
"phpunit/phpunit": "5.7.*",
3535
"phpspec/phpspec": "3.2.*",
36-
"symfony/yaml": "^3.3"
36+
"symfony/yaml": "^3.3",
37+
"donatj/mock-webserver": "^2.0"
3738
},
3839
"config": {
3940
"bin-dir": "bin"

tests/Api/ApiTestCase.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace Akeneo\Pim\ApiClient\tests\Api;
4+
5+
use Akeneo\Pim\ApiClient\AkeneoPimClientBuilder;
6+
use Akeneo\Pim\ApiClient\AkeneoPimClientInterface;
7+
use Akeneo\Pim\ApiClient\Api\AuthenticationApi;
8+
use donatj\MockWebServer\MockWebServer;
9+
use donatj\MockWebServer\Response;
10+
use donatj\MockWebServer\ResponseStack;
11+
use Http\Message\StreamFactory;
12+
use Http\Discovery\StreamFactoryDiscovery;
13+
14+
/**
15+
* @author Laurent Petard <[email protected]>
16+
* @copyright 2017 Akeneo SAS (http://www.akeneo.com)
17+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18+
*/
19+
abstract class ApiTestCase extends \PHPUnit_Framework_TestCase
20+
{
21+
/** @var MockWebServer */
22+
protected $server;
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
protected function setUp()
28+
{
29+
$this->server = new MockWebServer(8081, '127.0.0.1');
30+
$this->server->start();
31+
32+
$this->server->setResponseOfPath(
33+
'/'. AuthenticationApi::TOKEN_URI,
34+
new ResponseStack(
35+
new Response($this->getAuthenticatedJson())
36+
)
37+
);
38+
}
39+
40+
/**
41+
* @return AkeneoPimClientInterface
42+
*/
43+
protected function createClient()
44+
{
45+
$clientBuilder = new AkeneoPimClientBuilder($this->server->getServerRoot());
46+
47+
return $clientBuilder->buildAuthenticatedByPassword(
48+
'client_id',
49+
'secret',
50+
'username',
51+
'password'
52+
);
53+
}
54+
55+
private function getAuthenticatedJson()
56+
{
57+
return <<<JSON
58+
{
59+
"refresh_token" : "this-is-a-refresh-token",
60+
"access_token" : "this-is-an-access-token"
61+
}
62+
JSON;
63+
}
64+
65+
/**
66+
* @return StreamFactory
67+
*/
68+
protected function getStreamFactory()
69+
{
70+
return StreamFactoryDiscovery::find();
71+
}
72+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Akeneo\Pim\ApiClient\tests\Api;
4+
5+
use Akeneo\Pim\ApiClient\Api\ProductApi;
6+
use Akeneo\Pim\ApiClient\Api\ProductMediaFileApi;
7+
use Akeneo\Pim\ApiClient\Pagination\PageInterface;
8+
use Akeneo\Pim\ApiClient\tests\MediaSanitizer;
9+
use donatj\MockWebServer\Response;
10+
use donatj\MockWebServer\ResponseStack;
11+
12+
class CreateProductMediaFileTest extends ApiTestCase
13+
{
14+
public function test_create_media_file()
15+
{
16+
$mediaFileURI = $this->server->getServerRoot(). '/' . ProductMediaFileApi::MEDIA_FILES_URI.'/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png';
17+
$this->server->setResponseOfPath(
18+
'/'. ProductMediaFileApi::MEDIA_FILES_URI,
19+
new ResponseStack(
20+
new Response('', ['Location' => $mediaFileURI], 201)
21+
)
22+
);
23+
24+
$api = $this->createClient()->getProductMediaFileApi();
25+
$mediaFile = realpath(__DIR__ . '/../fixtures/akeneo.png');
26+
27+
$response = $api->create($mediaFile, [
28+
'identifier' => 'medium_boot',
29+
'attribute' => 'side_view',
30+
'scope' => null,
31+
'locale' => null,
32+
]);
33+
34+
$this->assertSame('f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png', $response);
35+
}
36+
}

tests/Api/CreateProductTest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Akeneo\Pim\ApiClient\tests\Api;
4+
5+
use Akeneo\Pim\ApiClient\Api\ProductApi;
6+
use donatj\MockWebServer\Response;
7+
use donatj\MockWebServer\ResponseStack;
8+
9+
class CreateProductTest extends ApiTestCase
10+
{
11+
public function test_create_product()
12+
{
13+
$this->server->setResponseOfPath(
14+
'/'. sprintf(ProductApi::PRODUCTS_URI, 'black_sneakers'),
15+
new ResponseStack(
16+
new Response('', [], 201)
17+
)
18+
);
19+
20+
$api = $this->createClient()->getProductApi();
21+
$response = $api->create('new_shoes', $this->newProduct());
22+
23+
$this->assertSame(201, $response);
24+
}
25+
26+
/**
27+
* @expectedException \Akeneo\Pim\ApiClient\Exception\UnprocessableEntityHttpException
28+
* @expectedExceptionMessage The value black_sneakers is already set on another product for the unique attribute sku
29+
*/
30+
public function test_create_invalid_product()
31+
{
32+
$this->server->setResponseOfPath(
33+
'/'. sprintf(ProductApi::PRODUCTS_URI, 'black_sneakers'),
34+
new ResponseStack(
35+
new Response('{"code": 422, "message":"The value black_sneakers is already set on another product for the unique attribute sku"}', [], 422)
36+
)
37+
);
38+
39+
$api = $this->createClient()->getProductApi();
40+
$api->create('new_shoes', $this->newProduct());
41+
}
42+
43+
private function newProduct()
44+
{
45+
return [
46+
'enabled' => false,
47+
'family' => 'sandals',
48+
'categories' => ['summer_collection'],
49+
'values' => [
50+
'name' => [
51+
[
52+
'data' => 'The pumps',
53+
'locale' => 'en_US',
54+
'scope' => null,
55+
],
56+
[
57+
'data' => 'Les pumps',
58+
'locale' => 'fr_FR',
59+
'scope' => null,
60+
]
61+
]
62+
]
63+
];
64+
}
65+
}

tests/Api/DeleteProductTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Akeneo\Pim\ApiClient\tests\Api;
4+
5+
use Akeneo\Pim\ApiClient\Api\ProductApi;
6+
use donatj\MockWebServer\Response;
7+
use donatj\MockWebServer\ResponseStack;
8+
9+
class DeleteProductTest extends ApiTestCase
10+
{
11+
public function test_create_product()
12+
{
13+
$this->server->setResponseOfPath(
14+
'/'. sprintf(ProductApi::PRODUCT_URI, 'docks_white'),
15+
new ResponseStack(
16+
new Response('', [], 204)
17+
)
18+
);
19+
20+
$api = $this->createClient()->getProductApi();
21+
22+
$response = $api->delete('docks_white');
23+
24+
$this->assertSame(204, $response);
25+
}
26+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Akeneo\Pim\ApiClient\tests\Api;
4+
5+
use Akeneo\Pim\ApiClient\Api\ProductApi;
6+
use Akeneo\Pim\ApiClient\Api\ProductMediaFileApi;
7+
use Akeneo\Pim\ApiClient\Pagination\PageInterface;
8+
use donatj\MockWebServer\Response;
9+
use donatj\MockWebServer\ResponseStack;
10+
use Psr\Http\Message\StreamInterface;
11+
12+
class DownloadProductMediaFileTest extends ApiTestCase
13+
{
14+
public function test_download_media_file()
15+
{
16+
$expectedMediaFile = realpath(__DIR__ . '/../fixtures/akeneo.png');
17+
18+
$this->server->setResponseOfPath(
19+
'/'. sprintf(ProductMediaFileApi::MEDIA_FILE_DOWNLOAD_URI, '/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png'),
20+
new ResponseStack(
21+
new Response(file_get_contents($expectedMediaFile), [], 201)
22+
)
23+
);
24+
25+
$api = $this->createClient()->getProductMediaFileApi();
26+
$mediaFile = $api->download('/f/b/0/6/fb068ccc9e3c5609d73c28d852812ba5faeeab28_akeneo.png');
27+
28+
$this->assertInstanceOf(StreamInterface::class, $mediaFile);
29+
$this->assertSame(file_get_contents($expectedMediaFile), $mediaFile->getContents());
30+
}
31+
}

tests/Api/GetProductTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace Akeneo\Pim\ApiClient\tests\Api;
4+
5+
use Akeneo\Pim\ApiClient\Api\ProductApi;
6+
use donatj\MockWebServer\Response;
7+
use donatj\MockWebServer\ResponseStack;
8+
9+
class GetProductTest extends ApiTestCase
10+
{
11+
public function test_get_product()
12+
{
13+
$this->server->setResponseOfPath(
14+
'/'. sprintf(ProductApi::PRODUCT_URI, 'black_sneakers'),
15+
new ResponseStack(
16+
new Response($this->getProduct(), [], 200)
17+
)
18+
);
19+
20+
$api = $this->createClient()->getProductApi();
21+
22+
$product = $api->get('black_sneakers');
23+
24+
$this->assertEquals($product, json_decode($this->getProduct(), true));
25+
}
26+
27+
/**
28+
* @expectedException \Akeneo\Pim\ApiClient\Exception\NotFoundHttpException
29+
* @expectedExceptionMessage Resource `black_sneakers` does not exist.
30+
*/
31+
public function test_get_unknow_product()
32+
{
33+
$this->server->setResponseOfPath(
34+
'/'. sprintf(ProductApi::PRODUCT_URI, 'black_sneakers'),
35+
new ResponseStack(
36+
new Response('{"code": 404, "message":"Resource `black_sneakers` does not exist."}', [], 404)
37+
)
38+
);
39+
40+
$api = $this->createClient()->getProductApi();
41+
$api->get('black_sneakers');
42+
}
43+
44+
private function getProduct()
45+
{
46+
return <<<JSON
47+
[
48+
{
49+
"identifier" : "black_sneakers",
50+
"family" : "sneakers",
51+
"groups": [],
52+
"categories": ['summer_collection'],
53+
"values": [{
54+
'color': {'locale': null, 'scope': null, 'data': 'black'}
55+
}],
56+
}
57+
]
58+
JSON;
59+
}
60+
}

0 commit comments

Comments
 (0)