<?php
namespace FlowerTest\View\Pane\ManagerListener\Domain;

use Flower\Domain\Domain;
use Flower\Test\TestTool;
use Flower\View\Pane\PaneEvent;
use Flower\View\Pane\ManagerListener\Domain\RenderCacheListener;
use Zend\EventManager\EventManager;

/**
 * Generated by PHPUnit_SkeletonGenerator 1.2.1 on 2014-02-07 at 11:03:24.
 */
class RenderCacheListenerTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var RenderCacheListener
     */
    protected $object;

    protected $config;

    protected $storageOptions;

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        $this->object = new RenderCacheListener;
        $this->config = require 'TestAsset/render_cache_listener.config.php';
        $this->storageOptions = $this->config['render_cache_listener']['cache_storage'];
    }

    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown()
    {
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::setStorageOptions
     */
    public function testSetStorageOptions()
    {
        $this->object->setStorageOptions($this->storageOptions);
        $this->assertEquals($this->storageOptions, TestTool::getPropertyValue($this->object, 'storageOptions'));
    }

    /**
     * @expectedException Flower\View\Pane\Exception\RuntimeException
     */
    public function testGetStorageOptionsWithoutDomainService()
    {
        $this->object->getStorageOptions();
    }

    /**
     * @expectedException Flower\View\Pane\Exception\RuntimeException
     */
    public function testGetStorageOptionsBeforeCurrentDomainIsSet()
    {
        $currentDomain = new Domain;
        $domainService = $this->getMock('Flower\Domain\Service');
        $domainService->expects($this->once())
                ->method('getCurrentDomain')
                ->will($this->returnValue($currentDomain));
        $this->object->setDomainService($domainService);
        $this->object->getStorageOptions();
    }

    /**
     * @depends testSetStorageOptions
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::getStorageOptions
     */
    public function testGetStorageOptions()
    {
        $currentDomain = new Domain;
        $currentDomain->setDomainId(123);
        $domainService = $this->getMock('Flower\Domain\Service');
        $domainService->expects($this->once())
                ->method('getCurrentDomain')
                ->will($this->returnValue($currentDomain));
        $this->object->setDomainService($domainService);
        $this->object->setStorageOptions($this->storageOptions);
        $this->object->setStorageOptions($this->storageOptions);
        $expects = $this->storageOptions;
        $expects['adapter']['options']['namespace'] = 'd_123' . $expects['adapter']['options']['namespace'];
        $this->assertEquals($expects, $this->object->getStorageOptions());
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::setStorage
     */
    public function testSetStorage()
    {
        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');
        $this->object->setStorage($storage);
        $this->assertSame($storage, TestTool::getPropertyValue($this->object, 'storage'));
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::getStorage
     */
    public function testGetStorage()
    {
        $this->assertNull($this->object->getStorage());
        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');
        $this->object->setStorage($storage);
        $this->assertSame($storage, $this->object->getStorage());
    }

    public function testGetStorageWithOptions()
    {
        $currentDomain = new Domain;
        $currentDomain->setDomainId(123);
        $domainService = $this->getMock('Flower\Domain\Service');
        $domainService->expects($this->once())
                ->method('getCurrentDomain')
                ->will($this->returnValue($currentDomain));
        $this->object->setDomainService($domainService);
        $this->assertNull($this->object->getStorage());
        $this->object->setStorageOptions($this->storageOptions);
        $storage = $this->object->getStorage();
        $this->assertInstanceOf('Zend\Cache\Storage\Adapter\FileSystem', $storage);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::attach
     */
    public function testAttach()
    {
        $eventManager = new EventManager;
        $this->object->attach($eventManager);
        $listeners = $eventManager->getListeners(PaneEvent::EVENT_RENDER);
        $this->assertCount(2, $listeners);
        $this->assertSame(TestTool::getPropertyValue($this->object, 'listeners')[0], $listeners->top());
    }

    public function testPreRenderModelCase()
    {
        $paneId = 'foo';
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setTarget($paneId);

        $rendered = '--';

        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');

        $storage->expects($this->once())
                ->method('hasItem')
                ->with($this->equalTo($paneId))
                ->will($this->returnValue(true));

        $storage->expects($this->once())
                ->method('getItem')
                ->with($this->equalTo($paneId))
                ->will($this->returnValue($rendered));

        $this->object->setStorage($storage);

        $res = $this->object->preRender($event);
        $this->assertTrue($event->propagationIsStopped());

        $this->assertEquals($rendered, $res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::preRender
     */
    public function testPreRenderWithStorageHasNoData()
    {
        $paneId = 'foo';
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setTarget($paneId);

        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');

        $storage->expects($this->once())
                ->method('hasItem')
                ->with($this->equalTo($paneId))
                ->will($this->returnValue(false));

        $this->object->setStorage($storage);

        $res = $this->object->preRender($event);

        $this->assertFalse($event->hasError());
        $this->assertNull($res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::preRender
     */
    public function testPreRenderWithStorageThrowsException()
    {
        $paneId = 'foo';
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setTarget($paneId);

        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');

        $storage->expects($this->once())
                ->method('hasItem')
                ->with($this->equalTo($paneId))
                ->will($this->returnValue(true));

        $storage->expects($this->once())
                ->method('getItem')
                ->with($this->equalTo($paneId))
                ->will($this->throwException(new \Exception));

        $this->object->setStorage($storage);
        $res = $this->object->preRender($event);

        $this->assertTrue($event->hasError());
        $this->assertNull($res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::postRender
     */
    public function testPostRenderModelCase()
    {
        $paneId = 'foo';
        $rendered = '--';
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setResult($rendered);

        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');

        $storage->expects($this->once())
                ->method('setItem')
                ->with($this->equalTo($paneId), $this->equalTo($rendered));

        $this->object->setStorage($storage);

        $res = $this->object->postRender($event);

        $this->assertEquals($rendered, $res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::postRender
     */
    public function testPostRenderEventHasError()
    {
        $paneId = 'foo';
        $rendered = '--';
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setResult($rendered);
        $event->addErrorMessage('error');
        $res = $this->object->postRender($event);
        $this->assertSame($rendered, $res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::postRender
     */
    public function testPostRenderWithoutStorage()
    {
        $paneId = 'foo';
        $rendered = '--';
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setResult($rendered);
        $res = $this->object->postRender($event);
        $this->assertSame($rendered, $res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::postRender
     */
    public function testPostRenderStorageThrowsException()
    {
        $paneId = 'foo';
        $rendered = '--';
        $pane = $this->getMock('Flower\View\Pane\PaneClass\Pane');
        $event = new PaneEvent(PaneEvent::EVENT_RENDER);
        $event->setPaneId($paneId);
        $event->setResult($rendered);

        $storage = $this->getMock('Zend\Cache\Storage\StorageInterface');
        $storage->expects($this->once())
                ->method('setItem')
                ->with($this->equalTo($paneId), $this->equalTo($rendered))
                ->will($this->throwException(new \Exception));
        $this->object->setStorage($storage);

        $res = $this->object->postRender($event);
        $this->assertTrue($event->hasError());
        $this->assertSame($rendered, $res);
    }

    /**
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::setDomainService
     */
    public function testSetDomainService()
    {
        $domainService = $this->getMock('Flower\Domain\Service');
        $this->object->setDomainService($domainService);
        $this->assertSame($domainService, TestTool::getPropertyValue($this->object, 'domainService'));
    }

    /**
     * @depends testSetDomainService
     * @covers Flower\View\Pane\ManagerListener\Domain\RenderCacheListener::getDomainService
     */
    public function testGetDomainService()
    {
        $domainService = $this->getMock('Flower\Domain\Service');
        $this->object->setDomainService($domainService);
        $this->assertSame($domainService, $this->object->getDomainService());
    }
}
