<?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  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\WebserviceBundle\Tests\Services\User\Add;

use Sso\WebserviceBundle\Api\ApiManagerInterface;
use Sso\WebserviceBundle\Database\Webservice\User as UserRepository;
use Sso\WebserviceBundle\ErrorHandler\ErrorHandlerInterface;
use Sso\WebserviceBundle\PasswordCrypt\PasswordCryptRepositoryInterface;
use Sso\WebserviceBundle\Services\ApiVersionInflectorInterface;
use Sso\WebserviceBundle\Services\User\Add\Factory;
use Sso\WebserviceBundle\Services\User\Add\Handler;
use Sso\WebserviceBundle\Services\RequestInterface;
use Sso\WebserviceBundle\Services\ResponseBuilderInterface;
use Doctrine\ORM\EntityManagerInterface;
use LifeStyle\Tools\MfaBundle\MfaCreator;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Sso\WebserviceBundle\Tests\Services\ServicesKernelTestCase;
use Sso\WebserviceBundle\Entity\Webservice\Type\User as ModelUser;
use Sso\WebserviceBundle\Api\PasswordPolicy\History\Service as PasswordHistoryService;
use Sso\WebserviceBundle\Database\Webservice\PasswordPolicy as PasswordPolicyDatabase;

/**
 * Class HandlerTest
 *
 * @copyright  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Sso\WebserviceBundle\Tests\Services\User\Show
 */
class HandlerTest extends ServicesKernelTestCase
{
    /**
     * @var UserRepository
     */
    private $database;

    /**
     * @var ApiManagerInterface
     */
    private $apiManager;

    /**
     * @var MfaCreator
     */
    private $mfaCreator;

    /**
     * @var PasswordPolicyDatabase
     */
    private $passwordPolicyDatabase;

    /**
     * @var PasswordHistoryService
     */
    private $passwordHistoryService;

    /**
     * @var PasswordCryptRepositoryInterface
     */
    private $passwordCryptRepository;

    public function testHandleSuccess()
    {

        $apiVersion = 2;

        $apiVersionInflector = $this->createMock(ApiVersionInflectorInterface::class);
        $apiVersionInflector->method('inflect')->will(
                self::returnCallback(
                    function ($namespace, $classname) use ($apiVersion) {
                        return $namespace.'\\Version'.$apiVersion.'\\'.$classname;
                    }
                )
            );
        $factory = new Factory($this->apiManager, $apiVersionInflector);

        $errorHandler = $this->createMock(ErrorHandlerInterface::class);
        $errorHandler->method('hasErrors')->will(self::returnValue(false));

        $request = $this->createMock(RequestInterface::class);
        $request->expects(self::once())->method('getRequestBody')->will(self::returnValue($this->getRequestBody()));

        $handler = new Handler(
            $factory,
            $this->database,
            $errorHandler,
            $this->mfaCreator,
            $this->passwordPolicyDatabase,
            $this->passwordHistoryService,
            $this->passwordCryptRepository
        );

        $responseBuilder = $handler->handle($request);


        self::assertInstanceOf(ResponseBuilderInterface::class, $responseBuilder);
    }

    /**
     * @param string $identifier
     * @return string
     */
    private function getRequestBody()
    {
        return '<?xml version="1.0"?>
                <SsoRequest>
                    <User>
                        <Add>
                            <Value>
                                <UserType>
                                    <Email><![CDATA['.$this->faker->email.']]></Email>
                                    <Username><![CDATA['.$this->faker->userName.']]></Username>
                                    <Firstname><![CDATA['.$this->faker->firstName.']]></Firstname>
                                    <Lastname><![CDATA['.$this->faker->lastName.']]></Lastname>
                                    <Password><![CDATA['.$this->faker->password().']]></Password>
                                    <Active>'.$this->faker->boolean.'</Active>
                                </UserType>
                            </Value>
                        </Add>
                    </User>
                </SsoRequest>';
    }

    protected function setUp()
    {
        parent::setUp();
        $this->apiManager = $this->container->get('service_api_manager');
        $entityManager = $this->createMock(EntityManagerInterface::class);
        $mockedValidator = $this->createMock(ValidatorInterface::class);
        $readonly = false;
        $this->database = $this->createMock(UserRepository::class, array(), array($entityManager, $mockedValidator, $readonly));
        $this->database->expects(self::once())->method('getUserEntity')->will(self::returnValue(new ModelUser($mockedValidator)));
        $this->mfaCreator = $this->getMockBuilder(MfaCreator::class)->getMock();
        $this->passwordHistoryService = $this->getMockBuilder(PasswordHistoryService::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->passwordPolicyDatabase = $this->getMockBuilder(PasswordPolicyDatabase::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->passwordCryptRepository = $this->getMockBuilder(PasswordCryptRepositoryInterface::class)->getMock();
    }
}
