<?php
/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2017 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\RestBundle\Tests\ModelRest\Common\Type;

use Sso\RestBundle\ModelRest\Common\Type\ArrayStringType;
use JMS\Serializer\SerializerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Sso\RestBundle\Api\Manager as ApiManager;

/**
 * Class ArrayStringTypeTest
 *
 * @copyright  2017 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Sso\RestBundle\Tests\ModelRest\Common\Type
 */
class ArrayStringTypeTest extends KernelTestCase
{
    /**
     * @var SerializerInterface
     */
    private $serializer;

    public function testSerializeJsonArray()
    {
        $values = ['Apple', 'Orange'];
        $object = new ArrayStringContainer();
        $object->setArrayValue(new ArrayStringType($values));

        $json = $this->serializer->serialize($object, 'json');
        $this->assertEquals('{"arrayValue":["Apple","Orange"]}', $json);
    }

    public function testDeserializeJsonArray()
    {
        $values = ['Apple', 'Orange'];
        $json = '{"arrayValue":["Apple","Orange"]}';

        $object = $this->serializer->deserialize($json, ArrayStringContainer::class, 'json');
        $this->assertInstanceOf(ArrayStringContainer::class, $object);
        $this->assertInstanceOf(ArrayStringType::class, $object->getArrayValue());
        $this->assertEquals($values, $object->getArrayValue()->getValue());
    }

    public function testSerializeJsonString()
    {
        $value = 'Apple';
        $object = new ArrayStringContainer();
        $object->setStringValue(new ArrayStringType($value));

        $json = $this->serializer->serialize($object, 'json');
        $this->assertEquals('{"stringValue":"Apple"}', $json);
    }

    public function testDeserializeJsonString()
    {
        $value = 'Apple';
        $json = '{"stringValue":"Apple"}';

        $object = $this->serializer->deserialize($json, ArrayStringContainer::class, 'json');
        $this->assertInstanceOf(ArrayStringContainer::class, $object);
        $this->assertInstanceOf(ArrayStringType::class, $object->getStringValue());
        $this->assertEquals($value, $object->getStringValue()->getValue());
    }

    public function testDeserializeJsonError()
    {
        $value = new \stdClass();
        $value->fruit = 'Apple';
        $json = json_encode($value);

        $object = $this->serializer->deserialize($json, ArrayStringContainer::class, 'json');
        $this->assertInstanceOf(ArrayStringContainer::class, $object);
        $this->assertNull($object->getArrayValue());
    }

    public function testSerializeXmlArray()
    {
        $values = ['Apple', 'Orange'];
        $object = new ArrayStringContainer();
        $object->setArrayValue(new ArrayStringType($values));

        $expectedXml = '<?xml version="1.0" encoding="UTF-8"?><root><arrayValue><entry>Apple</entry><entry>Orange</entry></arrayValue></root>';
        $xml = $this->serializer->serialize($object, 'xml');
        $this->assertXmlStringEqualsXmlString($expectedXml, $xml);
    }

    public function testDeserializeXmlArray()
    {
        $values = ['Apple', 'Orange'];
        $xml = '<?xml version="1.0" encoding="UTF-8"?><root><arrayValue><entry>Apple</entry><entry>Orange</entry></arrayValue></root>';

        $object = $this->serializer->deserialize($xml, ArrayStringContainer::class, 'xml');
        $this->assertInstanceOf(ArrayStringContainer::class, $object);
        $this->assertInstanceOf(ArrayStringType::class, $object->getArrayValue());
        $this->assertEquals($values, $object->getArrayValue()->getValue());
    }

    public function testSerializeXmlString()
    {
        $value = 'Apple';
        $object = new ArrayStringContainer();
        $object->setStringValue(new ArrayStringType($value));

        $expectedXml = '<?xml version="1.0" encoding="UTF-8"?><root><stringValue><entry>Apple</entry></stringValue></root>';
        $xml = $this->serializer->serialize($object, 'xml');
        $this->assertXmlStringEqualsXmlString($expectedXml, $xml);
    }

    public function testDeserializeXmlString()
    {
        $value = ['Apple'];
        $xml = '<?xml version="1.0" encoding="UTF-8"?><root><stringValue><entry>Apple</entry></stringValue></root>';

        $object = $this->serializer->deserialize($xml, ArrayStringContainer::class, 'xml');
        $this->assertInstanceOf(ArrayStringContainer::class, $object);
        $this->assertEquals($value, $object->getStringValue()->getValue());
    }

    public function testDeserializeXmlError()
    {
        $value = new \stdClass();
        $value->fruit = 'Apple';
        $xml = $this->serializer->serialize($value, 'xml');

        $object = $this->serializer->deserialize($xml, ArrayStringContainer::class, 'xml');
        $this->assertInstanceOf(ArrayStringContainer::class, $object);
        $this->assertNull($object->getArrayValue());
    }

    protected function setUp()
    {
        parent::setUp();
        static::bootKernel();
        $apiManager = new ApiManager(static::$kernel->getContainer());
        $this->serializer = $apiManager->serializer();
    }
}
