assertInstanceOf(AtolOnlineApi::class, $api); $this->assertSame(AtolOnlineApi::API_VERSION_V3, $api->getVersion()); $api->setVersion(AtolOnlineApi::API_VERSION_V4); $this->assertSame(AtolOnlineApi::API_VERSION_V4, $api->getVersion()); $api->setLogger(new NullLogger()); $this->assertInstanceOf(NullLogger::class, $this->getProperty($api, 'logger')); $api->setCache(new ArrayCache()); $this->assertInstanceOf(ArrayCache::class, $this->getProperty($api, 'cache')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::sell */ public function testSell(): void { $responses = [ new Response(200, [], $this->getTokenSuccessResponseV4()), new Response(200, [], $this->getReportSuccessReportV4()), ]; $request = (new AtolOnline())->serializeOperationRequest($this->getPaymentRecepientRequest()); $response = $this->getApi($responses)->sell($request); $this->assertSame('2ea26f17–0884–4f08–b120–306fc096a58f', json_decode($response, true)['uuid']); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::sellRefund */ public function testSellRefund(): void { $responses = [ new Response(200, [], $this->getTokenSuccessResponseV4()), new Response(200, [], $this->getReportSuccessReportV4()), ]; $request = (new AtolOnline())->serializeOperationRequest($this->getPaymentRecepientRequest()); $response = $this->getApi($responses)->sellRefund($request); $this->assertSame('2ea26f17–0884–4f08–b120–306fc096a58f', json_decode($response, true)['uuid']); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::checkStatus */ public function testCheckStatusSuccessResponse(): void { $responses = [ new Response(200, [], $this->getTokenSuccessResponseV4()), new Response(200, [], $this->getReportSuccessReportV4()), ]; $response = $this->callMethod($this->getApi($responses), 'checkStatus', [ 'uuid' => '2ea26f17–0884–4f08–b120–306fc096a58f', ]); $this->assertSame('2ea26f17–0884–4f08–b120–306fc096a58f', json_decode($response, true)['uuid']); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::checkStatus */ public function testCheckStatusBadResponse(): void { $responses = [ new Response(200, [], $this->getTokenSuccessResponseV4()), new BadResponseException('', new Request('GET', 'test'), new Response(200, [], $this->getErrorResponseV4())), new Response(200, [], $this->getTokenSuccessResponseV4()), new Response(200, [], $this->getReportSuccessReportV4()), ]; $api = $this->getApi($responses); $api->setCache(new ArrayCache()); $response = $this->callMethod($api, 'checkStatus', [ 'uuid' => '2ea26f17–0884–4f08–b120–306fc096a58f', ]); $this->assertSame('2ea26f17–0884–4f08–b120–306fc096a58f', json_decode($response, true)['uuid']); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getUri */ public function testGetUri(): void { $this->assertSame('https://online.atol.ru/possystem', $this->callMethod($this->getApi(), 'getUri')); $this->assertSame('https://testonline.atol.ru/possystem', $this->callMethod($this->getApi([], true, true), 'getUri')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenBadResponse(): void { $api = $this->getApi([new BadResponseException('', new Request('GET', 'test'))]); $this->assertFalse($this->callMethod($api, 'getToken')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenSuccessResponse(): void { $api = $this->getApi([new Response(200, [], $this->getTokenSuccessResponseV4())]); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', $this->callMethod($api, 'getToken')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenErrorResponseWithLogger(): void { $logger = new TestLogger(); $api = $this->getApi([new Response(200, [], $this->getErrorResponseV4())]); $api->setLogger($logger); $this->assertFalse($this->callMethod($api, 'getToken')); $this->assertTrue($logger->hasError('12 Неверный логин или пароль')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenBadResponseWithLogger(): void { $logger = new TestLogger(); $api = $this->getApi([new BadResponseException('', new Request('GET', 'test'), new Response(200, [], $this->getErrorResponseV4()))]); $api->setLogger($logger); $this->assertFalse($this->callMethod($api, 'getToken')); $this->assertTrue($logger->hasError('{"error":{"error_id":"4475d6d8d-844d-4d05-aa8b-e3dbdf3defd5","code":12,"text":"\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043b\u043e\u0433\u0438\u043d \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c","type":"system"},"timestamp":"30.11.2017 17:58:53"}')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenSuccessResponseWithCache(): void { $cache = new ArrayCache(); $api = $this->getApi([new Response(200, [], $this->getTokenSuccessResponseV4())]); $api->setCache($cache); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', $this->callMethod($api, 'getToken')); $this->assertTrue($cache->contains($this->callMethod($api, 'getTokenCacheKey'))); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', $this->callMethod($api, 'getToken')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenSuccessResponseV3(): void { $api = $this->getApi([new Response(200, [], $this->getTokenSuccessResponseV3())])->setVersion(AtolOnlineApi::API_VERSION_V3); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', $this->callMethod($api, 'getToken')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getToken */ public function testGetTokenSuccessResponseV3WithCache(): void { $cache = new ArrayCache(); $api = $this->getApi([new Response(200, [], $this->getTokenSuccessResponseV3())])->setVersion(AtolOnlineApi::API_VERSION_V3); $api->setCache($cache); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', $this->callMethod($api, 'getToken')); $this->assertTrue($cache->contains($this->callMethod($api, 'getTokenCacheKey'))); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', $this->callMethod($api, 'getToken')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::buildUrl */ public function testBuildUrlWithoutToken(): void { $args = ['operation' => 'test']; $this->assertSame('https://online.atol.ru/possystem/v4/group/test', $this->callMethod($this->getApi(), 'buildUrl', $args)); $this->assertSame('https://online.atol.ru/possystem/v3/group/test', $this->callMethod($this->getApi()->setVersion(AtolOnlineApi::API_VERSION_V3), 'buildUrl', $args)); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::buildUrl */ public function testBuildUrlWithToken(): void { $args = ['operation' => 'test', 'token' => 'test']; $this->assertSame('https://online.atol.ru/possystem/v4/group/test?token=test', $this->callMethod($this->getApi(), 'buildUrl', $args)); $this->assertSame('https://online.atol.ru/possystem/v3/group/test?tokenid=test', $this->callMethod($this->getApi()->setVersion(AtolOnlineApi::API_VERSION_V3), 'buildUrl', $args)); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::sendOperationRequest */ public function testSendOperationRequestSuccessResponse(): void { $responses = [ new Response(200, [], $this->getTokenSuccessResponseV4()), new Response(200, [], $this->getTokenSuccessResponseV4()) ]; $request = (new AtolOnline())->serializeOperationRequest($this->getPaymentRecepientRequest()); $response = $this->callMethod($this->getApi($responses), 'sendOperationRequest', [ 'operation' => 'sell', 'data' => $request, ]); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', json_decode($response, true)['token']); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::sendOperationRequest */ public function testSendOperationRequestBadResponse(): void { $responses = [ new Response(200, [], $this->getTokenSuccessResponseV4()), new BadResponseException('', new Request('GET', 'test'), new Response(200, [], $this->getErrorResponseV4())), new Response(200, [], $this->getTokenSuccessResponseV4()), new Response(200, [], $this->getTokenSuccessResponseV4()), ]; $request = (new AtolOnline())->serializeOperationRequest($this->getPaymentRecepientRequest()); $api = $this->getApi($responses); $api->setCache(new ArrayCache()); $response = $this->callMethod($api, 'sendOperationRequest', [ 'operation' => 'sell', 'data' => $request, ]); $this->assertSame('fj45u923j59ju42395iu9423i59243u0', json_decode($response, true)['token']); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::logDebug */ public function testLogDebug(): void { $logger = new TestLogger(); $api = $this->getApi(); $api->setLogger($logger); $this->callMethod($api, 'logDebug', [ 'url' => '/test', 'data' => 'test', 'response' => new Response(200, ['X-Foo' => 'Bar', 'X-Foo2' => 'Bar2'], 'test'), ]); $this->assertTrue($logger->hasDebug('* URL: /test * POSTFIELDS: test * RESPONSE HEADERS: X-Foo: Bar, X-Foo2: Bar2 * RESPONSE BODY: test * ATTEMPTS: 0')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::getTokenCacheKey */ public function testGetTokenCacheKey(): void { $this->assertSame('crm_fiscal_atol_online_token_68526766e6751745b52ae70b7bd3c6fe_v4', $this->callMethod($this->getApi(), 'getTokenCacheKey')); $this->assertSame('crm_fiscal_atol_online_token_68526766e6751745b52ae70b7bd3c6fe_v3', $this->callMethod($this->getApi()->setVersion(AtolOnlineApi::API_VERSION_V3), 'getTokenCacheKey')); } /** * @return void * @covers \AtolOnlineClient\AtolOnlineApi::isTokenExpired */ public function testIsTokenExpired(): void { $body = new \stdClass(); $body->error = new \stdClass(); $body->error->code = 4; $this->assertTrue($this->callMethod($this->getApi(), 'isTokenExpired', ['body' => $body])); $body = new \stdClass(); $this->assertFalse($this->callMethod($this->getApi(), 'isTokenExpired', ['body' => $body])); } /** * @param array $responses * @param bool $debug * @param bool $test * @return AtolOnlineApi */ private function getApi(array $responses = [], bool $debug = true, bool $test = false): AtolOnlineApi { $connection = new Connection(); $connection->login = 'login'; $connection->pass = 'pass'; $connection->group = 'group'; $connection->sno = Connection::SNO_GENERAL; $connection->version = AtolOnlineApi::API_VERSION_V4; $connection->setDebug($debug); $connection->setTestMode($test); $mock = new MockHandler($responses); $handler = HandlerStack::create($mock); return new AtolOnlineApi(new Client(['handler' => $handler]), $connection); } /** * @param mixed $object * @param string $name * @param array $args * @return mixed */ private function callMethod($object, string $name, array $args = []) { $reflection = new \ReflectionClass($object); $method = $reflection->getMethod($name); $method->setAccessible(true); return $method->invokeArgs($object, $args); } /** * @param mixed $object * @param string $name * @return mixed */ private function getProperty($object, string $name) { $reflection = new \ReflectionClass($object); $property = $reflection->getProperty($name); $property->setAccessible(true); return $property->getValue($object); } /** * @return false|string */ private function getTokenSuccessResponseV3() { return json_encode([ 'token' => 'fj45u923j59ju42395iu9423i59243u0', 'code' => 1, ]); } /** * @return false|string */ private function getTokenSuccessResponseV4() { return json_encode([ 'error' => null, 'token' => 'fj45u923j59ju42395iu9423i59243u0', 'timestamp' => '30.11.2017 17:58:53', ]); } /** * @return false|string */ private function getErrorResponseV4() { return json_encode([ 'error' => [ 'error_id' => '4475d6d8d-844d-4d05-aa8b-e3dbdf3defd5', 'code' => 12, 'text' => 'Неверный логин или пароль', 'type' => 'system', ], 'timestamp' => '30.11.2017 17:58:53', ]); } /** * @return string */ private function getReportSuccessReportV4(): string { return file_get_contents(__DIR__.'/../fixtures/success_response_v4_3.json'); } /** * @return PaymentReceiptRequest */ private function getPaymentRecepientRequest(): PaymentReceiptRequest { $service = new ServiceRequest(); $service->setCallbackUrl('test.local'); $receipt = new ReceiptRequest(); $receipt->setTotal('100'); /** @var PaymentReceiptRequest $request */ $request = new PaymentReceiptRequest(); $request->setExternalId('test'); $request->setService($service); $request->setReceipt($receipt); return $request; } }