<?php
namespace Backend\BaseBundle\Tests\Model;

use Backend\BaseBundle\Model\Site;
use Backend\BaseBundle\Model\SiteGroup;
use Backend\BaseBundle\Model\SiteUser;
use Backend\BaseBundle\Security\SecurityEncoderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Backend\BaseBundle\Tests\Fixture\BaseTestCase;

/**
 * @group unit
 */
class SiteUserTest extends BaseTestCase
{
    public function test_is_a_SecurityEncoderInterface()
    {
        //arrange
        //act
        $user = new SiteUser();

        //assert
        $this->assertInstanceOf(SecurityEncoderInterface::class, $user);
    }

    public function test_is_a_UserInterface()
    {
        //arrange
        //act
        $user = new SiteUser();

        //assert
        $this->assertInstanceOf(UserInterface::class, $user);
    }

    public function test_getSiteSlug_null()
    {
        //arrage
        $expect = 'test';

        $site = $this->getMock(Site::class, array('getSlug'));
        $site
            ->expects($this->once())
            ->method('getSlug')
            ->willReturn($expect);

        $siteUser = $this->getMock(SiteUser::class, array('getSite'));
        $siteUser
            ->expects($this->once())
            ->method('getSite')
            ->willReturn($site);

        //act
        $result = $siteUser->getSiteSlug();

        //assert
        $this->assertEquals($expect, $result);
    }

    public function test_getSiteSlug()
    {
        //arrage
        $expect = 'test';

        $site = $this->getMock(Site::class, array('getSlug'));
        $site
            ->expects($this->never())
            ->method('getSlug')
            ->willReturn($expect);

        $siteUser = $this->getMock(SiteUser::class, array('getSite'));
        $siteUser
            ->expects($this->never())
            ->method('getSite')
            ->willReturn($site);

        $this->setObjectAttribute($siteUser, 'site_slug', $expect);

        //act
        $result = $siteUser->getSiteSlug();

        //assert
        $this->assertEquals($expect, $result);
    }

    public function test_getUserName()
    {
        $mokeUser = $this->getMock(SiteUser::class, array('getLoginName'));
        $mokeUser
            ->expects($this->once())
            ->method('getLoginName')
            ->willReturn('test_value');
        $this->assertEquals('test_value', $mokeUser->getUserName());
    }

    public function test_eraseCredentials()
    {
        $user = new SiteUser();
        $user->setPassword('password');
        $user->setSalt('salt');
        $user->setPlainPassword('plain_password');

        $user->eraseCredentials();

        $this->assertNull($user->getPassword());
        $this->assertNull($user->getSalt());
        $this->assertNull($user->getPlainPassword());
    }

    public function test_setPlainPassword()
    {
        $user = new SiteUser();
        $user->setPlainPassword('plain_password');
        $this->assertEquals('plain_password', $this->getObjectAttribute($user, 'plainPassword'));
    }

    public function test_getPlainPassword()
    {
        $user = new SiteUser();
        $user->setPlainPassword('plain_password');
        $this->assertEquals('plain_password', $user->getPlainPassword());
    }

    public function test_getRoles()
    {
        //arrange
        $defaultRoles = array('DEFAULT1', 'DEFAULT2');
        $customRoles = array('CUSTOM1', 'CUSTOM2');
        $group1Roles = array('GROUP1', 'CUSTOM1');
        $group2Roles = array('GROUP2', 'CUSTOM2');
        $expectResult = array('CUSTOM1', 'CUSTOM2', 'DEFAULT1', 'DEFAULT2', 'GROUP1', 'GROUP2');

        $group1 = $this->getMock(SiteGroup::class, array('getRoles'));
        $group1->expects($this->once())
            ->method('getRoles')
            ->willReturn($group1Roles);
        $group2 = $this->getMock(SiteGroup::class, array('getRoles'));
        $group2->expects($this->once())
            ->method('getRoles')
            ->willReturn($group2Roles);
        $user = $this->getMock(SiteUser::class, array('getDefaultRoles', 'getCustomRoles', 'getSiteGroups'));
        $user->expects($this->once())
            ->method('getDefaultRoles')
            ->willReturn($defaultRoles);
        $user->expects($this->once())
            ->method('getCustomRoles')
            ->willReturn($customRoles);
        $user->expects($this->once())
            ->method('getSiteGroups')
            ->willReturn(new \PropelCollection(array($group1, $group2)));

        //act
        $result = $user->getRoles();
        sort($result);

        //assert
        $this->assertEquals($expectResult, $result);
    }

    public function test_regenerateSalt()
    {
        //arrange
        $user = new SiteUser();

        //act
        $user->regenerateSalt();

        //assert
        $this->assertNotNull($user->getSalt());
    }

    public function test_generateToken()
    {
        //arrange
        $user = new SiteUser();

        //act
        $user->generateToken();

        //aeeert
        $this->assertNotNull($user->getConfirmToken());
        $this->assertGreaterThan(time()+29*60, $user->getTokenExpiredAt('U'));
    }

}