Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="phpstan" version="1.12.4" installed="1.12.4" location="./tools/phpstan" copy="false"/>
<phar name="psalm" version="5.26.1" installed="5.26.1" location="./tools/psalm" copy="false"/>
<phar name="phpstan" version="2.1.19" installed="2.1.19" location="./tools/phpstan" copy="false"/>
</phive>
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
],
"require": {
"cakephp/orm": "^5.0",
"league/flysystem": "^3.15.1.0"
"league/flysystem": "^3.15.1"
},
"require-dev": {
"cakephp/cakephp": "^5.0",
"phpunit/phpunit": "^10.1.0",
"phpunit/phpunit": "^10.5.58 || ^11.5.3 || ^12.4",
"cakephp/cakephp-codesniffer": "^5.0",
"league/flysystem-memory": "^3.15",
"mikey179/vfsstream": "^1.6.10",
Expand Down
6 changes: 4 additions & 2 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0"?>
<ruleset name="CakePHP Core">
<config name="installed_paths" value="../../cakephp/cakephp-codesniffer" />
<ruleset name="FriendsOfCake Upload">
<file>config/</file>
<file>src/</file>
<file>tests/</file>

<rule ref="CakePHP" />

Expand Down
1 change: 0 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<coverage/>
<php>
<ini name="memory_limit" value="-1"/>
<ini name="apc.enable_cli" value="1"/>
<env name="FIXTURE_SCHEMA_METADATA" value="./tests/schema.php"/>
</php>
<!-- Add any additional test suites you want to run here -->
Expand Down
4 changes: 4 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@
<directory name="vendor" />
</ignoreFiles>
</projectFiles>

<issueHandlers>
<MissingOverrideAttribute errorLevel="info" />
</issueHandlers>
</psalm>
1 change: 1 addition & 0 deletions tests/Stub/ChildBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
class ChildBehavior extends UploadBehavior
{
protected array $_defaultConfig = ['key' => 'value'];
public array $constructedFiles;

public function constructFiles(
EntityInterface $entity,
Expand Down
115 changes: 64 additions & 51 deletions tests/TestCase/File/Path/Basepath/DefaultTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,87 @@
namespace Josegonzalez\Upload\Test\TestCase\File\Path\Basepath;

use Cake\TestSuite\TestCase;
use Josegonzalez\Upload\File\Path\Basepath\DefaultTrait;

class DefaultTraitTest extends TestCase
{
private function createTraitMock()
{
return new class {
use DefaultTrait;

public $entity;
public $table;
public $settings;
public $data;
public $field;
};
}

public function testNoSpecialConfiguration()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->settings = [];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->exactly(0))->method('get')->will($this->returnValue(1));
$mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table'));
$mock->table->expects($this->exactly(0))->method('getPrimaryKey')->will($this->returnValue('id'));
$mock->table->expects($this->once())->method('getAlias')->willReturn('Table');
$this->assertEquals('webroot/files/Table/field/', $mock->basepath());
}

public function testCustomPath()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}-{field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->exactly(0))->method('get')->will($this->returnValue(1));
$mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table'));
$mock->table->expects($this->exactly(0))->method('getPrimaryKey')->will($this->returnValue('id'));
$mock->table->expects($this->once())->method('getAlias')->willReturn('Table');
$this->assertEquals('webroot/files/Table-field/', $mock->basepath());
}

public function testExistingEntityWithPrimaryKey()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock = $this->createTraitMock();
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}-{field}{DS}{primaryKey}/'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->once())->method('get')->will($this->returnValue(1));
$mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table'));
$mock->table->expects($this->exactly(2))->method('getPrimaryKey')->will($this->returnValue('id'));
$mock->entity->expects($this->once())->method('get')->willReturn(1);
$mock->table->expects($this->once())->method('getAlias')->willReturn('Table');
$mock->table->expects($this->exactly(2))->method('getPrimaryKey')->willReturn('id');
$this->assertEquals('webroot/files/Table-field/1/', $mock->basepath());
}

public function testNewEntity()
{
$this->expectException('LogicException', '{primaryKey} substitution not allowed for new entities');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock = $this->createTraitMock();
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}-{field}{DS}{primaryKey}/'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->once())->method('isNew')->will($this->returnValue(true));
$mock->entity->expects($this->once())->method('isNew')->willReturn(true);
$mock->basepath();
}

public function testExitingEntityWithCompositePrimaryKey()
{
$this->expectException('LogicException', '{primaryKey} substitution not valid for composite primary keys');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock = $this->createTraitMock();
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}-{field}{DS}{primaryKey}/'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->once())->method('isNew')->will($this->returnValue(false));
$mock->table->expects($this->once())->method('getPrimaryKey')->will($this->returnValue(['id', 'other_id']));
$mock->entity->expects($this->once())->method('isNew')->willReturn(false);
$mock->table->expects($this->once())->method('getPrimaryKey')->willReturn(['id', 'other_id']);
$mock->basepath();
}

