<?php
namespace Backend\BaseBundle\Tests\Controller\API;


use Backend\BaseBundle\Model\SiteConfig;
use Backend\BaseBundle\Model\SiteConfigQuery;
use Backend\BaseBundle\Model\SiteQuery;
use Backend\BaseBundle\Service\CustomGRecaptchaService;
use Backend\BaseBundle\SiteConfig\ModelConfig;
use Backend\BaseBundle\SiteConfig\SiteConfigBuilder;
use Backend\BaseBundle\Tests\Fixture\BackendWebTestCase;
use Symfony\Component\HttpFoundation\Response;

/**
 * @group functional
 */
class ConfigControllerTest extends BackendWebTestCase
{

    public function test_indexAction_not_found()
    {
        //arrange
        $slug = 'dgfactor';
        $config = 'bad_config';

        //act
        $this->client->request(
            'GET',
            $this->generateUrl('backend_base_api_config_index', array('slug' => $slug, 'config' => $config))
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertTrue($response->isNotFound());
    }

    public function test_indexAction_google_tag_manager()
    {
        //arrange
        $slug = 'dgfactor';
        $config = 'google_tag_manager';
        $configContent = 'test_content';

        $modelConfig = $this->getMockBuilder(ModelConfig::class)
            ->disableOriginalConstructor()
            ->setMethods(array('get'))
            ->getMock();
        $modelConfig
            ->expects($this->once())
            ->method('get')
            ->willReturnCallback(function($config) use($configContent){
                $this->assertEquals('system', $config);
                return array(
                    'google_tag_manager' => $configContent,
                );
            });

        $mockConfigBuilder = $this->getMockBuilder(SiteConfigBuilder::class)
            ->disableOriginalConstructor()
            ->setMethods(array('build'))
            ->getMock()
            ;
        $mockConfigBuilder
            ->expects($this->once())
            ->method('build')
            ->willReturn($modelConfig);
        $this->client->getContainer()->set('backend_base.site_config_builder', $mockConfigBuilder);

        //act
        $this->client->request(
            'GET',
            $this->generateUrl('backend_base_api_config_index', array('slug' => $slug, 'config' => $config))
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertTrue($response->isOk());
        $this->assertEquals($result['config'], $configContent);
    }

    public function test_indexAction_google_tag_manager_null()
    {
        //arrange
        $slug = 'dgfactor';
        $config = 'google_tag_manager';
        $configContent = 'test_content';

        $modelConfig = $this->getMockBuilder(ModelConfig::class)
            ->disableOriginalConstructor()
            ->setMethods(array('get'))
            ->getMock();
        $modelConfig
            ->expects($this->once())
            ->method('get')
            ->willReturnCallback(function($config) use($configContent){
                $this->assertEquals('system', $config);
                return array();
            });

        $mockConfigBuilder = $this->getMockBuilder(SiteConfigBuilder::class)
            ->disableOriginalConstructor()
            ->setMethods(array('build'))
            ->getMock()
        ;
        $mockConfigBuilder
            ->expects($this->once())
            ->method('build')
            ->willReturn($modelConfig);
        $this->client->getContainer()->set('backend_base.site_config_builder', $mockConfigBuilder);

        //act
        $this->client->request(
            'GET',
            $this->generateUrl('backend_base_api_config_index', array('slug' => $slug, 'config' => $config))
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertTrue($response->isOk());
        $this->assertNull($result['config']);
    }

    public function test_indexAction_recaptcha_site_key()
    {
        //arrange
        $slug = 'dgfactor';
        $config = 'recaptcha_site_key';
        $configContent = 'test_content';

        $modelConfig = $this->getMockBuilder(ModelConfig::class)
            ->disableOriginalConstructor()
            ->setMethods(array('get'))
            ->getMock();
        $modelConfig
            ->expects($this->once())
            ->method('get')
            ->willReturnCallback(function($config) use($configContent){
                $this->assertEquals('system', $config);
                return array(
                    'recaptcha_site_key' => $configContent,
                );
            });

        $mockConfigBuilder = $this->getMockBuilder(SiteConfigBuilder::class)
            ->disableOriginalConstructor()
            ->setMethods(array('build'))
            ->getMock()
        ;
        $mockConfigBuilder
            ->expects($this->once())
            ->method('build')
            ->willReturn($modelConfig);
        $this->client->getContainer()->set('backend_base.site_config_builder', $mockConfigBuilder);

        //act
        $this->client->request(
            'GET',
            $this->generateUrl('backend_base_api_config_index', array('slug' => $slug, 'config' => $config))
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertTrue($response->isOk());
        $this->assertEquals($result['config'], $configContent);
    }

    public function test_indexAction_recaptcha_site_key_null()
    {
        //arrange
        $slug = 'dgfactor';
        $config = 'recaptcha_site_key';
        $configContent = 'test_content';

        $modelConfig = $this->getMockBuilder(ModelConfig::class)
            ->disableOriginalConstructor()
            ->setMethods(array('get'))
            ->getMock();
        $modelConfig
            ->expects($this->once())
            ->method('get')
            ->willReturnCallback(function($config) use($configContent){
                $this->assertEquals('system', $config);
                return array();
            });

        $mockConfigBuilder = $this->getMockBuilder(SiteConfigBuilder::class)
            ->disableOriginalConstructor()
            ->setMethods(array('build'))
            ->getMock()
        ;
        $mockConfigBuilder
            ->expects($this->once())
            ->method('build')
            ->willReturn($modelConfig);
        $this->client->getContainer()->set('backend_base.site_config_builder', $mockConfigBuilder);

        //act
        $this->client->request(
            'GET',
            $this->generateUrl('backend_base_api_config_index', array('slug' => $slug, 'config' => $config))
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertTrue($response->isOk());
        $this->assertNull($result['config']);
    }

    public function test_grecaptchaVerifyAction()
    {
        //arrange
        $slug = 'dgfactor';
        $grecaptchaData = 'abc012345678';
        $secretKeyData = '11111111111';
        $data = array(
            'grecaptcha' => $grecaptchaData
        );

        $modelConfig = $this->getMockBuilder(ModelConfig::class)
            ->disableOriginalConstructor()
            ->setMethods(array('get'))
            ->getMock();
        $modelConfig
            ->expects($this->once())
            ->method('get')
            ->willReturnCallback(function($config) use($secretKeyData){
                $this->assertEquals('system', $config);
                return array(
                    'recaptcha_secret_key' => $secretKeyData
                );
            });
        $mockConfigBuilder = $this->getMockBuilder(SiteConfigBuilder::class)
            ->disableOriginalConstructor()
            ->setMethods(array('build'))
            ->getMock()
        ;
        $mockConfigBuilder
            ->expects($this->once())
            ->method('build')
            ->willReturn($modelConfig);
        $this->client->getContainer()->set('backend_base.site_config_builder', $mockConfigBuilder);

        $service = $this->getMockBuilder(CustomGRecaptchaService::class)
            ->disableOriginalConstructor()
            ->setMethods(array('captchaVerify'))
            ->getMock();
        $service
            ->expects($this->once())
            ->method('captchaVerify')
            ->willReturnCallback(function($grecaptcha, $secretKey) use($grecaptchaData, $secretKeyData){
                $this->assertEquals($grecaptchaData, $grecaptcha);
                $this->assertEquals($secretKeyData, $secretKey);
                return true;
            });
        $this->client->getContainer()->set('backend_base.custom_g_recaptcha', $service);

        //act
        $this->client->request(
            'PUT',
            $this->generateUrl('backend_base_api_config_grecaptchaverify', array('slug' => $slug)),
            array(),
            array(),
            array(),
            json_encode($data)
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertTrue($response->isOk());
        $this->assertEquals($result['status'], true);
    }

    public function test_grecaptchaVerifyAction_empty_grecaptcha()
    {
        //arrange
        $slug = 'dgfactor';
        $data = array(
            'grecaptcha' => ''
        );

        //act
        $this->client->request(
            'PUT',
            $this->generateUrl('backend_base_api_config_grecaptchaverify', array('slug' => $slug)),
            array(),
            array(),
            array(),
            json_encode($data)
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $response->getStatusCode());
        $this->assertEquals($result['code'], 1);
        $this->assertEquals($result['message'], 'not recaptcha');
    }

    public function test_grecaptchaVerifyAction_invalid()
    {
        //arrange
        $slug = 'dgfactor';
        $grecaptchaData = 'abc012345678';
        $data = array(
            'grecaptcha' => $grecaptchaData
        );

        //act
        $this->client->request(
            'PUT',
            $this->generateUrl('backend_base_api_config_grecaptchaverify', array('slug' => $slug)),
            array(),
            array(),
            array(),
            json_encode($data)
        );
        $response = $this->client->getResponse();
        $result = json_decode($response->getContent(), true);

        //assert
        $this->assertEquals($result['status'], false);
    }
}