<?php

namespace Sso\WebserviceBundle\Tests\Services\PasswordPolicy\Policy;

use Sso\WebserviceBundle\Tests\Services\ServicesKernelTestCase;
use Sso\WebserviceBundle\Database\Manager as DatabaseManager;
use Sso\WebserviceBundle\Entity\Webservice\Type\User;
use Sso\WebserviceBundle\Entity\Webservice\Type\PasswordPolicy;
use Sso\WebserviceBundle\Database\Webservice\User as DbUser;
use Sso\WebserviceBundle\Database\Webservice\Manager as WebserviceManager;
use Sso\WebserviceBundle\Database\Webservice\PasswordPolicy as DbPasswordPolicy;
use Sso\WebserviceBundle\Api\PasswordPolicy\Policy\Service;

/**
 * Class ServiceTest
 * @package Sso\WebserviceBundle\Tests\Services\PasswordPolicy\Policy
 */
class ServiceTest extends ServicesKernelTestCase
{
    public function testGetPolicyForUser()
    {
        $passwordPolicy = new PasswordPolicy();
        $passwordPolicy
            ->setPolicyId('00000000-0000-0000-0000-000000000000')
            ->setRegEx('[^A-Za-z0-9]')
            ->setValidityDuration(60)
            ->setHistorySize(5)
            ->setChangeDelay(10)
            ->setEditDistance(4)
            ->setPolicyDescription('Test Policy');

        $mockDbPasswordPolicy = $this->makeMock(
            DbPasswordPolicy::class,
            [
                'getOne' => $passwordPolicy
            ]
        );

        $mockUser = $this->makeMock(
            User::class,
            [
                'getPasswordPolicy' => '00000000-0000-0000-0000-000000000000'
            ]
        );

        $mockDbUser = $this->makeMock(
            DbUser::class,
            [
                'getUserByGuid' => $mockUser
            ]
        );

        $mockDbWebservice = $this->makeMock(
            WebserviceManager::class,
            [
                'user' => $mockDbUser,
                'passwordPolicy' => $mockDbPasswordPolicy,
            ]
        );

        $mockDbManager = $this->makeMock(
            DatabaseManager::class,
            [
                'webservice' => $mockDbWebservice
            ]
        );

        $service = new Service($mockDbManager);
        $userPolicy = $service->getPolicyForUser('TEST00000');

        $this->assertEquals('Test Policy', $userPolicy->getPolicyDescription());
    }

    /**
     * Helper function to ease the pain of creating 165382 mocks.... ;-)
     *
     * @param string $class
     * @param array $methodReturns
     * @return \PHPUnit_Framework_MockObject_MockObject
     */
    private function makeMock($class, $methodReturns)
    {
        $methods = [];
        foreach ($methodReturns as $method => $returnValue) {
            $methods[] = $method;
        }

        $mock = $this->getMockBuilder($class)
            ->disableOriginalConstructor()
            ->setMethods($methods)
            ->getMock();

        foreach ($methodReturns as $method => $returnValue) {
            $mock->expects($this->atLeastOnce())
                ->method($method)
                ->willReturn($returnValue);
        }

        return $mock;
    }
}
