Compare commits

..

2 Commits

Author SHA1 Message Date
b35b9bfa87 Удалена поддержка base_name в документе коррекции (#5) 2021-11-20 23:46:39 +08:00
e1120051c1 Новая сущность Kkt для ответов мониторинга (#8) + мелкий рефакторинг
- enum-константы перенесены в своё пространство Enums
- новые исключения EmptyMonitorDataException + NotEnoughMonitorDataException
- KktMonitor::getAll() теперь возвращает коллекцию объектов Kkt
- KktMonitor::getOne() теперь возвращает объект Kkt
- местами актуализированы return types + phpdoc

Покрытие тестами:
- 61% исключений
- 98% AtolClient (пока хз как покрыть 208-ую строку)
- 100% KktMonitor
- 100% Kkt
- 100% Client
- 100% Company
- 100% Entity
2021-11-20 23:39:08 +08:00
25 changed files with 471 additions and 130 deletions

View File

@ -11,9 +11,11 @@ declare(strict_types = 1);
namespace AtolOnline\Api; namespace AtolOnline\Api;
use AtolOnline\Entities\Kkt;
use AtolOnline\Exceptions\EmptyMonitorDataException;
use AtolOnline\Exceptions\NotEnoughMonitorDataException;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use stdClass;
/** /**
* Класс для мониторинга ККТ * Класс для мониторинга ККТ
@ -85,7 +87,8 @@ class KktMonitor extends AtolClient
*/ */
public function getAll(?int $limit = null, ?int $offset = null): Collection public function getAll(?int $limit = null, ?int $offset = null): Collection
{ {
return collect($this->fetchAll($limit, $offset)->getContent()); $collection = collect($this->fetchAll($limit, $offset)->getContent());
return $collection->map(fn($data) => new Kkt($data));
} }
/** /**
@ -114,12 +117,14 @@ class KktMonitor extends AtolClient
* *
* @todo кастовать к отдельному классу со своими геттерами * @todo кастовать к отдельному классу со своими геттерами
* @param string $serial_number * @param string $serial_number
* @return stdClass * @return Kkt
* @throws GuzzleException * @throws GuzzleException
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
* @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 11 * @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 11
*/ */
public function getOne(string $serial_number): stdClass public function getOne(string $serial_number): Kkt
{ {
return $this->fetchOne($serial_number)->getContent()->data; return new Kkt($this->fetchOne($serial_number)->getContent()->data);
} }
} }

View File

