Туча доработок

- класс `PayingAgent`, покрытый тестами
- новые константы для тегов ФФД 1.05 `Ffd105Tags`
- `Entity::jsonSerialize()` object -> array (again)
- `TooManyException::$max` int -> float
- тесты по psr-4, потому что почему бы и нет
- некоторые провайдеры вынесены в `BasicTestCase`
- улучшен тест покупателя
This commit is contained in:
2021-11-24 01:30:54 +08:00
parent b5a01debd2
commit 42d194116f
40 changed files with 622 additions and 192 deletions

View File

@@ -0,0 +1,225 @@
<?php
/*
* Copyright (c) 2020-2021 Антон Аксенов (Anthony Axenov)
*
* This code is licensed under MIT.
* Этот код распространяется по лицензии MIT.
* https://github.com/anthonyaxenov/atol-online/blob/master/LICENSE
*/
declare(strict_types = 1);
namespace AtolOnline\Tests;
use AtolOnline\Entities\Entity;
use AtolOnline\Helpers;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use PHPUnit\Framework\TestCase;
/**
* Базовый класс для тестов
*/
class BasicTestCase extends TestCase
{
/**
* Проверяет наличие подключения к ресурсу по URL
*
* @param string $url
* @param int $code
* @return bool
*/
protected function ping(string $url, int $code): bool
{
try {
$result = (new Client([
'http_errors' => false,
'timeout' => 3,
]))->request('GET', $url);
} catch (GuzzleException) {
return false;
}
return $result->getStatusCode() === $code;
}
/**
* Проверяет доступность API мониторинга
*
* @return bool
*/
protected function isMonitoringOnline(): bool
{
return $this->ping('https://testonline.atol.ru/api/auth/v1/gettoken', 400);
}
/**
* Пропускает текущий тест если API мониторинга недоступен
*/
protected function skipIfMonitoringIsOffline(): void
{
if (!$this->isMonitoringOnline()) {
$this->markTestSkipped($this->getName() . ': Monitoring API is inaccessible. Skipping test.');
}
}
/**
* Тестирует является ли объект приводимым к json-строке согласно схеме АТОЛ Онлайн
*
* @param Entity $entity
* @param array $json_structure
* @covers \AtolOnline\Entities\Entity::jsonSerialize
* @covers \AtolOnline\Entities\Entity::__toString
*/
public function assertAtolable(Entity $entity, array $json_structure = []): void
{
$this->assertIsArray($entity->jsonSerialize());
$this->assertIsString((string)$entity);
$this->assertJson((string)$entity);
if ($json_structure) {
$this->assertEquals(json_encode($json_structure), (string)$entity);
}
}
/**
* Тестирует идентичность двух классов
*
* @param object|string $expected
* @param object|string $actual
*/
public function assertIsSameClass(object|string $expected, object|string $actual): void
{
$this->assertTrue(Helpers::isSameClass($expected, $actual));
}
/**
* Тестирует наследование класса (объекта) от указанных классов
*
* @param object|string $class
* @param string[] $parents
*/
public function assertExtendsClasses(object|string $class, array $parents): void
{
$this->assertTrue(Helpers::checkExtendsClasses($class, $parents));
}
/**
* Тестирует имплементацию классом (объектом) указанных интерфейсов
*
* @param object|string $class
* @param string[] $interfaces
*/
public function assertImplementsInterfaces(object|string $class, array $interfaces): void
{
$this->assertTrue(Helpers::checkImplementsInterfaces($class, $interfaces));
}
/**
* Тестирует использование классом (объектом) указанных трейтов
*
* @param object|string $class
* @param string[] $traits
*/
public function assertUsesTraits(object|string $class, array $traits): void
{
$this->assertTrue(Helpers::checkUsesTraits($traits, $class));
}
/**
* Тестирует, является ли объект коллекцией
*
* @param mixed $expected
*/
public function assertIsCollection(mixed $expected): void
{
$this->assertIsObject($expected);
$this->assertIsIterable($expected);
$this->assertIsSameClass($expected, Collection::class);
}
//------------------------------------------------------------------------------------------------------------------
/**
* Провайдер строк, которые приводятся к null
*
* @return array<array<string|null>>
*/
public function providerNullableStrings(): array
{
return [
[''],
[' '],
[null],
["\n\r\t"],
];
}
/**
* Провайдер валидных телефонов
*
* @return array<array<string, string>>
*/
public function providerValidPhones(): array
{
return [
['+79991234567', '+79991234567'],
['79991234567', '+79991234567'],
['89991234567', '+89991234567'],
['+7 999 123 45 67', '+79991234567'],
['+7 (999) 123-45-67', '+79991234567'],
["+7 %(?9:9\"9')abc\r123\n45\t67\0", '+79991234567'],
];
}
/**
* Провайдер телефонов, которые приводятся к null
*
* @return array<array<string>>
*/
public function providerNullablePhones(): array
{
return array_merge(
$this->providerNullableStrings(),
[
[Helpers::randomStr(10, false)],
["asdfgvs \n\rtt\t*/(*&%^*$%"],
]
);
}
/**
* Провайдер валидных email-ов
*
* @return array<array<string>>
*/
public function providerValidEmails(): array
{
return [
['abc@mail.com'],
['abc-d@mail.com'],
['abc.def@mail.com'],
['abc.def@mail.org'],
['abc.def@mail-archive.com'],
];
}
/**
* Провайдер невалидных email-ов
*
* @return array<array<string>>
*/
public function providerInvalidEmails(): array
{
return [
['@example'],
[Helpers::randomStr(15)],
['@example.com'],
['abc.def@mail'],
['.abc@mail.com'],
['example@example'],
['abc..def@mail.com'],
['abc.def@mail..com'],
['abc.def@mail#archive.com'],
];
}
}