silverstripe-framework/tests/forms/uploadfield/UploadFieldTest.php

917 lines
34 KiB
PHP
Raw Normal View History

<?php
/**
* @package framework
* @subpackage tests
*/
class UploadFieldTest extends FunctionalTest {
static $fixture_file = 'UploadFieldTest.yml';
protected $extraDataObjects = array('UploadFieldTest_Record');
protected $requiredExtensions = array(
'File' => array('UploadFieldTest_FileExtension')
);
public function testUploadNoRelation() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$tmpFileName = 'testUploadBasic.txt';
$_FILES = array('NoRelationField' => $this->getUploadFile($tmpFileName));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/NoRelationField/upload',
array('NoRelationField' => $this->getUploadFile($tmpFileName))
);
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertTrue(is_object($uploadedFile), 'The file object is created');
}
public function testUploadHasOneRelation() {
$this->loginWithPermission('ADMIN');
// Unset existing has_one relation before re-uploading
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$record->HasOneFileID = null;
$record->write();
$tmpFileName = 'testUploadHasOneRelation.txt';
$_FILES = array('HasOneFile' => $this->getUploadFile($tmpFileName));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasOneFile/upload',
array('HasOneFile' => $this->getUploadFile($tmpFileName))
);
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertTrue(is_object($uploadedFile), 'The file object is created');
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertTrue($record->HasOneFile()->exists());
$this->assertEquals($record->HasOneFile()->Name, $tmpFileName);
}
public function testUploadHasOneRelationWithExtendedFile() {
$this->loginWithPermission('ADMIN');
// Unset existing has_one relation before re-uploading
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$record->HasOneExtendedFileID = null;
$record->write();
$tmpFileName = 'testUploadHasOneRelationWithExtendedFile.txt';
$_FILES = array('HasOneExtendedFile' => $this->getUploadFile($tmpFileName));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasOneExtendedFile/upload',
array('HasOneExtendedFile' => $this->getUploadFile($tmpFileName))
);
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('UploadFieldTest_ExtendedFile', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertTrue(is_object($uploadedFile), 'The file object is created');
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertTrue($record->HasOneExtendedFile()->exists(), 'The extended file is attached to the class');
$this->assertEquals($record->HasOneExtendedFile()->Name, $tmpFileName, 'Proper file has been attached');
}
public function testUploadHasManyRelation() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$tmpFileName = 'testUploadHasManyRelation.txt';
$_FILES = array('HasManyFiles' => $this->getUploadFile($tmpFileName));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFiles/upload',
array('HasManyFiles' => $this->getUploadFile($tmpFileName))
);
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertTrue(is_object($uploadedFile), 'The file object is created');
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals(3, $record->HasManyFiles()->Count());
$this->assertEquals($record->HasManyFiles()->Last()->Name, $tmpFileName);
}
public function testUploadManyManyRelation() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$relationCount = $record->ManyManyFiles()->Count();
$tmpFileName = 'testUploadManyManyRelation.txt';
$_FILES = array('ManyManyFiles' => $this->getUploadFile($tmpFileName));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/ManyManyFiles/upload',
array('ManyManyFiles' => $this->getUploadFile($tmpFileName))
);
$this->assertFalse($response->isError());
$this->assertFileExists(ASSETS_PATH . "/UploadFieldTest/$tmpFileName");
$uploadedFile = DataObject::get_one('File', sprintf('"Name" = \'%s\'', $tmpFileName));
$this->assertTrue(is_object($uploadedFile), 'The file object is created');
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals($relationCount+1, $record->ManyManyFiles()->Count());
$this->assertEquals($record->ManyManyFiles()->Last()->Name, $tmpFileName);
}
/**
* Partially covered by {@link UploadTest->testUploadAcceptsAllowedExtension()},
* but this test additionally verifies that those constraints are actually enforced
* in this controller method.
*/
public function testAllowedExtensions() {
$this->loginWithPermission('ADMIN');
$invalidFile = 'invalid.php';
$_FILES = array('AllowedExtensionsField' => $this->getUploadFile($invalidFile));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/AllowedExtensionsField/upload',
array('AllowedExtensionsField' => $this->getUploadFile($invalidFile))
);
$this->assertTrue($response->isError());
$this->assertContains('Extension is not allowed', $response->getBody());
$validFile = 'valid.jpg';
$_FILES = array('AllowedExtensionsField' => $this->getUploadFile($validFile));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/AllowedExtensionsField/upload',
array('AllowedExtensionsField' => $this->getUploadFile($validFile))
);
$this->assertFalse($response->isError());
$this->assertNotContains('Extension is not allowed', $response->getBody());
}
public function testAllowedMaxFileNumberWithHasOne() {
$this->loginWithPermission('ADMIN');
// Test each of the three cases - has one with no max filel limit, has one with a limit of
// one, has one with a limit of more than one (makes no sense, but should test it anyway).
// Each of them should public function in the same way - attaching the first file should work, the
// second should cause an error.
foreach (array('HasOneFile', 'HasOneFileMaxOne', 'HasOneFileMaxTwo') as $recordName) {
// Unset existing has_one relation before re-uploading
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$record->{$recordName . 'ID'} = null;
$record->write();
$tmpFileName = 'testUploadHasOneRelation.txt';
$_FILES = array($recordName => $this->getUploadFile($tmpFileName));
$response = $this->post(
"UploadFieldTest_Controller/Form/field/$recordName/upload",
array($recordName => $this->getUploadFile($tmpFileName))
);
$body = json_decode($response->getBody());
$this->assertEquals(0, $body[0]->error);
// Write to it again, should result in an error.
$response = $this->post(
"UploadFieldTest_Controller/Form/field/$recordName/upload",
array($recordName => $this->getUploadFile($tmpFileName))
);
$body = json_decode($response->getBody());
$this->assertNotEquals(0, $body[0]->error);
}
}
public function testAllowedMaxFileNumberWithHasMany() {
$this->loginWithPermission('ADMIN');
// The 'HasManyFilesMaxTwo' field has a maximum of two files able to be attached to it.
// We want to add files to it until we attempt to add the third. We expect that the first
// two should work and the third will fail.
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$record->HasManyFilesMaxTwo()->removeAll();
$tmpFileName = 'testUploadHasManyRelation.txt';
$_FILES = array('HasManyFilesMaxTwo' => $this->getUploadFile($tmpFileName));
// Write the first element, should be okay.
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFilesMaxTwo/upload',
array('HasManyFilesMaxTwo' => $this->getUploadFile($tmpFileName))
);
$body = json_decode($response->getBody());
$this->assertEquals(0, $body[0]->error);
// Write the second element, should be okay.
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFilesMaxTwo/upload',
array('HasManyFilesMaxTwo' => $this->getUploadFile($tmpFileName))
);
$body = json_decode($response->getBody());
$this->assertEquals(0, $body[0]->error);
// Write the third element, should result in error.
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFilesMaxTwo/upload',
array('HasManyFilesMaxTwo' => $this->getUploadFile($tmpFileName))
);
$body = json_decode($response->getBody());
$this->assertNotEquals(0, $body[0]->error);
}
public function testRemoveFromHasOne() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file1 = $this->objFromFixture('File', 'file1');
$this->assertTrue($record->HasOneFile()->exists());
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasOneFile/item/' . $file1->ID . '/remove',
array()
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertFalse($record->HasOneFile()->exists());
$this->assertFileExists($file1->FullPath, 'File is only detached, not deleted from filesystem');
}
public function testRemoveFromHasMany() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file2 = $this->objFromFixture('File', 'file2');
$file3 = $this->objFromFixture('File', 'file3');
$this->assertEquals(array('File2', 'File3'), $record->HasManyFiles()->column('Title'));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFiles/item/' . $file2->ID . '/remove',
array()
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals(array('File3'), $record->HasManyFiles()->column('Title'));
$this->assertFileExists($file3->FullPath, 'File is only detached, not deleted from filesystem');
}
public function testRemoveFromManyMany() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4');
$file5 = $this->objFromFixture('File', 'file5');
$this->assertContains('File4', $record->ManyManyFiles()->column('Title'));
$this->assertContains('File5', $record->ManyManyFiles()->column('Title'));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/ManyManyFiles/item/' . $file4->ID . '/remove',
array()
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertNotContains('File4', $record->ManyManyFiles()->column('Title'));
$this->assertContains('File5', $record->ManyManyFiles()->column('Title'));
$this->assertFileExists($file4->FullPath, 'File is only detached, not deleted from filesystem');
}
public function testDeleteFromHasOne() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file1 = $this->objFromFixture('File', 'file1');
$this->assertTrue($record->HasOneFile()->exists());
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasOneFile/item/' . $file1->ID . '/delete',
array()
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertFalse($record->HasOneFile()->exists());
$this->assertFileNotExists($file1->FullPath, 'File is also removed from filesystem');
}
public function testDeleteFromHasMany() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file2 = $this->objFromFixture('File', 'file2');
$file3 = $this->objFromFixture('File', 'file3');
$this->assertEquals(array('File2', 'File3'), $record->HasManyFiles()->column('Title'));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFiles/item/' . $file2->ID . '/delete',
array()
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals(array('File3'), $record->HasManyFiles()->column('Title'));
$this->assertFileNotExists($file2->FullPath, 'File is also removed from filesystem');
$fileNotOnRelationship = $this->objFromFixture('File', 'file1');
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFiles/item/' . $fileNotOnRelationship->ID . '/delete',
array()
);
$this->assertEquals(403, $response->getStatusCode(),
"Denies deleting files if they're not on the current relationship");
}
public function testDeleteFromManyMany() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4');
$file5 = $this->objFromFixture('File', 'file5');
$fileNoDelete = $this->objFromFixture('File', 'file-nodelete');
$this->assertContains('File4', $record->ManyManyFiles()->column('Title'));
$this->assertContains('File5', $record->ManyManyFiles()->column('Title'));
$response = $this->post(
'UploadFieldTest_Controller/Form/field/ManyManyFiles/item/' . $file4->ID . '/delete',
array()
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertNotContains('File4', $record->ManyManyFiles()->column('Title'));
$this->assertContains('File5', $record->ManyManyFiles()->column('Title'));
$this->assertFileNotExists($file4->FullPath, 'File is also removed from filesystem');
// Test record-based permissions
$response = $this->post(
'UploadFieldTest_Controller/Form/field/ManyManyFiles/item/' . $fileNoDelete->ID . '/delete',
array()
);
$this->assertEquals(403, $response->getStatusCode());
}
public function testView() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4');
$file5 = $this->objFromFixture('File', 'file5');
$fileNoView = $this->objFromFixture('File', 'file-noview');
$fileNoEdit = $this->objFromFixture('File', 'file-noedit');
$fileNoDelete = $this->objFromFixture('File', 'file-nodelete');
$response = $this->get('UploadFieldTest_Controller');
$this->assertFalse($response->isError());
$parser = new CSSContentParser($response->getBody());
$items = $parser->getBySelector('#ManyManyFiles .ss-uploadfield-files .ss-uploadfield-item');
$ids = array();
foreach($items as $item) $ids[] = (int)$item['data-fileid'];
$this->assertContains($file4->ID, $ids, 'Views related file');
$this->assertContains($file5->ID, $ids, 'Views related file');
$this->assertNotContains($fileNoView->ID, $ids, "Doesn't view files without view permissions");
$this->assertContains($fileNoEdit->ID, $ids, "Views files without edit permissions");
$this->assertContains($fileNoDelete->ID, $ids, "Views files without delete permissions");
}
public function testEdit() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4');
$file5 = $this->objFromFixture('File', 'file5');
$fileNoEdit = $this->objFromFixture('File', 'file-noedit');
$baseUrl = 'UploadFieldTest_Controller/Form/field/ManyManyFiles/item/' . $file4->ID;
$response = $this->get($baseUrl . '/edit');
$this->assertFalse($response->isError());
$response = $this->post($baseUrl . '/EditForm', array('Title' => 'File 4 modified'));
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$file4 = DataObject::get_by_id($file4->class, $file4->ID, false);
$this->assertEquals('File 4 modified', $file4->Title);
// Test record-based permissions
$response = $this->post(
'UploadFieldTest_Controller/Form/field/ManyManyFiles/item/' . $fileNoEdit->ID . '/edit',
array()
);
$this->assertEquals(403, $response->getStatusCode());
}
public function testGetRecord() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$form = $this->getMockForm();
$field = new UploadField('MyField');
$field->setForm($form);
$this->assertNull($field->getRecord(), 'Returns no record by default');
$field = new UploadField('MyField');
$field->setForm($form);
$form->loadDataFrom($record);
$this->assertEquals($record, $field->getRecord(), 'Returns record from form if available');
$field = new UploadField('MyField');
$field->setForm($form);
$field->setRecord($record);
$this->assertEquals($record, $field->getRecord(), 'Returns record when set explicitly');
}
public function testSetItems() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$form = $this->getMockForm();
$items = new ArrayList(array(
$this->objFromFixture('File', 'file1'),
$this->objFromFixture('File', 'file2')
));
// Anonymous field
$field = new UploadField('MyField');
$field->setForm($form);
$field->setRecord($record);
$field->setItems($items);
$this->assertEquals(array('File1', 'File2'), $field->getItems()->column('Title'));
// Field with has_one auto-detected
$field = new UploadField('HasOneFile');
$field->setForm($form);
$field->setRecord($record);
$field->setItems($items);
$this->assertEquals(array('File1', 'File2'), $field->getItems()->column('Title'),
'Allows overwriting of items even when relationship is detected'
);
}
public function testGetItems() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$form = $this->getMockForm();
// Anonymous field
$field = new UploadField('MyField');
$field->setForm($form);
$field->setRecord($record);
$this->assertEquals(array(), $field->getItems()->column('Title'));
// Field with has_one auto-detected
$field = new UploadField('HasOneFile');
$field->setForm($form);
$field->setRecord($record);
$this->assertEquals(array('File1'), $field->getItems()->column('Title'));
// Field with has_many auto-detected
$field = new UploadField('HasManyFiles');
$field->setForm($form);
$field->setRecord($record);
$this->assertEquals(array('File2', 'File3'), $field->getItems()->column('Title'));
// Field with many_many auto-detected
$field = new UploadField('ManyManyFiles');
$field->setForm($form);
$field->setRecord($record);
$this->assertNotContains('File1',$field->getItems()->column('Title'));
$this->assertNotContains('File2',$field->getItems()->column('Title'));
$this->assertNotContains('File3',$field->getItems()->column('Title'));
$this->assertContains('File4',$field->getItems()->column('Title'));
$this->assertContains('File5',$field->getItems()->column('Title'));
}
public function testReadonly() {
$this->loginWithPermission('ADMIN');
$response = $this->get('UploadFieldTest_Controller');
$this->assertFalse($response->isError());
$parser = new CSSContentParser($response->getBody());
$this->assertFalse((bool)$parser->getBySelector(
'#ReadonlyField .ss-uploadfield-files .ss-uploadfield-item .ss-ui-button'),
'Removes all buttons on items');
$this->assertFalse((bool)$parser->getBySelector('#ReadonlyField .ss-uploadfield-dropzone'),
'Removes dropzone');
$this->assertFalse((bool)$parser->getBySelector(
'#ReadonlyField .ss-uploadfield-addfile .ss-ui-button'),
'Removes all buttons from "add" area');
}
public function testDisabled() {
$this->loginWithPermission('ADMIN');
$response = $this->get('UploadFieldTest_Controller');
$this->assertFalse($response->isError());
$parser = new CSSContentParser($response->getBody());
$this->assertFalse(
(bool)$parser->getBySelector('#DisabledField .ss-uploadfield-files .ss-uploadfield-item .ss-ui-button'),
'Removes all buttons on items');
$this->assertFalse((bool)$parser->getBySelector('#DisabledField .ss-uploadfield-dropzone'),
'Removes dropzone');
$this->assertFalse(
(bool)$parser->getBySelector('#DisabledField .ss-uploadfield-addfile .ss-ui-button'),
'Removes all buttons from "add" area');
}
public function testCanUpload() {
$this->loginWithPermission('ADMIN');
$response = $this->get('UploadFieldTest_Controller');
$this->assertFalse($response->isError());
$parser = new CSSContentParser($response->getBody());
$this->assertFalse((bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-dropzone'),
'Removes dropzone');
$this->assertTrue(
(bool)$parser->getBySelector('#CanUploadFalseField .ss-uploadfield-fromfiles'),
'Keeps "From files" button'
);
}
public function testCanUploadWithPermissionCode() {
$field = new UploadField('MyField');
$field->setConfig('canUpload', true);
$this->assertTrue($field->canUpload());
$field->setConfig('canUpload', false);
$this->assertFalse($field->canUpload());
$this->loginWithPermission('ADMIN');
$field->setConfig('canUpload', false);
$this->assertFalse($field->canUpload());
$field->setConfig('canUpload', 'ADMIN');
$this->assertTrue($field->canUpload());
}
public function testCanAttachExisting() {
$this->loginWithPermission('ADMIN');
$response = $this->get('UploadFieldTest_Controller');
$this->assertFalse($response->isError());
$parser = new CSSContentParser($response->getBody());
$this->assertTrue(
(bool)$parser->getBySelector('#CanAttachExistingFalseField .ss-uploadfield-fromcomputer-fileinput'),
'Keeps input file control'
);
$this->assertFalse(
(bool)$parser->getBySelector('#CanAttachExistingFalseField .ss-uploadfield-fromfiles'),
'Removes "From files" button'
);
}
public function testIsSaveable() {
$form = $this->getMockForm();
$field = new UploadField('MyField');
$this->assertTrue($field->isSaveable(), 'Field without relation is always marked as saveable');
$field = new UploadField('HasOneFile');
$this->assertTrue($field->isSaveable(), 'Field with has_one relation is saveable without record on form');
$field = new UploadField('HasOneFile');
$newRecord = new UploadFieldTest_Record();
$form->loadDataFrom($newRecord);
$field->setForm($form);
$this->assertFalse($field->isSaveable(), 'Field with has_one relation not saveable with new record on form');
$field = new UploadField('HasOneFile');
$existingRecord = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$form->loadDataFrom($existingRecord);
$field->setForm($form);
$this->assertTrue($field->isSaveable(), 'Field with has_one relation saveable with saved record on form');
}
public function testSelect() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4');
$file5 = $this->objFromFixture('File', 'file5');
$fileSubfolder = $this->objFromFixture('File', 'file-subfolder');
$fileNoEdit = $this->objFromFixture('File', 'file-noedit');
$response = $this->get('UploadFieldTest_Controller/Form/field/ManyManyFiles/select/');
$this->assertFalse($response->isError());
// A bit too much coupling with GridField, but a full template overload would make things too complex
$parser = new CSSContentParser($response->getBody());
$items = $parser->getBySelector('.ss-gridfield-item');
$itemIDs = array_map(create_function('$el', 'return (int)$el["data-id"];'), $items);
$this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder');
$this->assertNotContains($fileSubfolder->ID, $itemIDs, 'Does not contain file in subfolder');
}
public function testAttachHasOne() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file1 = $this->objFromFixture('File', 'file1');
$file2 = $this->objFromFixture('File', 'file2');
$file3AlreadyAttached = $this->objFromFixture('File', 'file3');
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasOneFile/attach',
array('ids' => array($file1->ID/* first file should be ignored */, $file2->ID))
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertEquals($file2->ID, $record->HasOneFileID, 'Attaches new relations');
}
public function testAttachHasMany() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file1 = $this->objFromFixture('File', 'file1');
$file2 = $this->objFromFixture('File', 'file2');
$file3AlreadyAttached = $this->objFromFixture('File', 'file3');
$response = $this->post(
'UploadFieldTest_Controller/Form/field/HasManyFiles/attach',
array('ids' => array($file1->ID, $file2->ID))
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertContains($file1->ID, $record->HasManyFiles()->column('ID'),
'Attaches new relations');
$this->assertContains($file2->ID, $record->HasManyFiles()->column('ID'),
'Attaches new relations');
$this->assertContains($file3AlreadyAttached->ID, $record->HasManyFiles()->column('ID'),
'Does not detach existing relations');
}
public function testAttachManyMany() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file1 = $this->objFromFixture('File', 'file1');
$file2 = $this->objFromFixture('File', 'file2');
$file5AlreadyAttached = $this->objFromFixture('File', 'file5');
$response = $this->post(
'UploadFieldTest_Controller/Form/field/ManyManyFiles/attach',
array('ids' => array($file1->ID, $file2->ID))
);
$this->assertFalse($response->isError());
$record = DataObject::get_by_id($record->class, $record->ID, false);
$this->assertContains($file1->ID, $record->ManyManyFiles()->column('ID'),
'Attaches new relations');
$this->assertContains($file2->ID, $record->ManyManyFiles()->column('ID'),
'Attaches new relations');
$this->assertContains($file5AlreadyAttached->ID, $record->ManyManyFiles()->column('ID'),
'Does not detach existing relations');
}
public function testManagesRelation() {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$field = new UploadField('ManyManyFiles');
$this->assertFalse($field->managesRelation(), 'False if no record is set');
$field = new UploadField('NoRelationField');
$field->setRecord($record);
$this->assertFalse($field->managesRelation(), 'False if no relation found by name');
$field = new UploadField('HasOneFile');
$field->setRecord($record);
$this->assertTrue($field->managesRelation(), 'True for has_one');
$field = new UploadField('HasManyFiles');
$field->setRecord($record);
$this->assertTrue($field->managesRelation(), 'True for has_many');
$field = new UploadField('ManyManyFiles');
$field->setRecord($record);
$this->assertTrue($field->managesRelation(), 'True for many_many');
}
protected function getMockForm() {
return new Form(new Controller(), 'Form', new FieldList(), new FieldList());
}
/**
* @return Array Emulating an entry in the $_FILES superglobal
*/
protected function getUploadFile($tmpFileName = 'UploadFieldTest-testUpload.txt') {
$tmpFilePath = TEMP_FOLDER . '/' . $tmpFileName;
$tmpFileContent = '';
for($i=0; $i<10000; $i++) $tmpFileContent .= '0';
file_put_contents($tmpFilePath, $tmpFileContent);
// emulates the $_FILES array
return array(
'name' => $tmpFileName,
'type' => 'text/plaintext',
'size' => filesize($tmpFilePath),
'tmp_name' => $tmpFilePath,
'extension' => 'txt',
'error' => UPLOAD_ERR_OK,
);
}
public function setUp() {
parent::setUp();
if(!file_exists(ASSETS_PATH)) mkdir(ASSETS_PATH);
/* Create a test folders for each of the fixture references */
$folderIDs = $this->allFixtureIDs('Folder');
foreach($folderIDs as $folderID) {
$folder = DataObject::get_by_id('Folder', $folderID);
if(!file_exists(BASE_PATH."/$folder->Filename")) mkdir(BASE_PATH."/$folder->Filename");
}
/* Create a test files for each of the fixture references */
$fileIDs = $this->allFixtureIDs('File');
foreach($fileIDs as $fileID) {
$file = DataObject::get_by_id('File', $fileID);
$fh = fopen(BASE_PATH."/$file->Filename", "w");
fwrite($fh, str_repeat('x',1000000));
fclose($fh);
}
}
public function tearDown() {
parent::tearDown();
/* Remove the test files that we've created */
$fileIDs = $this->allFixtureIDs('File');
foreach($fileIDs as $fileID) {
$file = DataObject::get_by_id('File', $fileID);
if($file && file_exists(BASE_PATH."/$file->Filename")) unlink(BASE_PATH."/$file->Filename");
}
/* Remove the test folders that we've crated */
$folderIDs = $this->allFixtureIDs('Folder');
foreach($folderIDs as $folderID) {
$folder = DataObject::get_by_id('Folder', $folderID);
if($folder && file_exists(BASE_PATH."/$folder->Filename")) {
Filesystem::removeFolder(BASE_PATH."/$folder->Filename");
}
}
// Remove left over folders and any files that may exist
if(file_exists('../assets/UploadFieldTest')) Filesystem::removeFolder('../assets/UploadFieldTest');
}
}
class UploadFieldTest_Record extends DataObject implements TestOnly {
static $db = array(
'Title' => 'Text',
);
static $has_one = array(
'HasOneFile' => 'File',
'HasOneFileMaxOne' => 'File',
'HasOneFileMaxTwo' => 'File',
'HasOneExtendedFile' => 'UploadFieldTest_ExtendedFile'
);
static $has_many = array(
'HasManyFiles' => 'File',
'HasManyFilesMaxTwo' => 'File',
);
static $many_many = array(
'ManyManyFiles' => 'File',
);
}
class UploadFieldTest_FileExtension extends DataExtension implements TestOnly {
public static $has_one = array(
'Record' => 'UploadFieldTest_Record'
);
public function canDelete($member = null) {
if($this->owner->Name == 'nodelete.txt') return false;
}
public function canEdit($member = null) {
if($this->owner->Name == 'noedit.txt') return false;
}
public function canView($member = null) {
if($this->owner->Name == 'noview.txt') return false;
}
}
class UploadFieldTest_Controller extends Controller implements TestOnly {
protected $template = 'BlankPage';
public function Form() {
$record = DataObject::get_one('UploadFieldTest_Record', '"Title" = \'Record 1\'');
$fieldNoRelation = new UploadField('NoRelationField');
$fieldNoRelation->setFolderName('UploadFieldTest');
$fieldNoRelation->setRecord($record);
$fieldHasOne = new UploadField('HasOneFile');
$fieldHasOne->setFolderName('UploadFieldTest');
$fieldHasOne->setRecord($record);
$fieldHasOneExtendedFile = new UploadField('HasOneExtendedFile');
$fieldHasOneExtendedFile->setFolderName('UploadFieldTest');
$fieldHasOneExtendedFile->setRecord($record);
$fieldHasOneMaxOne = new UploadField('HasOneFileMaxOne');
$fieldHasOneMaxOne->setFolderName('UploadFieldTest');
$fieldHasOneMaxOne->setConfig('allowedMaxFileNumber', 1);
$fieldHasOneMaxOne->setRecord($record);
$fieldHasOneMaxTwo = new UploadField('HasOneFileMaxTwo');
$fieldHasOneMaxTwo->setFolderName('UploadFieldTest');
$fieldHasOneMaxTwo->setConfig('allowedMaxFileNumber', 2);
$fieldHasOneMaxTwo->setRecord($record);
$fieldHasMany = new UploadField('HasManyFiles');
$fieldHasMany->setFolderName('UploadFieldTest');
$fieldHasMany->setRecord($record);
$fieldHasManyMaxTwo = new UploadField('HasManyFilesMaxTwo');
$fieldHasManyMaxTwo->setFolderName('UploadFieldTest');
$fieldHasManyMaxTwo->setConfig('allowedMaxFileNumber', 2);
$fieldHasManyMaxTwo->setRecord($record);
$fieldManyMany = new UploadField('ManyManyFiles');
$fieldManyMany->setFolderName('UploadFieldTest');
$fieldManyMany->setRecord($record);
$fieldReadonly = new UploadField('ReadonlyField');
$fieldReadonly->setFolderName('UploadFieldTest');
$fieldReadonly->setRecord($record);
$fieldReadonly = $fieldReadonly->performReadonlyTransformation();
$fieldDisabled = new UploadField('DisabledField');
$fieldDisabled->setFolderName('UploadFieldTest');
$fieldDisabled->setRecord($record);
$fieldDisabled = $fieldDisabled->performDisabledTransformation();
$fieldSubfolder = new UploadField('SubfolderField');
$fieldSubfolder->setFolderName('UploadFieldTest/subfolder1');
$fieldSubfolder->setRecord($record);
$fieldCanUploadFalse = new UploadField('CanUploadFalseField');
$fieldCanUploadFalse->setConfig('canUpload', false);
$fieldCanUploadFalse->setRecord($record);
$fieldCanAttachExisting = new UploadField('CanAttachExistingFalseField');
$fieldCanAttachExisting->setConfig('canAttachExisting', false);
$fieldCanAttachExisting->setRecord($record);
$fieldAllowedExtensions = new UploadField('AllowedExtensionsField');
$fieldAllowedExtensions->getValidator()->setAllowedExtensions(array('jpg'));
$form = new Form(
$this,
'Form',
new FieldList(
$fieldNoRelation,
$fieldHasOne,
$fieldHasOneMaxOne,
$fieldHasOneMaxTwo,
$fieldHasOneExtendedFile,
$fieldHasMany,
$fieldHasManyMaxTwo,
$fieldManyMany,
$fieldReadonly,
$fieldDisabled,
$fieldSubfolder,
$fieldCanUploadFalse,
$fieldCanAttachExisting,
$fieldAllowedExtensions
),
new FieldList(
new FormAction('submit')
),
new RequiredFields(
'NoRelationField',
'HasOneFile',
'HasOneFileMaxOne',
'HasOneFileMaxTwo',
'HasOneExtendedFile',
'HasManyFiles',
'HasManyFilesMaxTwo',
'ManyManyFiles',
'ReadonlyField',
'DisabledField',
'SubfolderField',
'CanUploadFalseField',
'CanAttachExistingField'
)
);
return $form;
}
public function submit($data, $form) {
}
}
/**
* Used for testing the create-on-upload
*/
class UploadFieldTest_ExtendedFile extends File implements TestOnly {
}