<?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\WebserviceBundle\Tests\Functional\Services\Tests\Version2;

use Sso\WebserviceBundle\Tests\Functional\Services\Helper\Credentials;
use Sso\WebserviceBundle\Tests\Functional\Services\Helper\Version2\FunctionalTestCase;
use Sso\WebserviceBundle\Tests\Functional\Services\Helper\Version2\Constants;

/**
 * Class UserShowTest
 *
 * @copyright  2017 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Tests\Version2
 */
class UserShowTest extends FunctionalTestCase
{
    public function testSuccess()
    {
        $requestBody = $this->getRequest($this->configuration->getUsername());
        $response = $this->sendPostRequest('User', 'Show', $requestBody);

        static::assertEquals(200, $response->getStatusCode());

        $xml = $response->getContent();
        $xmlElement = $this->loadResponse($xml);

        $xmlElementExpected = $this->loadXmlDomElement(
            __DIR__ . '/xml/response-structure-success.xml',
            'SsoResponse'
        );

        static::assertEqualXMLStructure(
            $xmlElementExpected,
            $xmlElement,
            false,
            $this->fXml($requestBody, $xml, 'Xml structure check failed')
        );
    }

    public function testFindByUsername()
    {
        $user = $this->helperFactory->userAdd()->execute();

        $requestBody = $this->getRequestByUsername($user->getUsername());
        $response = $this->sendPostRequest('User', 'Show', $requestBody);

        static::assertEquals(200, $response->getStatusCode());
        $xml = $response->getContent();
        $xmlElement = $this->loadResponse($xml);

        $xmlElementExpected = $this->loadXmlDomElement(
            __DIR__ . '/xml/response-structure-success-inactive-user.xml',
            'SsoResponse'
        );

        static::assertEqualXMLStructure(
            $xmlElementExpected,
            $xmlElement,
            false,
            $this->fXml($requestBody, $xml, 'Xml structure check failed')
        );
    }

    public function testFindByEmail()
    {
        $user = $this->helperFactory->userAdd()->execute();

        $requestBody = $this->getRequestByEmail($user->getEmail());
        $response = $this->sendPostRequest('User', 'Show', $requestBody);

        static::assertEquals(200, $response->getStatusCode());

        $xml = $response->getContent();
        $xmlElement = $this->loadResponse($xml);

        $xmlElementExpected = $this->loadXmlDomElement(
            __DIR__ . '/xml/response-structure-success-inactive-user.xml',
            'SsoResponse'
        );

        static::assertEqualXMLStructure(
            $xmlElementExpected,
            $xmlElement,
            false,
            $this->fXml($requestBody, $xml, 'Xml structure check failed')
        );
    }

    public function testFindByGuid()
    {
        $user = $this->helperFactory->userAdd()->execute();

        $requestBody = $this->getRequestByGuid($user->getGuid());
        $response = $this->sendPostRequest('User', 'Show', $requestBody);

        static::assertEquals(200, $response->getStatusCode());

        $xml = $response->getContent();
        $xmlElement = $this->loadResponse($xml);

        $xmlElementExpected = $this->loadXmlDomElement(
            __DIR__ . '/xml/response-structure-success-inactive-user.xml',
            'SsoResponse'
        );

        static::assertEqualXMLStructure(
            $xmlElementExpected,
            $xmlElement,
            false,
            $this->fXml($requestBody, $xml, 'Xml structure check failed')
        );
    }

    public function testFindByIdentifier()
    {
        $user = $this->helperFactory->userAdd()->execute();

        $requestBody = $this->getRequestByIdentifier($user->getEmail());
        $response = $this->sendPostRequest('User', 'Show', $requestBody);

        static::assertEquals(200, $response->getStatusCode());

        $xml = $response->getContent();
        $xmlElement = $this->loadResponse($xml);

        $xmlElementExpected = $this->loadXmlDomElement(
            __DIR__ . '/xml/response-structure-success-inactive-user.xml',
            'SsoResponse'
        );

        static::assertEqualXMLStructure(
            $xmlElementExpected,
            $xmlElement,
            false,
            $this->fXml($requestBody, $xml, 'Xml structure check failed')
        );
    }

