<?php

namespace App\Tests\A_Unit\Api\Crokit;

use GuzzleHttp\Client;
use GuzzleHttp\Message\Response;
use GuzzleHttp\Stream\Stream;
use Myvetshop\Module\Clinique\Api\Crokit\CrokitApiClient;
use Myvetshop\Module\Clinique\Api\Crokit\Dto\CrokitRecommandation;
use Myvetshop\Module\Clinique\Api\Crokit\Normalizer\CrokitRecommandationNormalizer;
use PHPUnit\Framework\TestCase;

class CrokitApiClientTest extends TestCase
{
    public function testGetRecommandationSuccessful(): void
    {
        $client = $this->createMock(Client::class);
        $normalizer = $this->createMock(CrokitRecommandationNormalizer::class);
        $apiClient = new CrokitApiClient($client, $normalizer);

        $client->expects($this->once())->method('get')
            ->willReturn(
                new Response(200, [], Stream::factory((string) \json_encode([['date' => 'some-date']])))
            );

        $normalizer->expects($this->once())->method('denormalize')
            ->with(['date' => 'some-date'])
            ->willReturn($this->createMock(CrokitRecommandation::class));

        $result = $apiClient->getRecommandation('some-code');
        $this->assertInstanceOf(CrokitRecommandation::class, $result);
    }

    public function testGetRecommandationRequestException(): void
    {
        $client = $this->createMock(Client::class);
        $normalizer = $this->createMock(CrokitRecommandationNormalizer::class);
        $apiClient = new CrokitApiClient($client, $normalizer);

        $client->expects($this->once())->method('get')
            ->willThrowException($this->createMock(\GuzzleHttp\Exception\RequestException::class));

        $this->expectException(\GuzzleHttp\Exception\RequestException::class);

        $apiClient->getRecommandation('some-code');
    }

    public function testGetRecommandationInvalidResponse(): void
    {
        $client = $this->createMock(Client::class);
        $normalizer = $this->createMock(CrokitRecommandationNormalizer::class);
        $apiClient = new CrokitApiClient($client, $normalizer);

        $client->expects($this->once())->method('get')
            ->willReturn(
                new Response(200, [], Stream::factory((string) \json_encode(['date' => null])))
            );

        $this->expectException(\Exception::class);

        $apiClient->getRecommandation('some-code');
    }
}
