<?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\UserSearch\FindByApplication;

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\Model\Application;
use Sso\WebserviceBundle\Tests\Functional\Services\Helper\Version2\Model\ApplicationRole;

/**
 * Class FindByApplicationRoleTest
 *
 * @copyright  2017 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Tests\Version2\UserSearch\FindByApplicationRoleTest
 */
class FindByApplicationRoleTest extends FunctionalTestCase
{

    public function testEmptyResultByValidApplicationRole()
    {
        $application = $this->helperFactory->applicationAdd()->execute();
        $this->helperFactory->userPermissionAdd()->execute($application);

        $applicationRole = $this->helperFactory->applicationRoleAdd()->execute($application);

        $requestBody = $this->getRequest($application, $applicationRole);
        $response = $this->sendPostRequest('UserSearch', 'FindByApplicationRole', $requestBody);

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

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

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

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

    /**
     * @dataProvider getUserActiveFlags
     * @param bool $userIsActive
     */
    public function testFindSingleUserByValidApplicationRole($userIsActive)
    {
        $application = $this->helperFactory->applicationAdd()->execute();
        $this->helperFactory->userPermissionAdd()->execute($application);

        $applicationRole = $this->helperFactory->applicationRoleAdd()->execute($application);

        $user = $this->helperFactory->userAdd()->execute($userIsActive);

        $this->helperFactory->userApplicationAdd()->execute($user, $application);
        $this->helperFactory->userApplicationRoleAdd()->execute($user, $application, $applicationRole);

        $requestBody = $this->getRequest($application, $applicationRole);
        $response = $this->sendPostRequest('UserSearch', 'FindByApplicationRole', $requestBody);

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

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

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

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

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

        static::assertEquals(
            $user->getEmail(),
            (string)$xmlSimple->UserSearch->FindByApplicationRole->UserType->Email,
            $this->fXml($requestBody, $xml, 'Xml value check failed')
        );

        static::assertEquals(
            $user->getUsername(),
            (string)$xmlSimple->UserSearch->FindByApplicationRole->UserType->Username,
            $this->fXml($requestBody, $xml, 'Xml value check failed')
        );

        static::assertEquals(
            $user->isActive() ? '1' : '0',
            (string)$xmlSimple->UserSearch->FindByApplicationRole->UserType->Active,
            $this->fXml($requestBody, $xml, 'Xml value check failed')
        );
    }

    /**
     * @return array
     */
    public function getUserActiveFlags()
    {
        return [
            [ true ],
            [ false ]
        ];
    }

    public function testFindMultipleUserByValidApplicationRole()
    {
        $application = $this->helperFactory->applicationAdd()->execute();
        $this->helperFactory->userPermissionAdd()->execute($application);

        $applicationRole = $this->helperFactory->applicationRoleAdd()->execute($application);

        $count = 3;
        do {
            $user = $this->helperFactory->userAdd()->execute();
            $this->helperFactory->userApplicationAdd()->execute($user, $application);
            $this->helperFactory->userApplicationRoleAdd()->execute($user, $application, $applicationRole);
        } while (--$count > 0);

        $requestBody = $this->getRequest($application, $applicationRole);
        $response = $this->sendPostRequest('UserSearch', 'FindByApplicationRole', $requestBody);

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

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

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

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

    public function testInvalidValidApplicationRole()
    {
        $application = new Application();
        $application->setName('NonExistingApplication');

        $applicationRole = new ApplicationRole('NonExistingApplicationRole');
        $applicationRole->setName('NonExistingRole');

        $requestBody = $this->getRequest($application, $applicationRole);
        $response = $this->sendPostRequest('UserSearch', 'FindByApplicationRole', $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')
        );
    }

    /**
     * @param Application $application
     * @param ApplicationRole $applicationRole
     * @return string
     */
    private function getRequest(Application $application, ApplicationRole $applicationRole)
    {
        return '<?xml version="1.0" encoding="UTF-8"?>
<SsoRequest>' . (string)(new Credentials($this->configuration)) . '
    <UserSearch>
        <FindByApplicationRole>
            <Key>
                <ApplicationType>
                    <Name>' . $this->cdata($application->getName()) . '</Name>
                </ApplicationType>
                <RoleType>
                    <Name>' . $this->cdata($applicationRole->getName()) . '</Name>
                </RoleType>
            </Key>
        </FindByApplicationRole>
    </UserSearch>
</SsoRequest>';
    }
}