Expand All @@ -83,22 +93,21 @@ public function testExitingEntityWithCompositePrimaryKey()
*/
public function testPathWithoutPrimaryKey()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}-{field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->table->expects($this->exactly(0))->method('getPrimaryKey')->will($this->returnValue(['id', 'other_id']));
$mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table'));
$mock->table->expects($this->once())->method('getAlias')->willReturn('Table');
$this->assertEquals('webroot/files/Table-field/', $mock->basepath());
}

public function testYearWithMonthPath()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{year}{DS}{month}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
Expand All @@ -108,9 +117,9 @@ public function testYearWithMonthPath()

public function testYearWithMonthAndDayPath()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{year}{DS}{month}{DS}{day}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
Expand All @@ -120,15 +129,14 @@ public function testYearWithMonthAndDayPath()

public function testModelFieldYearWithMonthAndDayPath()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field}{DS}{year}{DS}{month}{DS}{day}{DS}'];

$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->exactly(0))->method('get')->will($this->returnValue(1));
$mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table'));
$mock->table->expects($this->once())->method('getAlias')->willReturn('Table');

$this->assertEquals('webroot/files/Table/field/' . date('Y') . '/' . date('m') . '/' . date('d') . '/', $mock->basepath());
}
Expand All @@ -137,54 +145,59 @@ public function testFieldValueMissing()
{
$this->expectException('LogicException', 'Field value for substitution is missing: field');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$entity = $this->createStub('Cake\ORM\Entity');
$entity->method('get')->willReturn(null);
$mock->entity = $entity;
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue(null));
$mock->basepath();
}

public function testFieldValueNonScalar()
{
$this->expectException('LogicException', 'Field value for substitution must be a integer, float, string or boolean: field');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$entity = $this->createStub('Cake\ORM\Entity');
$entity->method('get')->willReturn([]);
$mock->entity = $entity;
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue([]));
$mock->basepath();
}

public function testFieldValueZeroLength()
{
$this->expectException('LogicException', 'Field value for substitution must be non-zero in length: field');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$entity = $this->createStub('Cake\ORM\Entity');
$entity->method('get')->willReturn('');
$mock->entity = $entity;
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue(''));
$mock->basepath();
}

public function testFieldValue()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$entity = $this->createStub('Cake\ORM\Entity');
$entity->method('get')->willReturn('value');
$table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$table->expects($this->once())->method('getAlias')->willReturn('Table');
$mock->entity = $entity;
$mock->table = $table;
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue('value'));
$mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table'));
$this->assertEquals('webroot/files/Table/value/', $mock->basepath());
}
}
4 changes: 2 additions & 2 deletions tests/TestCase/File/Path/DefaultProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class DefaultProcessorTest extends TestCase
{
public function testIsProcessorInterface()
{
$entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$entity = $this->createStub('Cake\ORM\Entity');
$table = $this->createStub('Cake\ORM\Table');
$data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK);
$field = 'field';
$settings = [];
Expand Down
24 changes: 19 additions & 5 deletions tests/TestCase/File/Path/Filename/DefaultTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,41 @@
namespace Josegonzalez\Upload\Test\TestCase\File\Path\Filename;

use Cake\TestSuite\TestCase;
use Josegonzalez\Upload\File\Path\Filename\DefaultTrait;
use Laminas\Diactoros\UploadedFile;

class DefaultTraitTest extends TestCase
{
private function createTraitMock()
{
return new class {
use DefaultTrait;

public $entity;
public $table;
public $settings;
public $data;
public $field;
};
}

public function testFilename()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait');
$mock = $this->createTraitMock();
$mock->settings = [];
$mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename');
$this->assertEquals('filename', $mock->filename());

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait');
$mock = $this->createTraitMock();
$mock->settings = [
'nameCallback' => 'not_callable',
];
$mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename');
$this->assertEquals('filename', $mock->filename());

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait');
$mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$mock = $this->createTraitMock();
$mock->entity = $this->createStub('Cake\ORM\Entity');
$mock->table = $this->createStub('Cake\ORM\Table');
$mock->field = 'field';
$mock->settings = [
'nameCallback' => function ($table, $entity, $data, $field, $settings) {
Expand Down
7 changes: 5 additions & 2 deletions tests/TestCase/File/Transformer/DefaultTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@

class DefaultTransformerTest extends TestCase
{
protected UploadedFile $uploadedFile;
protected DefaultTransformer $transformer;

public function setUp(): void
{
$entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock();
$table = $this->getMockBuilder('Cake\ORM\Table')->getMock();
$entity = $this->createStub('Cake\ORM\Entity');
$table = $this->createStub('Cake\ORM\Table');
$this->uploadedFile = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'foo.txt');

$field = 'field';
Expand Down
Loading