<?php
/**
 * core.framework
 *
 * @category   Core
 * @package    Core_Storage
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 */

/**
 * @category   Core
 * @package    Core_Storage
 * @subpackage UnitTests
 * @copyright  Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 * @group      Core_Storage
 */
class Core_Storage_FileTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var Core_Storage_File
     */
    protected $_object;

    protected function setUp()
    {
        $this->_object = new Core_Storage_File('/path');
    }

    /**
     * @covers Core_Storage_File::setUrl
     * @covers Core_Storage_File::getUrl
     */
    public function testCanSetAndGetUrl()
    {
        $this->_object->setUrl('/some/path');
        $this->assertEquals('/some/path', $this->_object->getUrl());
    }

    /**
     * @covers Core_Storage_File::getUrlPath
     */
    public function testCanGetUrlPathUsingCoreStorageStrategyHash()
    {
        $storage = $this->getMock('Core_Storage_Strategy_Hash');
        $storage
            ->expects($this->once())
            ->method('getUrlRoot')
            ->will($this->returnValue('/some/path'));
        $storage
            ->expects($this->once())
            ->method('createFileUrlPath')
            ->will($this->returnValue('/some/path/file'));
        $this->_object->setStorage($storage);

        $urlPath = $this->_object->getUrlPath();
        $this->assertEquals('/some/path/file', $urlPath);
    }

    /**
     * @covers Core_Storage_File::getUrl
     */
    public function testCanGetUrlUsingCoreStorageStrategyHash()
    {
        $filename = 'temppic.jpg';
        $storage = $this->getMock('Core_Storage_Strategy_Hash');
        $storage
            ->expects($this->once())
            ->method('getUrlRoot')
            ->will($this->returnValue('/repo/images'));
        $storage
            ->expects($this->once())
            ->method('createFileUrl')
            ->will($this->returnValue('/repo/images/'. $filename));
        $this->_object->setStorage($storage);

        $url = $this->_object->getUrl();
        $this->assertEquals('/repo/images/'. $filename, $url);
    }

    /**
     * @covers Core_Storage_File::getUrl
     */
    public function testCallingGetUrlWithoutBeingSetOrNoStorageThrowsAnException()
    {
        $this->setExpectedException('InvalidArgumentException');
        $this->_object->getUrl();
    }

    /**
     * @covers Core_Storage_File::getUrl
     * @expectedException InvalidArgumentException
     */
    public function testCallingGetUrlWithoutUrlRootBeingSetOnStorageThrowsAnException()
    {
        // $this->markTestIncomplete('TODO');

        $storage = $this->getMock('Core_Storage_Strategy_Hash');
        $storage
            ->expects($this->any())
            ->method('getUrl')
            ->will($this->throwException(new InvalidArgumentException));

        $this->_object->setStorage($storage);
        $this->_object->getUrl();
    }

    /**
     * @covers Core_Storage_File::setStorageName
     * @covers Core_Storage_File::getStorageName
     */
    public function testCanSetAndGetStorageName()
    {
        $this->_object->setStorageName('some_storage_name.txt');
        $this->assertEquals('some_storage_name.txt', $this->_object->getStorageName());
    }

    /**
     * @covers Core_Storage_File::setStorage
     * @covers Core_Storage_File::getStorage
     */
    public function testCanSetAndGetStorageStrategyHash()
    {
        $storage = $this->getMock('Core_Storage_Strategy_Hash');
        $this->_object->setStorage($storage);
        $this->assertInstanceOf('Core_Storage_Strategy_Hash', $this->_object->getStorage());
    }

    /**
     * @covers Core_Storage_File::getType
     * @group mimetype
     */
    public function testCallingGetTypeOnRemotelyStoredFileWorks()
    {
        include_once 'vfsStream/vfsStream.php';

        // using this for mocking out the filesystem!
        vfsStream::setup('storage_file');
        $file = vfsStream::url('storage_file/faux.txt');

        fclose(fopen($file, 'w'));
        file_put_contents($file, 'abc');

        $this->_object->setPath($file);

        $this->assertEquals('text/plain', $this->_object->getType());
    }

    /**
     * @covers Core_Storage_File::getSize
     */
    public function testCallingGetSizeOnRemotelyStoredFileWorks()
    {
        include_once 'vfsStream/vfsStream.php';

        // using this for mocking out the filesystem!
        vfsStream::setup('storage_file');
        $file = vfsStream::url('storage_file/faux.txt');

        fclose(fopen($file, 'w'));
        file_put_contents($file, '123456');

        $this->_object->setPath($file);

        $this->assertEquals('6', $this->_object->getSize());
    }

    /**
     * @covers Core_Storage_File::delete
     */
    public function testDeletingFile()
    {
        // using this for mocking out the filesystem!
        include_once 'vfsStream/vfsStream.php';
        vfsStream::setup('storage_file');
        $sourceFile = vfsStream::url('storage_file/faux.txt');

        fclose(fopen($sourceFile, 'w'));
        file_put_contents($sourceFile, '123456');

        $storage = $this->getMock('Core_Storage_Strategy_Hash');
        $storage
            ->expects($this->any())
            ->method('getPath')
            ->will($this->returnValue('/storage_file/faux.txt'));
        $this->_object = new Core_Storage_File($sourceFile);
        $this->_object->setStorage($storage);

        $this->assertTrue(file_exists($this->_object->getPath()));
        $this->assertTrue($this->_object->delete());
        $this->assertFalse(file_exists($this->_object->getPath()));
    }

    /**
     * @covers Core_Storage_File::rename
     */
    public function testRenamingFile()
    {
        $this->markTestIncomplete('TODO');
        // using this for mocking out the filesystem!
        include_once 'vfsStream/vfsStream.php';
        vfsStream::setup('storage_file');
        $sourceFile = vfsStream::url('storage_file/faux.txt');

        fclose(fopen($sourceFile, 'w'));
        file_put_contents($sourceFile, '123456');

        $storage = $this->getMock('Core_Storage_Strategy_Hash');
        $storage
            ->expects($this->any())
            ->method('getPath')
            ->will($this->returnValue('/storage_file/faux.txt'));
        $this->_object = new Core_Storage_File($sourceFile);
        $this->_object->setStorage($storage);

        $oldPath = $this->_object->getPath();
        $newName = 'new_name.dat';

        $this->assertTrue(file_exists($this->_object->getPath()));
        $destinationFile = $this->_object->rename($newName);
        $this->assertFalse(file_exists($oldPath));
        $this->assertTrue(file_exists($destinationFile->getPath()));
    }
}