@ -13,7 +13,7 @@ namespace AtolOnline\Entities;
use AtolOnline\{ use AtolOnline\{
Constants\Constraints, Constants\Constraints,
Constants\SnoTypes, Enums\SnoTypes,
Exceptions\InvalidEmailException, Exceptions\InvalidEmailException,
Exceptions\InvalidInnLengthException, Exceptions\InvalidInnLengthException,
Exceptions\InvalidPaymentAddressException, Exceptions\InvalidPaymentAddressException,

View File

@ -31,33 +31,21 @@ class CorrectionInfo extends Entity
*/ */
protected string $base_number; protected string $base_number;
/**
* @var string Описание коррекции. Тег ФФД - 1177.
*/
protected string $base_name;
/** /**
* CorrectionInfo constructor. * CorrectionInfo constructor.
* *
* @param string|null $type Тип коррекции * @param string|null $type Тип коррекции
* @param string|null $base_date Дата документа * @param string|null $base_date Дата документа
* @param string|null $base_number Номер документа * @param string|null $base_number Номер документа
* @param string|null $base_name Описание коррекции
*/ */
public function __construct(?string $type = null, ?string $base_date = null, ?string $base_number = null, ?string $base_name = null) public function __construct(
{ ?string $type = null,
if ($type) { ?string $base_date = null,
$this->setType($type); ?string $base_number = null
} ) {
if ($base_date) { $type && $this->setType($type);
$this->setDate($base_date); $base_date && $this->setDate($base_date);
} $base_number && $this->setNumber($base_number);
if ($base_number) {
$this->setNumber($base_number);
}
if ($base_name) {
$this->setName($base_name);
}
} }
/** /**
@ -84,30 +72,6 @@ class CorrectionInfo extends Entity
return $this; return $this;
} }
/**
* Возвращает описание коррекции.
* Тег ФФД - 1177.
*
* @return string|null
*/
public function getName(): ?string
{
return $this->base_name;
}
/**
* Устанавливает описание коррекции.
* Тег ФФД - 1177.
*
* @param string $name
* @return $this
*/
public function setName(string $name): CorrectionInfo
{
$this->base_name = trim($name);
return $this;
}
/** /**
* Возвращает дату документа основания для коррекции. * Возвращает дату документа основания для коррекции.
* Тег ФФД - 1178. * Тег ФФД - 1178.
@ -159,13 +123,12 @@ class CorrectionInfo extends Entity
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function jsonSerialize() public function jsonSerialize(): object
{ {
return [ return (object)[
'type' => $this->getType() ?? '', // обязателен 'type' => $this->getType() ?? '', // обязателен
'base_date' => $this->getDate() ?? '', // обязателен 'base_date' => $this->getDate() ?? '', // обязателен
'base_number' => $this->getNumber() ?? '', // обязателен 'base_number' => $this->getNumber() ?? '', // обязателен
'base_name' => $this->getName() ?? '' // не обязателен
]; ];
} }
} }

149
src/Entities/Kkt.php Normal file
View File

@ -0,0 +1,149 @@
<?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\Entities;
use AtolOnline\Exceptions\EmptyMonitorDataException;
use AtolOnline\Exceptions\NotEnoughMonitorDataException;
use DateTime;
use Exception;
/**
* Класс сущности ККТ, получаемой от монитора
*
* @property string|null serialNumber Заводской номер ККТ
* @property string|null registrationNumber Регистрационный номер машины (РНМ)
* @property string|null deviceNumber Номер автоматического устройства (внутренний идентификатор устройства)
* @property DateTime|string|null fiscalizationDate Дата активации (фискализации) ФН с указанием таймзоны
* @property DateTime|string|null fiscalStorageExpiration Дата замены ФН (Срок действия ФН), с указанием таймзоны
* @property int|null signedDocuments Количество подписанных документов в ФН
* @property float|null fiscalStoragePercentageUse Наполненость ФН в %
* @property string|null fiscalStorageINN ИНН компании (указанный в ФН)
* @property string|null fiscalStorageSerialNumber Заводской (серийный) номер ФН
* @property string|null fiscalStoragePaymentAddress Адрес расчёта, указанный в ФН
* @property string|null groupCode Код группы кассы
* @property DateTime|string|null timestamp Время и дата формирования данных, UTC
* @property bool|null isShiftOpened Признак открыта смена (true) или закрыта (false)
* @property int|null shiftNumber Номер смены (или "Номер закрытой смены", когда смена закрыта)
* @property int|null shiftReceipt Номер документа за смену (или "Кол-во чеков закрытой смены", когда смена закрыта)
* @property int|null unsentDocs Количество неотправленных документов. Указывается, если значение отлично от 0.
* @property DateTime|string|null firstUnsetDocTimestamp Дата первого неотправленного документа. Указывается, если
* есть неотправленные документы.
* @property int|null networkErrorCode Код ошибки сети
* @see https://online.atol.ru/files/API_service_information.pdf Документация, стр 11
*/
final class Kkt extends Entity
{
/**
* Сопоставление кодов сетевых ошибок ККТ с их описаниями
*/
public const ERROR_CODES = [
0 => 'Нет ошибок',
1 => 'Отсутствует физический канал связи',
2 => 'Ошибка сетевых настроек или нет соединения с сервером ОФД',
3 => 'Разрыв соединения при передаче документа на сервер',
4 => 'Некорректный заголовок сессионного пакета',
5 => 'Превышен таймаут ожидания квитанции',
6 => 'Разрыв соединения при приеме квитанции',
7 => 'Превышен таймаут передачи документа на сервер',
8 => 'ОФД-процесс не иницилизирован',
];
/**
* @var string[] Список обязательных атрибутов
*/
private array $properties = [
'serialNumber',
'registrationNumber',
'deviceNumber',
'fiscalizationDate',
'fiscalStorageExpiration',
'signedDocuments',
'fiscalStoragePercentageUse',
'fiscalStorageINN',
'fiscalStorageSerialNumber',
'fiscalStoragePaymentAddress',
'groupCode',
'timestamp',
'isShiftOpened',
'shiftNumber',
'shiftReceipt',
//'unsentDocs',
//'firstUnsetDocTimestamp',
'networkErrorCode',
];
/**
* @var string[] Массив атрибутов, которые кастуются к DateTime
*/
private array $timestamps = [
'fiscalizationDate',
'fiscalStorageExpiration',
'firstUnsetDocTimestamp',
'timestamp',
];
/**
* Конструктор
*
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/
public function __construct(protected \stdClass $data)
{
if (empty((array)$data)) {
throw new EmptyMonitorDataException();
}
$diff = array_diff($this->properties, array_keys((array)$data));
if (count($diff) !== 0) {
throw new NotEnoughMonitorDataException($diff);
}
}
/**
* Эмулирует обращение к атрибутам
*
* @param string $name
* @return null
* @throws Exception
*/
public function __get(string $name)
{
if (empty($this->data?->$name)) {
return null;
}
if (in_array($name, $this->timestamps)) {
return new DateTime($this->data->$name);
}
return $this->data->$name;
}
/**
* Возвращает объект с информацией о сетевой ошибке
*
* @return object
*/
public function getNetworkError(): object
{
return (object)[
'code' => $this->data->networkErrorCode,
'text' => self::ERROR_CODES[$this->data->networkErrorCode],
];
}
/**
* @inheritDoc
*/
public function jsonSerialize()
{
return $this->data;
}
}

View File

@ -11,7 +11,7 @@ declare(strict_types = 1);
namespace AtolOnline\Entities; namespace AtolOnline\Entities;
use AtolOnline\Constants\PaymentTypes; use AtolOnline\Enums\PaymentTypes;
/** /**
* Класс, описывающий оплату. Тег ФФД - 1031, 1081, 1215, 1216, 1217. * Класс, описывающий оплату. Тег ФФД - 1031, 1081, 1215, 1216, 1217.

View File

@ -11,7 +11,7 @@ declare(strict_types = 1);
namespace AtolOnline\Entities; namespace AtolOnline\Entities;
use AtolOnline\Constants\VatTypes; use AtolOnline\Enums\VatTypes;
/** /**
* Класс, описывающий ставку НДС * Класс, описывающий ставку НДС

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -9,7 +9,7 @@
declare(strict_types = 1); declare(strict_types = 1);
namespace AtolOnline\Constants; namespace AtolOnline\Enums;
use MyCLabs\Enum\Enum; use MyCLabs\Enum\Enum;

View File

@ -0,0 +1,23 @@
<?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\Exceptions;
/**
* Исключение, возникающее при попытке создать объект ККТ без данных от монитора
*/
class EmptyMonitorDataException extends AtolException
{
/**
* @var string Сообщение об ошибке
*/
protected $message = 'Cannot create KKT entity without data from monitor';
}

View File

@ -11,7 +11,7 @@ declare(strict_types = 1);
namespace AtolOnline\Exceptions; namespace AtolOnline\Exceptions;
use AtolOnline\Constants\DocumentTypes; use AtolOnline\Enums\DocumentTypes;
use Throwable; use Throwable;
/** /**

View File

@ -11,7 +11,7 @@ declare(strict_types = 1);
namespace AtolOnline\Exceptions; namespace AtolOnline\Exceptions;
use AtolOnline\Constants\SnoTypes; use AtolOnline\Enums\SnoTypes;
use Throwable; use Throwable;
/** /**

View File

@ -0,0 +1,38 @@
<?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\Exceptions;
use Throwable;
/**
* Исключение, возникающее при попытке создать объект ККТ с неполными данными от монитора
*/
class NotEnoughMonitorDataException extends AtolException
{
/**
* @var string Сообщение об ошибке
*/
protected $message = 'Cannot create KKT entity without these properties: ';
/**
* Конструктор
*
* @param array $props_diff
* @param string $message
* @param int $code
* @param Throwable|null $previous
*/
public function __construct(array $props_diff, $message = "", int $code = 0, Throwable $previous = null)
{
parent::__construct($message ?: $this->message . implode(', ', $props_diff), $code, $previous);
}
}

View File

@ -46,7 +46,6 @@ class BasicTestCase extends TestCase
* Проверяет доступность API мониторинга * Проверяет доступность API мониторинга
* *
* @return bool * @return bool
* @throws GuzzleException
*/ */
protected function isMonitoringOnline(): bool protected function isMonitoringOnline(): bool
{ {
@ -54,9 +53,7 @@ class BasicTestCase extends TestCase
} }
/** /**
* Пропускает текущий тест если API мониторинга недоступно * Пропускает текущий тест если API мониторинга недоступен
*
* @throws GuzzleException
*/ */
protected function skipIfMonitoringIsOffline(): void protected function skipIfMonitoringIsOffline(): void
{ {
@ -90,7 +87,7 @@ class BasicTestCase extends TestCase
* @param object|string $expected * @param object|string $expected
* @param object|string $actual * @param object|string $actual
*/ */
public function assertIsSameClass(object|string $expected, object|string $actual) public function assertIsSameClass(object|string $expected, object|string $actual): void
{ {
$this->assertEquals( $this->assertEquals(
is_object($expected) ? $expected::class : $expected, is_object($expected) ? $expected::class : $expected,
@ -104,7 +101,7 @@ class BasicTestCase extends TestCase
* @param string[] $parents * @param string[] $parents
* @param object|string $actual * @param object|string $actual
*/ */
public function assertExtendsClasses(array $parents, object|string $actual) public function assertExtendsClasses(array $parents, object|string $actual): void
{ {
$this->checkClassesIntersection($parents, $actual, 'class_parents'); $this->checkClassesIntersection($parents, $actual, 'class_parents');
} }
@ -115,7 +112,7 @@ class BasicTestCase extends TestCase
* @param string[] $parents * @param string[] $parents
* @param object|string $actual * @param object|string $actual
*/ */
public function assertImplementsInterfaces(array $parents, object|string $actual) public function assertImplementsInterfaces(array $parents, object|string $actual): void
{ {
$this->checkClassesIntersection($parents, $actual, 'class_implements'); $this->checkClassesIntersection($parents, $actual, 'class_implements');
} }
@ -126,7 +123,7 @@ class BasicTestCase extends TestCase
* @param string[] $parents * @param string[] $parents
* @param object|string $actual * @param object|string $actual
*/ */
public function assertUsesTraits(array $parents, object|string $actual) public function assertUsesTraits(array $parents, object|string $actual): void
{ {
$this->checkClassesIntersection($parents, $actual, 'class_uses'); $this->checkClassesIntersection($parents, $actual, 'class_uses');
} }

View File

@ -10,8 +10,8 @@
namespace AtolOnlineTests; namespace AtolOnlineTests;
use AtolOnline\{ use AtolOnline\{
Constants\SnoTypes,
Entities\Company, Entities\Company,
Enums\SnoTypes,
Exceptions\InvalidEmailException, Exceptions\InvalidEmailException,
Exceptions\InvalidInnLengthException, Exceptions\InvalidInnLengthException,
Exceptions\InvalidPaymentAddressException, Exceptions\InvalidPaymentAddressException,

View File

@ -10,10 +10,10 @@
namespace AtolOnlineTests; namespace AtolOnlineTests;
use AtolOnline\{ use AtolOnline\{
Constants\PaymentMethods,
Constants\PaymentObjects,
Constants\VatTypes,
Entities\Item, Entities\Item,
Enums\PaymentMethods,
Enums\PaymentObjects,
Enums\VatTypes,
Exceptions\BasicTooManyException, Exceptions\BasicTooManyException,
Exceptions\TooHighPriceException, Exceptions\TooHighPriceException,
Exceptions\TooLongNameException, Exceptions\TooLongNameException,

153
tests/KktEntityTest.php Normal file
View File

@ -0,0 +1,153 @@
<?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 AtolOnlineTests;
use AtolOnline\Entities\Kkt;
use AtolOnline\Exceptions\EmptyMonitorDataException;
use AtolOnline\Exceptions\NotEnoughMonitorDataException;
use DateTime;
use Exception;
class KktEntityTest extends BasicTestCase
{
/**
* @var array Данные для создания объекта ККТ
*/
private array $sample_data = [
'serialNumber' => '00107703864827',
'registrationNumber' => '0000000003027865',
'deviceNumber' => 'KKT024219',
'fiscalizationDate' => '2019-07-22T14:03:00+00:00',
'fiscalStorageExpiration' => '2020-11-02T21:00:00+00:00',
'signedDocuments' => 213350,
'fiscalStoragePercentageUse' => 85.34,
'fiscalStorageINN' => '3026455760',
'fiscalStorageSerialNumber' => '9999078902004339',
'fiscalStoragePaymentAddress' => 'test.qa.ru',
'groupCode' => 'test-qa-ru_14605',
'timestamp' => '2019-12-05T10:45:30+00:00',
'isShiftOpened' => true,
'shiftNumber' => 126,
'shiftReceipt' => 2278,
//'unsentDocs' => 123,
'firstUnsetDocTimestamp' => 'there must be timestamp, but we want to get exception here to get string',
'networkErrorCode' => 2,
];
/**
* Тестирует создание объекта ККТ с валидными данными
*
* @covers \AtolOnline\Entities\Kkt::__construct
* @covers \AtolOnline\Entities\Kkt::__get
* @covers \AtolOnline\Entities\Kkt::jsonSerialize
* @covers \AtolOnline\Entities\Kkt::__toString
* @throws Exception
*/
public function testConstructor(): void
{
$kkt = new Kkt((object)$this->sample_data);
$this->assertIsSameClass(Kkt::class, $kkt);
$this->assertAtolable($kkt);
}
/**
* Тестирует исключение при попытке создать объект ККТ без данных от монитора
*
* @covers \AtolOnline\Entities\Kkt::__construct
* @covers \AtolOnline\Exceptions\EmptyMonitorDataException
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/
public function testEmptyMonitorDataException(): void
{
$this->expectException(EmptyMonitorDataException::class);
new Kkt((object)[]);
}
/**
* Тестирует исключение при попытке создать объект ККТ без данных от монитора
*
* @covers \AtolOnline\Entities\Kkt::__construct
* @covers \AtolOnline\Exceptions\NotEnoughMonitorDataException
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/
public function testNotEnoughMonitorDataException(): void
{
$this->expectException(NotEnoughMonitorDataException::class);
new Kkt((object)[
'fiscalizationDate' => '2021-11-20T10:21:00+00:00',
]);
}
/**
* Тестирует получение атрибутов через магический геттер
*
* @covers \AtolOnline\Entities\Kkt::__get
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/
public function testMagicGetter(): void
{
$kkt = new Kkt((object)$this->sample_data);
// string
$this->assertNotNull($kkt->serialNumber);
$this->assertIsString($kkt->serialNumber);
$this->assertEquals($this->sample_data['serialNumber'], $kkt->serialNumber);
// int
$this->assertNotNull($kkt->signedDocuments);
$this->assertIsInt($kkt->signedDocuments);
// float
$this->assertNotNull($kkt->signedDocuments);
$this->assertIsFloat($kkt->fiscalStoragePercentageUse);
// null
$this->assertNull($kkt->unsentDocs);
// DateTime
$this->assertNotNull($kkt->fiscalizationDate);
$this->assertIsSameClass(DateTime::class, $kkt->fiscalizationDate);
}
/**
* Тестирует исключение при попытке получить некорректный DateTime через магический геттер
*
* @covers \AtolOnline\Entities\Kkt::__get
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/
public function testDateTimeException(): void
{
$this->expectException(Exception::class);
(new Kkt((object)$this->sample_data))->firstUnsetDocTimestamp;
}
/**
* Тестирует получение данных о сетевой ошибке
*
* @covers \AtolOnline\Entities\Kkt::getNetworkError
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/
public function testGetNetworkError(): void
{
$kkt = new Kkt((object)$this->sample_data);
$this->assertIsObject($kkt->getNetworkError());
$this->assertEquals((object)[
'code' => $kkt->networkErrorCode,
'text' => $kkt::ERROR_CODES[$kkt->networkErrorCode],
], $kkt->getNetworkError());
}
}

View File

@ -5,9 +5,12 @@ namespace AtolOnlineTests;
use AtolOnline\Api\AtolClient; use AtolOnline\Api\AtolClient;
use AtolOnline\Api\KktMonitor; use AtolOnline\Api\KktMonitor;
use AtolOnline\Api\KktResponse; use AtolOnline\Api\KktResponse;
use AtolOnline\Entities\Kkt;
use AtolOnline\Exceptions\AuthFailedException; use AtolOnline\Exceptions\AuthFailedException;
use AtolOnline\Exceptions\EmptyLoginException; use AtolOnline\Exceptions\EmptyLoginException;
use AtolOnline\Exceptions\EmptyMonitorDataException;
use AtolOnline\Exceptions\EmptyPasswordException; use AtolOnline\Exceptions\EmptyPasswordException;
use AtolOnline\Exceptions\NotEnoughMonitorDataException;
use AtolOnline\Exceptions\TooLongLoginException; use AtolOnline\Exceptions\TooLongLoginException;
use AtolOnline\Exceptions\TooLongPasswordException; use AtolOnline\Exceptions\TooLongPasswordException;
use AtolOnline\Helpers; use AtolOnline\Helpers;
@ -19,12 +22,29 @@ use GuzzleHttp\Exception\GuzzleException;
*/ */
class KktMonitorTest extends BasicTestCase class KktMonitorTest extends BasicTestCase
{ {
/**
* Возвращает объект клиента для тестирования с тестовым API АТОЛ
*
* @return AtolClient
* @throws EmptyLoginException
* @throws EmptyPasswordException
* @throws TooLongLoginException
* @throws TooLongPasswordException
*/
private function newTestClient(): KktMonitor
{
$credentials = TestEnvParams::FFD105();
return (new KktMonitor(true))
->setLogin($credentials['login'])
->setPassword($credentials['password']);
}
/** /**
* Тестирует успешное создание объекта монитора без аргументов конструктора * Тестирует успешное создание объекта монитора без аргументов конструктора
* *
* @covers \AtolOnline\Api\KktMonitor::__construct * @covers \AtolOnline\Api\KktMonitor::__construct
*/ */
public function testConstructorWithoutArgs() public function testConstructorWithoutArgs(): void
{ {
$client = new KktMonitor(); $client = new KktMonitor();
$this->assertIsObject($client); $this->assertIsObject($client);
@ -45,7 +65,7 @@ class KktMonitorTest extends BasicTestCase
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testConstructorWithArgs() public function testConstructorWithArgs(): void
{ {
$client = new KktMonitor(false, 'login', 'password', []); $client = new KktMonitor(false, 'login', 'password', []);
$this->assertIsObject($client); $this->assertIsObject($client);
@ -62,7 +82,7 @@ class KktMonitorTest extends BasicTestCase
* @throws EmptyLoginException * @throws EmptyLoginException
* @throws TooLongLoginException * @throws TooLongLoginException
*/ */
public function testLogin() public function testLogin(): void
{ {
$client = new KktMonitor(login: 'login'); $client = new KktMonitor(login: 'login');
$this->assertEquals('login', $client->getLogin()); $this->assertEquals('login', $client->getLogin());
@ -81,7 +101,7 @@ class KktMonitorTest extends BasicTestCase
* @covers \AtolOnline\Api\KktMonitor::setLogin * @covers \AtolOnline\Api\KktMonitor::setLogin
* @covers \AtolOnline\Exceptions\EmptyLoginException * @covers \AtolOnline\Exceptions\EmptyLoginException
*/ */
public function testEmptyLoginException() public function testEmptyLoginException(): void
{ {
$this->expectException(EmptyLoginException::class); $this->expectException(EmptyLoginException::class);
new KktMonitor(login: ''); new KktMonitor(login: '');
@ -98,7 +118,7 @@ class KktMonitorTest extends BasicTestCase
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testTooLongLoginException() public function testTooLongLoginException(): void
{ {
$this->expectException(TooLongLoginException::class); $this->expectException(TooLongLoginException::class);
new KktMonitor(login: Helpers::randomStr(101)); new KktMonitor(login: Helpers::randomStr(101));
@ -113,7 +133,7 @@ class KktMonitorTest extends BasicTestCase
* @throws EmptyPasswordException * @throws EmptyPasswordException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testPassword() public function testPassword(): void
{ {
$client = new KktMonitor(password: 'password'); $client = new KktMonitor(password: 'password');
$this->assertEquals('password', $client->getPassword()); $this->assertEquals('password', $client->getPassword());
@ -132,7 +152,7 @@ class KktMonitorTest extends BasicTestCase
* @covers \AtolOnline\Api\KktMonitor::setPassword * @covers \AtolOnline\Api\KktMonitor::setPassword
* @covers \AtolOnline\Exceptions\EmptyPasswordException * @covers \AtolOnline\Exceptions\EmptyPasswordException
*/ */
public function testEmptyPasswordException() public function testEmptyPasswordException(): void
{ {
$this->expectException(EmptyPasswordException::class); $this->expectException(EmptyPasswordException::class);
new KktMonitor(password: ''); new KktMonitor(password: '');
@ -148,7 +168,7 @@ class KktMonitorTest extends BasicTestCase
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testConstructorWithLongPassword() public function testConstructorWithLongPassword(): void
{ {
$this->expectException(TooLongPasswordException::class); $this->expectException(TooLongPasswordException::class);
new KktMonitor(password: Helpers::randomStr(101)); new KktMonitor(password: Helpers::randomStr(101));
@ -161,7 +181,7 @@ class KktMonitorTest extends BasicTestCase
* @covers \AtolOnline\Api\KktMonitor::isTestMode * @covers \AtolOnline\Api\KktMonitor::isTestMode
* @covers \AtolOnline\Api\KktMonitor::setTestMode * @covers \AtolOnline\Api\KktMonitor::setTestMode
*/ */
public function testTestMode() public function testTestMode(): void
{ {
$client = new KktMonitor(); $client = new KktMonitor();
$this->assertTrue($client->isTestMode()); $this->assertTrue($client->isTestMode());
@ -182,23 +202,6 @@ class KktMonitorTest extends BasicTestCase
$this->assertFalse($client->isTestMode()); $this->assertFalse($client->isTestMode());
} }
/**
* Возвращает объект клиента для тестирования с тестовым API АТОЛ
*
* @return AtolClient
* @throws EmptyLoginException
* @throws EmptyPasswordException
* @throws TooLongLoginException
* @throws TooLongPasswordException
*/
private function newTestClient(): KktMonitor
{
$credentials = TestEnvParams::FFD105();
return (new KktMonitor(true))
->setLogin($credentials['login'])
->setPassword($credentials['password']);
}
/** /**
* Тестирует авторизацию * Тестирует авторизацию
* *
@ -207,6 +210,7 @@ class KktMonitorTest extends BasicTestCase
* @covers \AtolOnline\Api\KktMonitor::getAuthEndpoint * @covers \AtolOnline\Api\KktMonitor::getAuthEndpoint
* @covers \AtolOnline\Api\KktMonitor::doAuth * @covers \AtolOnline\Api\KktMonitor::doAuth
* @covers \AtolOnline\Api\KktMonitor::auth * @covers \AtolOnline\Api\KktMonitor::auth
* @covers \AtolOnline\Exceptions\AuthFailedException
* @throws EmptyLoginException * @throws EmptyLoginException
* @throws EmptyPasswordException * @throws EmptyPasswordException
* @throws TooLongLoginException * @throws TooLongLoginException
@ -214,7 +218,7 @@ class KktMonitorTest extends BasicTestCase
* @throws AuthFailedException * @throws AuthFailedException
* @throws GuzzleException * @throws GuzzleException
*/ */
public function testAuth() public function testAuth(): void
{ {
$this->skipIfMonitoringIsOffline(); $this->skipIfMonitoringIsOffline();
$result = $this->newTestClient()->auth(); $result = $this->newTestClient()->auth();
@ -227,6 +231,7 @@ class KktMonitorTest extends BasicTestCase
* @depends testAuth * @depends testAuth
* @covers \AtolOnline\Api\KktMonitor::setToken * @covers \AtolOnline\Api\KktMonitor::setToken
* @covers \AtolOnline\Api\KktMonitor::getToken * @covers \AtolOnline\Api\KktMonitor::getToken
* @covers \AtolOnline\Exceptions\AuthFailedException
* @throws AuthFailedException * @throws AuthFailedException
* @throws EmptyLoginException * @throws EmptyLoginException
* @throws EmptyPasswordException * @throws EmptyPasswordException
@ -234,7 +239,7 @@ class KktMonitorTest extends BasicTestCase
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testGetToken() public function testGetToken(): void
{ {
$client = new KktMonitor(); $client = new KktMonitor();
$this->assertNull($client->getToken()); $this->assertNull($client->getToken());
@ -250,6 +255,7 @@ class KktMonitorTest extends BasicTestCase
* *
* @depends testAuth * @depends testAuth
* @covers \AtolOnline\Api\KktMonitor::getResponse * @covers \AtolOnline\Api\KktMonitor::getResponse
* @covers \AtolOnline\Exceptions\AuthFailedException
* @throws AuthFailedException * @throws AuthFailedException
* @throws EmptyLoginException * @throws EmptyLoginException
* @throws EmptyPasswordException * @throws EmptyPasswordException
@ -257,7 +263,7 @@ class KktMonitorTest extends BasicTestCase
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testGetResponse() public function testGetResponse(): void
{ {
$this->skipIfMonitoringIsOffline(); $this->skipIfMonitoringIsOffline();
$client = $this->newTestClient(); $client = $this->newTestClient();
@ -273,6 +279,7 @@ class KktMonitorTest extends BasicTestCase
* @covers \AtolOnline\Api\AtolClient::getUrlToMethod * @covers \AtolOnline\Api\AtolClient::getUrlToMethod
* @covers \AtolOnline\Api\KktMonitor::fetchAll * @covers \AtolOnline\Api\KktMonitor::fetchAll
* @covers \AtolOnline\Api\KktMonitor::getAll * @covers \AtolOnline\Api\KktMonitor::getAll
* @covers \AtolOnline\Exceptions\AuthFailedException
* @throws AuthFailedException * @throws AuthFailedException
* @throws EmptyLoginException * @throws EmptyLoginException
* @throws EmptyPasswordException * @throws EmptyPasswordException
@ -280,7 +287,7 @@ class KktMonitorTest extends BasicTestCase
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
*/ */
public function testMonitorGetAll() public function testMonitorGetAll(): void
{ {
$this->skipIfMonitoringIsOffline(); $this->skipIfMonitoringIsOffline();
$client = $this->newTestClient(); $client = $this->newTestClient();
@ -289,6 +296,7 @@ class KktMonitorTest extends BasicTestCase
$this->assertNotEmpty($client->getResponse()->getContent()); $this->assertNotEmpty($client->getResponse()->getContent());
$this->assertIsCollection($kkts); $this->assertIsCollection($kkts);
$this->assertTrue($kkts->count() > 0); $this->assertTrue($kkts->count() > 0);
$this->assertIsSameClass(Kkt::class, $kkts->random());
} }
/** /**
@ -299,24 +307,30 @@ class KktMonitorTest extends BasicTestCase
* @covers \AtolOnline\Api\AtolClient::getUrlToMethod * @covers \AtolOnline\Api\AtolClient::getUrlToMethod
* @covers \AtolOnline\Api\KktMonitor::fetchOne * @covers \AtolOnline\Api\KktMonitor::fetchOne
* @covers \AtolOnline\Api\KktMonitor::getOne * @covers \AtolOnline\Api\KktMonitor::getOne
* @covers \AtolOnline\Entities\Kkt::__construct
* @covers \AtolOnline\Entities\Kkt::__get
* @covers \AtolOnline\Entities\Kkt::jsonSerialize
* @covers \AtolOnline\Entities\Kkt::__toString
* @throws AuthFailedException * @throws AuthFailedException
* @throws EmptyLoginException * @throws EmptyLoginException
* @throws EmptyPasswordException * @throws EmptyPasswordException
* @throws GuzzleException * @throws GuzzleException
* @throws TooLongLoginException * @throws TooLongLoginException
* @throws TooLongPasswordException * @throws TooLongPasswordException
* @throws EmptyMonitorDataException
* @throws NotEnoughMonitorDataException
*/ */
public function testGetOne() public function testMOnitorGetOne(): void
{ {
$this->skipIfMonitoringIsOffline(); $this->skipIfMonitoringIsOffline();
$client = $this->newTestClient(); $client = $this->newTestClient();
$client->auth(); $client->auth();
$kkts = $client->getAll(); $serial_number = $client->getAll()->random()->serialNumber;
$serial_number = $kkts->first()->serialNumber; $kkt = $client->getOne($serial_number);
$client->getOne($serial_number);
$this->assertIsSameClass(KktResponse::class, $client->getResponse());
$this->assertNotEmpty($client->getResponse()); $this->assertNotEmpty($client->getResponse());
$this->assertNotNull($client->getResponse()->data->serialNumber); $this->assertIsSameClass(Kkt::class, $kkt);
$this->assertEquals($serial_number, $client->getResponse()->data->serialNumber); $this->assertAtolable($kkt);
$this->assertNotNull($kkt->serialNumber);
$this->assertEquals($serial_number, $kkt->serialNumber);
} }
} }

View File

@ -10,9 +10,8 @@
namespace AtolOnlineTests; namespace AtolOnlineTests;
use AtolOnline\{ use AtolOnline\{
Constants\VatTypes, Entities\Vat,
Entities\Vat Enums\VatTypes};
};
/** /**
* Class VatTest * Class VatTest