<?php

namespace NoahVet\Reef\Test\A_Unit\Infrastructure\Serialization\Jane;

use NoahVet\Reef\Domain\Serialization\Jane\JaneDenormalizerInterface;
use NoahVet\Reef\Domain\Serialization\Jane\JaneDeserializerInterface;
use NoahVet\Reef\Domain\Serialization\Jane\JaneNormalizerInterface;
use NoahVet\Reef\Infrastructure\Serialization\Jane\JaneSerializerFacade;
use PHPUnit\Framework\TestCase;

class JaneSerializerFacadeTest extends TestCase
{
    private JaneSerializerFacade $subject;

    private JaneDenormalizerInterface $janeDenormalizer;

    private JaneDeserializerInterface $janeDeserializer;

    private JaneNormalizerInterface $janeNormalizer;

    protected function setUp(): void
    {
        $this->janeDenormalizer = $this->createMock(JaneDenormalizerInterface::class);
        $this->janeDeserializer = $this->createMock(JaneDeserializerInterface::class);
        $this->janeNormalizer = $this->createMock(JaneNormalizerInterface::class);
        $this->subject = new JaneSerializerFacade(
            $this->janeDeserializer,
            $this->janeDenormalizer,
            $this->janeNormalizer,
        );
    }

    public function testDenormalize(): void
    {
        $data = ['name' => 'test'];
        $expected = new \stdClass();

        $this->janeDenormalizer->expects($this->once())
            ->method('denormalize')
            ->with(data: $data, type: \stdClass::class)
            ->willReturn($expected)
        ;

        $result = $this->subject->denormalize(data: $data, type: \stdClass::class);

        $this->assertSame($expected, $result);
    }

    public function testNormalize(): void
    {
        $object = new \stdClass();
        $expected = ['name' => 'test'];

        $this->janeNormalizer->expects($this->once())
            ->method('normalize')
            ->with(object: $object)
            ->willReturn($expected)
        ;

        $result = $this->subject->normalize(object: $object);

        $this->assertSame($expected, $result);
    }

    public function testDeserialize(): void
    {
        $data = '{"name":"test"}';
        $expected = new \stdClass();

        $this->janeDeserializer->expects($this->once())
            ->method('deserialize')
            ->with(data: $data, type: \stdClass::class)
            ->willReturn($expected)
        ;

        $result = $this->subject->deserialize(data: $data, type: \stdClass::class);

        $this->assertSame($expected, $result);
    }
}