    public function testUserDoesNotExist()
    {
        $requestBody = $this->getRequest('NonExistingUser' . mt_rand());
        $response = $this->sendPostRequest('User', 'Show', $requestBody);

        static::assertEquals(200, $response->getStatusCode());

        $xml = $response->getContent();
        $xmlElement = $this->loadResponse($xml);

        $xmlElementExpected = $this->loadXmlDomElement(
            __DIR__ . '/xml/response-structure-error.xml',
            'SsoResponse'
        );

        static::assertEqualXMLStructure(
            $xmlElementExpected,
            $xmlElement,
            false,
            $this->fXml($requestBody, $xml, 'Xml structure check failed')
        );

        // Value check
        $xmlSimple = simplexml_load_string($xml);

        static::assertEquals(
            Constants::STATUS_NOT_FOUND,
            (string)$xmlSimple->Status,
            $this->fXml($requestBody, $xml, 'Global xml status code does not match!')
        );

        static::assertRegExp(
            Constants::REGEXP_DATE,
            (string)$xmlSimple->Date,
            $this->fXml($requestBody, $xml, 'Date format does not match!')
        );

        static::assertEquals(
            Constants::STATUS_NOT_FOUND,
            (string)$xmlSimple->Errors->Error->Status,
            $this->fXml($requestBody, $xml, 'Xml status code does not match!')
        );

        static::assertEquals(
            'u001',
            (string)$xmlSimple->Errors->Error->ErrorCode,
            $this->fXml($requestBody, $xml, 'Error code does not match!')
        );
    }

    /**
     * @param string $username
     * @return string
     */
    private function getRequest($username)
    {
        return '<?xml version="1.0" encoding="UTF-8"?>
<SsoRequest>' . (string)(new Credentials($this->configuration)) . '<User>
        <Show>
            <Key>
                <UserType>
                    <Username>' . $this->cdata($username) . '</Username>
                </UserType>
            </Key>
        </Show>
    </User>
</SsoRequest>';
    }

    /**
     * @param string $username
     * @return string
     */
    private function getRequestByUsername($username)
    {
        return '<?xml version="1.0" encoding="UTF-8"?>
<SsoRequest>' . (string)(new Credentials($this->configuration)) . '<User>
        <Show>
            <Key>
                <UserType>
                    <Username>' . $this->cdata($username) . '</Username>
                </UserType>
            </Key>
        </Show>
    </User>
</SsoRequest>';
    }

    /**
     * @param string $email
     * @return string
     */
    private function getRequestByEmail($email)
    {
        return '<?xml version="1.0" encoding="UTF-8"?>
<SsoRequest>' . (string)(new Credentials($this->configuration)) . '<User>
        <Show>
            <Key>
                <UserType>
                    <Email>' . $this->cdata($email) . '</Email>
                </UserType>
            </Key>
        </Show>
    </User>
</SsoRequest>';
    }

    /**
     * @param string $guid
     * @return string
     */
    private function getRequestByGuid($guid)
    {
        return '<?xml version="1.0" encoding="UTF-8"?>
<SsoRequest>' . (string)(new Credentials($this->configuration)) . '<User>
        <Show>
            <Key>
                <UserType>
                    <Guid>' . $this->cdata($guid) . '</Guid>
                </UserType>
            </Key>
        </Show>
    </User>
</SsoRequest>';
    }

    /**
     * @param string $identifier
     * @return string
     */
    private function getRequestByIdentifier($identifier)
    {
        return '<?xml version="1.0" encoding="UTF-8"?>
<SsoRequest>' . (string)(new Credentials($this->configuration)) . '<User>
        <Show>
            <Key>
                <UserType>
                    <Identifier>' . $this->cdata($identifier) . '</Identifier>
                </UserType>
            </Key>
        </Show>
    </User>
</SsoRequest>';
    }
}
