<?php

/**
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is protected 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  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\RestBundle\Tests\Controller;

use Symfony\Component\HttpFoundation\Request;
use GuzzleHttp\Psr7\Response;
use Sso\RestBundle\Worker\Worker;
use Sso\RestBundle\Worker\ObjectWs\Version1\Object\Delete\Handler as DeleteHandler;

/**
 * Class ObjectControllerTest
 *
 * @copyright  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package    Sso\RestBundle\Tests\Controller
 */
class ObjectControllerTest extends BaseTestCase
{
    /**
     * @var string
     */
    private $mockedResponsePath = __DIR__ . '../../../MockedResponse/ObjectWs/Version1/Object/';

    /**
     * @var string
     */
    private $requestBodyPath = __DIR__ . '../../../RequestBody/ObjectWs/Version1/Object/';

    /**
     * @var string
     */
    private $expectedResponsePath = __DIR__ . '../../../ExpectedResponse/ObjectWs/Version1/Object/';

    public function testJsonDeleteObjectSuccess()
    {
        // Mock client and set responses (this test is deleting multiple items in one call with success response)
        $clientMock = $this->getMockedClientMultipleResponses([
            new Response(200, [], file_get_contents($this->mockedResponsePath . 'Delete/success1.xml')),
            new Response(200, [], file_get_contents($this->mockedResponsePath . 'Delete/success2.xml')),
        ]);

        $this->apiM->setClient($clientMock);

        $worker = new Worker($this->apiM);
        $worker->objectWs()->version1()->object()->deleteObject();

        $server = [
            'REQUEST_URI' => '/api/v1/object.json',
            'REQUEST_METHOD' => 'DELETE',
        ];

        // Prepare request and set request body and server request settings
        $request = new Request(
            [], [], [], [], [],
            $server,
            file_get_contents($this->requestBodyPath . 'Delete/success.json')
        );

        $handler = new DeleteHandler($this->apiM);
        $view = $handler->init($request);

        $response = $this->container->get('serializer')->serialize($view->getData(), 'json');
        $response = preg_replace('/"ScriptTimeSec["0-9:.]+,/i', '', $response);

        $this->assertEquals(200, $view->getStatusCode());
        $this->assertJsonStringEqualsJsonString(
            file_get_contents($this->expectedResponsePath . 'Delete/success.json'),
            $response
        );
    }

    public function testJsonDeleteObjectErrorNoObjectFound()
    {
        // Mock client and set responses (this test is deleting multiple items in one call with error response)
        $clientMock = $this->getMockedClientMultipleResponses([
            new Response(400, [], file_get_contents($this->mockedResponsePath . 'Delete/error_no_object_found1.xml')),
            new Response(400, [], file_get_contents($this->mockedResponsePath . 'Delete/error_no_object_found2.xml')),
        ]);

        $this->apiM->setClient($clientMock);

        $worker = new Worker($this->apiM);
        $worker->objectWs()->version1()->object()->deleteObject();

        $server = [
            'REQUEST_URI' => '/api/v1/object.json',
            'REQUEST_METHOD' => 'DELETE',
        ];

        // Prepare request and set request body and server request settings
        $request = new Request(
            [], [], [], [], [],
            $server,
            file_get_contents($this->requestBodyPath . 'Delete/error_no_object_found.json')
        );

        $handler = new DeleteHandler($this->apiM);
        $view = $handler->init($request);

        $response = $this->container->get('serializer')->serialize($view->getData(), 'json');
        $response = preg_replace('/"ScriptTimeSec["0-9:.]+,/i', '', $response);

        $this->assertEquals(200, $view->getStatusCode());
        $this->assertJsonStringEqualsJsonString(
            file_get_contents($this->expectedResponsePath . 'Delete/error_no_object_found.json'),
            $response
        );
    }

    public function testXmlDeleteObjectSuccess()
    {
        // Mock client and set responses (this test is deleting multiple items in one call with success response)
        $clientMock = $this->getMockedClientMultipleResponses([
            new Response(200, [], file_get_contents($this->mockedResponsePath . 'Delete/success1.xml')),
            new Response(200, [], file_get_contents($this->mockedResponsePath . 'Delete/success2.xml')),
        ]);

        $this->apiM->setClient($clientMock);

        $worker = new Worker($this->apiM);
        $worker->objectWs()->version1()->object()->deleteObject();

        $server = [
            'REQUEST_URI' => '/api/v1/object.xml',
            'REQUEST_METHOD' => 'DELETE',
        ];

        // Prepare request and set request body and server request settings
        $request = new Request(
            [], [], [], [], [],
            $server,
            file_get_contents($this->requestBodyPath . 'Delete/success.xml')
        );

        $handler = new DeleteHandler($this->apiM);
        $view = $handler->init($request);

        $response = $this->container->get('serializer')->serialize($view->getData(), 'xml');
        $response = preg_replace('/<scriptTimeSec>(.*?)<\/scriptTimeSec>/i', '', $response);

        $this->assertEquals(200, $view->getStatusCode());
        $this->assertXmlStringEqualsXmlString(
            file_get_contents($this->expectedResponsePath . 'Delete/success.xml'),
            $response
        );
    }

    public function testXmlDeleteObjectErrorNoObjectFound()
    {
        // Mock client and set responses (this test is deleting multiple items in one call with error response)
        $clientMock = $this->getMockedClientMultipleResponses([
            new Response(400, [], file_get_contents($this->mockedResponsePath . 'Delete/error_no_object_found1.xml')),
            new Response(400, [], file_get_contents($this->mockedResponsePath . 'Delete/error_no_object_found2.xml')),
        ]);

        $this->apiM->setClient($clientMock);

        $worker = new Worker($this->apiM);
        $worker->objectWs()->version1()->object()->deleteObject();

        $server = [
            'REQUEST_URI' => '/api/v1/object.xml',
            'REQUEST_METHOD' => 'DELETE',
        ];

        // Prepare request and set request body and server request settings
        $request = new Request(
            [], [], [], [], [],
            $server,
            file_get_contents($this->requestBodyPath . 'Delete/error_no_object_found.xml')
        );

        $handler = new DeleteHandler($this->apiM);
        $view = $handler->init($request);

        $response = $this->container->get('serializer')->serialize($view->getData(), 'xml');
        $response = preg_replace('/<scriptTimeSec>(.*?)<\/scriptTimeSec>/i', '', $response);

        $this->assertEquals(200, $view->getStatusCode());
        $this->assertXmlStringEqualsXmlString(
            file_get_contents($this->expectedResponsePath . 'Delete/error_no_object_found.xml'),
            $response
        );
    }
}
