View source
<?php
namespace Unit;
use Flow\File;
use Flow\Config;
use Flow\FileLockException;
use Flow\FileOpenException;
use Flow\Request;
use org\bovigo\vfs\vfsStreamWrapper;
use org\bovigo\vfs\vfsStreamDirectory;
use org\bovigo\vfs\vfsStream;
class FileTest extends FlowUnitCase {
protected $config;
protected $vfs;
protected function setUp() {
parent::setUp();
vfsStreamWrapper::register();
$this->vfs = new vfsStreamDirectory('chunks');
vfsStreamWrapper::setRoot($this->vfs);
$this->config = new Config();
$this->config
->setTempDir($this->vfs
->url());
}
public function testFile_construct_withRequest() {
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$expIdentifier = sha1($this->requestArr['flowIdentifier']);
$this
->assertSame($expIdentifier, $file
->getIdentifier());
}
public function testFile_construct_noRequest() {
$_REQUEST = $this->requestArr;
$file = new File($this->config);
$expIdentifier = sha1($this->requestArr['flowIdentifier']);
$this
->assertSame($expIdentifier, $file
->getIdentifier());
}
public function testFile_construct_getChunkPath() {
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$expPath = $this->vfs
->url() . DIRECTORY_SEPARATOR . sha1($this->requestArr['flowIdentifier']) . '_1';
$this
->assertSame($expPath, $file
->getChunkPath(1));
}
public function testFile_construct_checkChunk() {
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$this
->assertFalse($file
->checkChunk());
$chunkName = sha1($request
->getIdentifier()) . '_' . $request
->getCurrentChunkNumber();
$firstChunk = vfsStream::newFile($chunkName);
$this->vfs
->addChild($firstChunk);
$this
->assertTrue($file
->checkChunk());
}
public function testFile_validateChunk() {
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$this
->assertFalse($file
->validateChunk());
$fileInfo = new \ArrayObject();
$request = new Request($this->requestArr, $fileInfo);
$file = new File($this->config, $request);
$this
->assertFalse($file
->validateChunk());
$fileInfo
->exchangeArray(array(
'size' => 10,
'error' => UPLOAD_ERR_OK,
'tmp_name' => '',
));
$this
->assertTrue($file
->validateChunk());
$fileInfo
->exchangeArray(array(
'size' => 9,
'error' => UPLOAD_ERR_OK,
'tmp_name' => '',
));
$this
->assertFalse($file
->validateChunk());
$fileInfo
->exchangeArray(array(
'size' => 10,
'error' => UPLOAD_ERR_EXTENSION,
'tmp_name' => '',
));
$this
->assertFalse($file
->validateChunk());
}
public function testFile_validateFile() {
$this->requestArr['flowTotalSize'] = 10;
$this->requestArr['flowTotalChunks'] = 3;
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$chunkPrefix = sha1($request
->getIdentifier()) . '_';
$this
->assertFalse($file
->validateFile());
$firstChunk = vfsStream::newFile($chunkPrefix . '1');
$firstChunk
->setContent('123');
$this->vfs
->addChild($firstChunk);
$this
->assertFalse($file
->validateFile());
$secondChunk = vfsStream::newFile($chunkPrefix . '2');
$secondChunk
->setContent('456');
$this->vfs
->addChild($secondChunk);
$this
->assertFalse($file
->validateFile());
$lastChunk = vfsStream::newFile($chunkPrefix . '3');
$lastChunk
->setContent('7890');
$this->vfs
->addChild($lastChunk);
$this
->assertTrue($file
->validateFile());
$lastChunk
->setContent('789');
$this
->assertFalse($file
->validateFile());
$this->requestArr['flowTotalSize'] = 9;
$this
->assertTrue($file
->validateFile());
}
public function testFile_deleteChunks() {
$this->requestArr['flowTotalChunks'] = 4;
$fileInfo = new \ArrayObject();
$request = new Request($this->requestArr, $fileInfo);
$file = new File($this->config, $request);
$chunkPrefix = sha1($request
->getIdentifier()) . '_';
$firstChunk = vfsStream::newFile($chunkPrefix . 1);
$this->vfs
->addChild($firstChunk);
$secondChunk = vfsStream::newFile($chunkPrefix . 3);
$this->vfs
->addChild($secondChunk);
$thirdChunk = vfsStream::newFile('other');
$this->vfs
->addChild($thirdChunk);
$this
->assertTrue(file_exists($firstChunk
->url()));
$this
->assertTrue(file_exists($secondChunk
->url()));
$this
->assertTrue(file_exists($thirdChunk
->url()));
$file
->deleteChunks();
$this
->assertFalse(file_exists($firstChunk
->url()));
$this
->assertFalse(file_exists($secondChunk
->url()));
$this
->assertTrue(file_exists($thirdChunk
->url()));
}
public function testFile_saveChunk() {
$tmpDir = new vfsStreamDirectory('tmp');
$tmpFile = vfsStream::newFile('tmpFile');
$tmpFile
->setContent('1234567890');
$tmpDir
->addChild($tmpFile);
$this->vfs
->addChild($tmpDir);
$this->filesArr['file']['tmp_name'] = $tmpFile
->url();
$request = new Request($this->requestArr, $this->filesArr['file']);
$file = $this
->getMock('Flow\\File', array(
'_move_uploaded_file',
), array(
$this->config,
$request,
));
$file
->expects($this
->once())
->method('_move_uploaded_file')
->will($this
->returnCallback(function ($filename, $destination) {
return rename($filename, $destination);
}));
$expDstFile = $this->vfs
->url() . DIRECTORY_SEPARATOR . sha1($request
->getIdentifier()) . '_1';
$this
->assertFalse(file_exists($expDstFile));
$this
->assertTrue(file_exists($tmpFile
->url()));
$this
->assertTrue($file
->saveChunk());
$this
->assertTrue(file_exists($expDstFile));
$this
->assertSame('1234567890', file_get_contents($expDstFile));
}
public function testFile_save() {
$this->requestArr['flowTotalChunks'] = 3;
$this->requestArr['flowTotalSize'] = 10;
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$chunkPrefix = sha1($request
->getIdentifier()) . '_';
$chunk = vfsStream::newFile($chunkPrefix . '1', 0777);
$chunk
->setContent('0123');
$this->vfs
->addChild($chunk);
$chunk = vfsStream::newFile($chunkPrefix . '2', 0777);
$chunk
->setContent('456');
$this->vfs
->addChild($chunk);
$chunk = vfsStream::newFile($chunkPrefix . '3', 0777);
$chunk
->setContent('789');
$this->vfs
->addChild($chunk);
$filePath = $this->vfs
->url() . DIRECTORY_SEPARATOR . 'file';
$this
->assertTrue($file
->save($filePath));
$this
->assertTrue(file_exists($filePath));
$this
->assertEquals($request
->getTotalSize(), filesize($filePath));
}
public function testFile_save_lock() {
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$dstFile = $this->vfs
->url() . DIRECTORY_SEPARATOR . 'file';
$fh = fopen($dstFile, 'wb');
$this
->assertTrue(flock($fh, LOCK_EX));
try {
$file
->save($dstFile);
$this
->fail();
} catch (FileLockException $e) {
$this
->assertEquals('failed to lock file: ' . $dstFile, $e
->getMessage());
}
}
public function testFile_save_FileOpenException() {
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
try {
@$file
->save('not/existing/path');
$this
->fail();
} catch (FileOpenException $e) {
$this
->assertEquals('failed to open destination file: not/existing/path', $e
->getMessage());
}
}
public function testFile_save_chunk_FileOpenException() {
$this->requestArr['flowTotalChunks'] = 3;
$this->requestArr['flowTotalSize'] = 10;
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$chunkPrefix = sha1($request
->getIdentifier()) . '_';
$chunk = vfsStream::newFile($chunkPrefix . '1', 0777);
$chunk
->setContent('0123');
$this->vfs
->addChild($chunk);
$chunk = vfsStream::newFile($chunkPrefix . '2', 0777);
$chunk
->setContent('456');
$this->vfs
->addChild($chunk);
$missingChunk = $this->vfs
->url() . DIRECTORY_SEPARATOR . $chunkPrefix . '3';
$filePath = $this->vfs
->url() . DIRECTORY_SEPARATOR . 'file';
try {
@$file
->save($filePath);
} catch (FileOpenException $e) {
$this
->assertEquals('failed to open chunk: ' . $missingChunk, $e
->getMessage());
}
}
public function testFile_save_preProcess() {
$this->requestArr['flowTotalChunks'] = 1;
$this->requestArr['flowTotalSize'] = 10;
$processCalled = false;
$process = function ($chunk) use (&$processCalled) {
$processCalled = true;
};
$this->config
->setPreprocessCallback($process);
$request = new Request($this->requestArr);
$file = new File($this->config, $request);
$chunkPrefix = sha1($request
->getIdentifier()) . '_';
$chunk = vfsStream::newFile($chunkPrefix . '1', 0777);
$chunk
->setContent('1234567890');
$this->vfs
->addChild($chunk);
$filePath = $this->vfs
->url() . DIRECTORY_SEPARATOR . 'file';
$this
->assertTrue($file
->save($filePath));
$this
->assertTrue(file_exists($filePath));
$this
->assertEquals($request
->getTotalSize(), filesize($filePath));
$this
->assertTrue($processCalled);
}
}