Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #39 from sanmai/pr/test-new-keys-2019
Browse files Browse the repository at this point in the history
Интеграционное тестирование с новыми ключами
  • Loading branch information
sanmai committed Mar 20, 2019
2 parents fb71f54 + dde974f commit 0fcb1fe
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 47 deletions.
10 changes: 8 additions & 2 deletions .travis.yml
Expand Up @@ -19,14 +19,20 @@ matrix:
stages:
- analyze
- test
- integration

jobs:
exclude:
- php: 7.2
include:
- if: branch = master
- stage: integration
php: 7.0
env: GROUP=integration
env: GROUP=integration TYPE=shop
secure: "gtOzOUYqUk1ucFKg0DtVdqzxov1nR/MiMS8vwsTc/ARSW0O4g38zYvAn61ZW1W81L41R2uqLChbaHls6SI/G3zEhPBgrfPTTr/bRCKZ+lfDfmtwRWUK0WB81/OUx7SGwIVULAaaZ3d8ti0RzsHz5NclaqlOM25XQjVzWfhPezTTfYX/DjCx5eNGMqDka74CsVj+pFk42DAW3wTH1GTTUWYTCk+U4qPEo+T29KAMmDS781YB283s9AmekUNIIo7Xf1j2GzyVdx1X7MlbBeWN+5Q+9g6wH458PmsM3LY+IzcNNcTiAS32H2WdKSMjokqjrZbSfBpXzQaX5SQRO+8RO3MgsKboGGODinxJX8PC3FUOZKOWUBtGLnqjoBjdsBJlvP2/CHqzHXWhPOQAmc0H3y/BpUnVd3mEowrQrEHG6SJtu7AVDri9j3elX5qEQjCt0HkvLAWfT5VqS1VF5VVIOSzgT6AwRAaa7+VQwZpFDP2DXnNLPmP3Ic9cyT+2IgwARNqSfEcroYRETKbNIyVasYTPR1RqazukA8iCw+QM04kJydL0A52TCGEV6x09DqQZLLsevD9oaR/LcHjKSnVXXAmtp3SMded4/CyMNHgMA2JAsTg2IHT0ZdO4A76mJYAtCbI3RdDc6Bbh8QsOwY0FCMCxc7Z6TomHHvJF4uXh9jPA="
- stage: integration
php: 7.0
env: GROUP=integration TYPE=delivery
secure: "Ph/Uj8bLsl0LrDmC77leACtwveVHacK959zQSCRJIDovUauX0t24eijAfF5qd0ki+g1qQjcgUa2vkak/A35bbMgnSLOdLUx+aZmC8rt3wi7pJoQa6Uc/beoUzrNvLF1Z7AHcJWhauPyM9cm/OGRl67Td2zNb10/CURjqWhsM2HDclkY2aIVMcWlj54euim6SEBCyDM5RIyiAsrATi++t2HvXzmPhfxanZ/girowL3ThlRc9fJGy2n9I1ItGzgkFUPFAdYu/UHcriQEaYTZYaqIsZL6WlVbgd989NPGt72eKObJLJX/CWVvm9pkc8nNC6EkyGjPaCUMuKX+XEnvRhJhYyDKgQY8c7EPANf7JE7TV5meFChvGiW21EKPw3bcrYCUJMGFRnUlU5jaN7nOzACgIKBrVvGobKHf+fV/H7p7nqkOT12+AI2mCSovcIbNY28TE1wtDWBAc3IazQzxcqGP+T0fbBiXGz/4KnyJzanLntVDrvH4aFK5nIxzXimd30HtKLmJRTHXdwSqdDBorRcWVfr+wdASXDUl+pTvYGpsiKyeY2TewLRcQ4gTACmSK8oSlZsCv2EpCDTIYyKewVm2VrYgNCIa85IzNhAM1LtgyY8UfFeswOCj720m/Zfy6qA20L+NQIMoE39k483GlWPRBni9FtyudKezhtxYxVbII="
- stage: analyze
php: 7.2
install:
Expand Down
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Expand Up @@ -12,17 +12,19 @@ make -j

# Интеграционные тесты

Для запуска интеграционных тестов нужно задать тестовые ключи, с которыми производится доступ:
Для запуска интеграционных тестов нужно задать тестовые ключи ([есть в документации](https://www.cdek.ru/clients/integrator.html)), с которыми производится доступ:

```bash
export CDEK_ACCOUNT=.....
export CDEK_PASSWORD=.....
```

Также можно поменять путь до API, например, на вариант без https:
Тесты должны проходить как с ключами для ИМ, так и с ключами для доставки.

Также можно задать путь до API, например, на вариант с https:

```bash
export CDEK_BASE_URL=http://integration.cdek.ru
export CDEK_BASE_URL=https://integration.edu.cdek.ru
```

Затем можно запускать тесты в режиме отладки:
Expand Down
7 changes: 6 additions & 1 deletion phpunit.xml.dist
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" colors="true">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="Test Suite">
<directory>tests</directory>
Expand All @@ -15,4 +17,7 @@
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<php>
<env name="CDEK_BASE_URL" value="http://integration.edu.cdek.ru" />
</php>
</phpunit>
6 changes: 6 additions & 0 deletions tests/Integration/CalculationRequestTest.php
Expand Up @@ -38,6 +38,8 @@
*/
class CalculationRequestTest extends TestCase
{
const UNAUTHORIZED_ERROR = 2;

public function test_success()
{
$request = new CalculationRequest();
Expand Down Expand Up @@ -81,6 +83,10 @@ public function test_authorized_success()
$response = $this->getClient()->sendCalculationRequest($request);

foreach ($response->getErrors() as $error) {
if ((int) $error->getErrorCode() === self::UNAUTHORIZED_ERROR) {
$this->skipIfTestEndpointIsUsed();
}

$this->fail("{$error->getErrorCode()}: {$error->getMessage()}");
}

Expand Down
82 changes: 56 additions & 26 deletions tests/Integration/DeliveryRequestTest.php
Expand Up @@ -104,7 +104,7 @@ public function test_delete_success()
/**
* @depends test_delete_success
*/
public function test_failing_request_with_demo_keys()
public function test_successful_request_for_shop(): string
{
$order = new Order([
'Number' => 'TEST-123456',
Expand Down Expand Up @@ -174,15 +174,24 @@ public function test_failing_request_with_demo_keys()
foreach ($response->getMessages() as $message) {
$this->assertNotEmpty($message->getErrorCode(), $message->getMessage());
$this->assertSame('ERR_INVALID_TARIFF_WITH_CLIENT', $message->getErrorCode());
break;

// "Для выбранного тарифа клиент-плательщик должен быть задан и иметь ИМ-договор"
// Это означает что с нашими реквизитами нельзя создать заказ для ИМ
return '';
}

$this->fail();

return '';
}

/**
* @depends test_delete_success
* @depends test_successful_request_for_shop
*/
public function test_successful_request()
public function test_successful_request_for_delivery(string $dispatchNumber): string
{
// Попробуем создать заказ на доставку

$order = new Order([
'ClientSide' => Order::CLIENT_SIDE_SENDER,
'Number' => 'TEST-123456',
Expand Down Expand Up @@ -262,16 +271,37 @@ public function test_successful_request()
}

/**
* @depends test_failing_request_with_demo_keys
* @depends test_successful_request_for_shop
* @depends test_successful_request_for_delivery
*/
public function test_successful_request_any(string $dispatchNumberShop, string $dispatchNumberDelivery)
{
$dispatchNumber = $dispatchNumberShop !== '' ? $dispatchNumberShop : $dispatchNumberDelivery;

$this->assertNotEmpty($dispatchNumber);

return $dispatchNumber;
}

/**
* @depends test_successful_request_any
*/
public function test_update_request(string $dispatchNumber)
{
if ($dispatchNumber === '') {
$this->markTestSkipped('Используются реквизиты для доставки');
}

$request = UpdateRequest::create([
'Number' => self::TEST_NUMBER,
])->addOrder(Order::create([
'DispatchNumber' => $dispatchNumber,
'Number' => 'TEST-123456',
])->addPackage(Package::create([
])->setAddress(Address::create([
'Street' => 'Морозильная улица',
'House' => '2',
'Flat' => '101',
]))->addPackage(Package::create([
'Number' => 'TEST-123456',
'BarCode' => 'TEST-123456',
'Weight' => 600, // Общий вес (в граммах)
Expand All @@ -291,18 +321,9 @@ public function test_update_request(string $dispatchNumber)

$this->assertInstanceOf(UpdateResponse::class, $response);

$this->skipIfKnownAPIErrorCode($response);

foreach ($response->getMessages() as $message) {
if ($message->getErrorCode() === 'ERR_INVALID_TARIFF_WITH_CLIENT') {
$this->markTestSkipped($message->getMessage());
}

// Случай когда БД СДЭК отстаёт
if ($message->getErrorCode() === 'ERR_ORDER_NOTFIND') {
$this->markTestSkipped($message->getMessage());
}
}
$this->skipIfKnownAPIErrorCode($response, [
'ERR_ORDER_NOTFIND', // Случай когда БД СДЭК отстаёт
]);

foreach ($response->getMessages() as $message) {
$this->assertEmpty($message->getErrorCode(), $message->getMessage());
Expand All @@ -317,7 +338,7 @@ public function test_update_request(string $dispatchNumber)
}

/**
* @depends test_successful_request
* @depends test_successful_request_any
*/
public function test_print_receipts_request(string $dispatchNumber)
{
Expand All @@ -326,12 +347,12 @@ public function test_print_receipts_request(string $dispatchNumber)

$response = $this->getClient()->sendPrintReceiptsRequest($request);

$this->skipIfKnownAPIErrorCode($response, [
'ERR_API',
]);

if ($response->hasErrors()) {
foreach ($response->getMessages() as $message) {
if ($message->getErrorCode() === 'ERR_API') {
$this->markTestSkipped($message->getMessage());
}

// Новые заказы попадают в БД СДЭК с задержкой, потому квитанцию не всегда получается сразу получить
if ($message->getErrorCode() === 'ERR_INVALID_DISPATCHNUMBER') {
$this->assertContains($dispatchNumber, $message->getMessage());
Expand All @@ -351,7 +372,7 @@ public function test_print_receipts_request(string $dispatchNumber)
}

/**
* @depends test_successful_request
* @depends test_successful_request_any
* @psalm-suppress PossiblyNullReference
*/
public function test_status_report(string $dispatchNumber)
Expand All @@ -378,9 +399,18 @@ public function test_status_report(string $dispatchNumber)
$order = $response->getOrders()[0];

$this->assertInstanceOf(Order::class, $order);
$this->assertSame('TESTING123', $order->getActNumber());
$this->assertSame($dispatchNumber, $order->getDispatchNumber());
$this->assertSame('Создан', $order->getStatus()->getDescription());

if ($order->getActNumber() !== '' && !$this->isTestEndpointUsed()) {
$this->assertSame('TESTING123', $order->getActNumber());
}

if ($order->getNumber() === 'null' && $this->isTestEndpointUsed()) {
// Тестовое API иногда возвращает такое - тестирование продолжаем как можно
return Order::withDispatchNumber($order->getDispatchNumber());
}

return Order::withNumberAndDate($order->getNumber(), $order->getStatus()->getDate());
}

Expand Down Expand Up @@ -436,7 +466,7 @@ public function test_info_report(Order $order)
}

/**
* @depends test_successful_request
* @depends test_successful_request_any
*/
public function test_call_courier(string $dispatchNumber)
{
Expand Down
7 changes: 6 additions & 1 deletion tests/Integration/RegionsRequestTest.php
Expand Up @@ -42,7 +42,7 @@ class RegionsRequestTest extends TestCase
public function test_example()
{
$request = new RegionsRequest();
$request->setCountryCode(1);
$request->setCountryCode('RU');
$request->setPage(0)->setSize(1);

$response = $this->getClient()->sendRegionsRequest($request);
Expand All @@ -53,6 +53,11 @@ public function test_example()
$this->assertCount(1, $response->getItems());

$region = $response->getItems()[0];

if ($region->getCountryCode() === 0) {
$this->markTestSkipped("Unknown country: {$region->getCountryName()}");
}

$this->assertSame('18aff43f-58b8-4608-ade7-92fdab7fc39f', $region->getUuid());
$this->assertSame('Тверская', $region->getName());
$this->assertSame('обл', $region->getPrefix());
Expand Down
57 changes: 43 additions & 14 deletions tests/Integration/TestCase.php
Expand Up @@ -34,9 +34,14 @@

abstract class TestCase extends \PHPUnit\Framework\TestCase
{
const TEST_HOST = 'integration.edu.cdek.ru';

/** @var \CdekSDK\CdekClient */
private $client;

/** @var bool */
private $isTesting = false;

/**
* @psalm-suppress PossiblyFalseArgument
* @psalm-suppress MixedArgument
Expand All @@ -51,10 +56,18 @@ protected function setUp()
$this->markTestSkipped('Integration testing disabled (CDEK_PASSWORD missing).');
}

$http = false === getenv('CDEK_BASE_URL') ? null : new GuzzleClient([
'base_uri' => getenv('CDEK_BASE_URL'),
'verify' => !getenv('CI'), // Igonore SSL errors on the likes of Travis CI
]);
if (false === getenv('CDEK_BASE_URL')) {
$http = null;
} else {
if (strpos(getenv('CDEK_BASE_URL'), self::TEST_HOST)) {
$this->isTesting = true;
}

$http = new GuzzleClient([
'base_uri' => getenv('CDEK_BASE_URL'),
'verify' => !getenv('CI'), // Igonore SSL errors on the likes of Travis CI
]);
}

$this->client = new CdekClient(getenv('CDEK_ACCOUNT'), getenv('CDEK_PASSWORD'), $http);

Expand All @@ -63,22 +76,38 @@ protected function setUp()
}
}

protected function getClient(): CdekClient
final protected function getClient(): CdekClient
{
return $this->client;
}

protected function skipIfKnownAPIErrorCode(Response $response)
final protected function skipIfKnownAPIErrorCode(Response $response, array $transientErrorCodes = [])
{
if ($response->hasErrors()) {
foreach ($response->getMessages() as $message) {
if ($message->getErrorCode() === '502') {
$this->markTestSkipped("CDEK responded with an HTTP error code: {$message->getMessage()}");
}
if ($message->getErrorCode() === 'ERROR_INTERNAL') {
$this->markTestSkipped("CDEK failed with an internal error: {$message->getMessage()}");
}
if (!$response->hasErrors()) {
return;
}

$transientErrorCodes[] = 'ERROR_INTERNAL';

foreach ($response->getMessages() as $message) {
if ($message->getErrorCode() === '502') {
$this->markTestSkipped("CDEK responded with an HTTP error code: {$message->getMessage()}");
}
if (in_array($message->getErrorCode(), $transientErrorCodes)) {
$this->markTestSkipped("CDEK failed with a known transient error code {$message->getErrorCode()}: {$message->getMessage()}");
}
}
}

final protected function isTestEndpointUsed(): bool
{
return $this->isTesting;
}

final protected function skipIfTestEndpointIsUsed(string $message = '')
{
if ($this->isTestEndpointUsed()) {
$this->markTestSkipped($message);
}
}
}

0 comments on commit 0fcb1fe

Please sign in to comment.