2008-08-12 02:12:29 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class TableListFieldTest extends SapphireTest {
|
|
|
|
static $fixture_file = 'sapphire/tests/forms/TableListFieldTest.yml';
|
2010-01-13 00:16:14 +01:00
|
|
|
|
|
|
|
protected $extraDataObjects = array(
|
|
|
|
'TableListFieldTest_Obj',
|
|
|
|
'TableListFieldTest_CsvExport',
|
|
|
|
);
|
2008-08-12 02:12:29 +02:00
|
|
|
|
2008-08-13 03:39:46 +02:00
|
|
|
function testCanReferenceCustomMethodsAndFieldsOnObject() {
|
2008-08-12 02:12:29 +02:00
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B",
|
|
|
|
"C" => "Col C",
|
|
|
|
"D" => "Col D",
|
|
|
|
"E" => "Col E",
|
|
|
|
));
|
2008-10-08 04:00:12 +02:00
|
|
|
// A TableListField must be inside a form for its links to be generated
|
|
|
|
$form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
|
|
|
|
2008-08-12 02:12:29 +02:00
|
|
|
$result = $table->FieldHolder();
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2008-08-12 02:12:29 +02:00
|
|
|
// Do a quick check to ensure that some of the D() and getE() values got through
|
|
|
|
$this->assertRegExp('/>\s*a2\s*</', $result);
|
|
|
|
$this->assertRegExp('/>\s*a2\/b2\/c2\s*</', $result);
|
|
|
|
$this->assertRegExp('/>\s*a2-e</', $result);
|
|
|
|
}
|
2008-08-13 03:39:46 +02:00
|
|
|
|
|
|
|
function testUnpaginatedSourceItemGeneration() {
|
2009-10-01 23:51:58 +02:00
|
|
|
$item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
|
|
|
|
$item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
|
|
|
|
$item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
|
|
|
|
$item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
|
|
|
|
$item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
|
|
|
|
|
2010-05-20 09:28:05 +02:00
|
|
|
// In this simple case, the source items should just list all the data objects specified
|
2008-08-13 03:39:46 +02:00
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B",
|
|
|
|
"C" => "Col C",
|
|
|
|
"D" => "Col D",
|
|
|
|
"E" => "Col E",
|
|
|
|
));
|
2008-10-08 04:00:12 +02:00
|
|
|
// A TableListField must be inside a form for its links to be generated
|
|
|
|
$form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2008-08-13 03:39:46 +02:00
|
|
|
$items = $table->sourceItems();
|
|
|
|
$this->assertNotNull($items);
|
|
|
|
|
2009-10-01 23:51:58 +02:00
|
|
|
$itemMap = $items->toDropdownMap("ID", "A") ;
|
|
|
|
$this->assertEquals(array(
|
|
|
|
$item1->ID => "a1",
|
|
|
|
$item2->ID => "a2",
|
|
|
|
$item3->ID => "a3",
|
|
|
|
$item4->ID => "a4",
|
|
|
|
$item5->ID => "a5"
|
|
|
|
), $itemMap);
|
2008-08-13 03:39:46 +02:00
|
|
|
}
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2008-08-13 03:39:46 +02:00
|
|
|
function testFirstPageOfPaginatedSourceItemGeneration() {
|
2009-10-01 23:51:58 +02:00
|
|
|
$item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
|
|
|
|
$item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
|
|
|
|
$item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
|
|
|
|
$item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
|
|
|
|
$item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
|
|
|
|
|
2010-05-20 09:28:05 +02:00
|
|
|
// With pagination enabled, only the first page of items should be shown
|
2008-08-13 03:39:46 +02:00
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B",
|
|
|
|
"C" => "Col C",
|
|
|
|
"D" => "Col D",
|
|
|
|
"E" => "Col E",
|
|
|
|
));
|
2008-10-08 04:00:12 +02:00
|
|
|
// A TableListField must be inside a form for its links to be generated
|
|
|
|
$form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2008-08-13 03:39:46 +02:00
|
|
|
$table->ShowPagination = true;
|
|
|
|
$table->PageSize = 2;
|
|
|
|
|
|
|
|
$items = $table->sourceItems();
|
|
|
|
$this->assertNotNull($items);
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2008-08-13 03:39:46 +02:00
|
|
|
$itemMap = $items->toDropdownMap("ID", "A") ;
|
2009-10-01 23:51:58 +02:00
|
|
|
$this->assertEquals(array(
|
|
|
|
$item1->ID => "a1",
|
|
|
|
$item2->ID => "a2"
|
|
|
|
), $itemMap);
|
2008-08-13 03:39:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function testSecondPageOfPaginatedSourceItemGeneration() {
|
2009-10-01 23:51:58 +02:00
|
|
|
$item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
|
|
|
|
$item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
|
|
|
|
$item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
|
|
|
|
$item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
|
|
|
|
$item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
|
|
|
|
|
2010-05-20 09:28:05 +02:00
|
|
|
// With pagination enabled, only the first page of items should be shown
|
2008-08-13 03:39:46 +02:00
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B",
|
|
|
|
"C" => "Col C",
|
|
|
|
"D" => "Col D",
|
|
|
|
"E" => "Col E",
|
|
|
|
));
|
2008-10-08 04:00:12 +02:00
|
|
|
// A TableListField must be inside a form for its links to be generated
|
|
|
|
$form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2008-08-13 03:39:46 +02:00
|
|
|
$table->ShowPagination = true;
|
|
|
|
$table->PageSize = 2;
|
|
|
|
$_REQUEST['ctf']['Tester']['start'] = 2;
|
|
|
|
|
|
|
|
$items = $table->sourceItems();
|
|
|
|
$this->assertNotNull($items);
|
2010-05-20 09:28:05 +02:00
|
|
|
|
2009-10-01 23:51:58 +02:00
|
|
|
$itemMap = $items->toDropdownMap("ID", "A") ;
|
|
|
|
$this->assertEquals(array($item3->ID => "a3", $item4->ID => "a4"), $itemMap);
|
2008-08-13 03:39:46 +02:00
|
|
|
}
|
2008-10-08 04:00:12 +02:00
|
|
|
|
2010-05-20 09:28:05 +02:00
|
|
|
function testSelectOptionsAddRemove() {
|
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
));
|
|
|
|
$this->assertNull($table->SelectOptions(), 'Empty by default');
|
|
|
|
|
|
|
|
$table->addSelectOptions(array("F"=>"FieldF", 'G'=>'FieldG'));
|
|
|
|
$this->assertEquals($table->SelectOptions()->map('Key', 'Value'), array("F"=>"FieldF",'G'=>'FieldG'));
|
|
|
|
|
|
|
|
$table->removeSelectOptions(array("F"));
|
|
|
|
$this->assertEquals($table->SelectOptions()->map('Key', 'Value'), array("G"=>"FieldG"));
|
|
|
|
}
|
|
|
|
|
|
|
|
function testSelectOptionsRendering() {
|
2010-05-21 01:15:56 +02:00
|
|
|
$obj1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
|
|
|
|
$obj2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
|
|
|
|
$obj3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
|
2010-05-20 09:28:05 +02:00
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
));
|
|
|
|
$table->Markable = true;
|
|
|
|
|
|
|
|
$table->addSelectOptions(array("F"=>"FieldF"));
|
|
|
|
$tableHTML = $table->FieldHolder();
|
|
|
|
$this->assertContains('rel="F"', $tableHTML);
|
|
|
|
|
2010-05-21 01:15:56 +02:00
|
|
|
$this->assertRegExp('/<tr[^>]*id="record-Tester-' . $obj1->ID . '"[^>]*>[^<]*<td[^>]*class="markingcheckbox F"[^>]*>/si', $tableHTML);
|
|
|
|
$this->assertRegExp('/<tr[^>]*id="record-Tester-' . $obj1->ID . '"[^>]*>[^<]*<td[^>]*class="markingcheckbox"[^>]*>/si', $tableHTML);
|
|
|
|
$this->assertRegExp('/<tr[^>]*id="record-Tester-' . $obj3->ID . '"[^>]*>[^<]*<td[^>]*class="markingcheckbox F"[^>]*>/si', $tableHTML);
|
2010-05-20 09:28:05 +02:00
|
|
|
}
|
|
|
|
|
2008-10-08 05:32:33 +02:00
|
|
|
/**
|
|
|
|
* Get that visiting the field's URL returns the content of the field.
|
|
|
|
* This capability is used by ajax
|
|
|
|
*/
|
|
|
|
function testAjaxRefreshing() {
|
|
|
|
$controller = new TableListFieldTest_TestController();
|
|
|
|
$table = $controller->TestForm()->Fields()->First();
|
|
|
|
|
|
|
|
$ajaxResponse = Director::test($table->Link())->getBody();
|
|
|
|
|
|
|
|
// Check that the column headings have been rendered
|
2010-02-04 04:52:40 +01:00
|
|
|
$this->assertRegExp('/<th[^>]*>.*Col A.*<\/th>/si', $ajaxResponse);
|
|
|
|
$this->assertRegExp('/<th[^>]*>.*Col B.*<\/th>/si', $ajaxResponse);
|
|
|
|
$this->assertRegExp('/<th[^>]*>.*Col C.*<\/th>/si', $ajaxResponse);
|
|
|
|
$this->assertRegExp('/<th[^>]*>.*Col D.*<\/th>/si', $ajaxResponse);
|
|
|
|
$this->assertRegExp('/<th[^>]*>.*Col E.*<\/th>/si', $ajaxResponse);
|
2008-10-08 05:32:33 +02:00
|
|
|
}
|
|
|
|
|
2008-10-08 04:00:12 +02:00
|
|
|
function testCsvExport() {
|
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_CsvExport", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B"
|
|
|
|
));
|
|
|
|
|
|
|
|
$form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
|
|
|
|
|
|
|
$csvResponse = $table->export();
|
|
|
|
|
|
|
|
$csvOutput = $csvResponse->getBody();
|
|
|
|
|
|
|
|
$this->assertNotEquals($csvOutput, false);
|
|
|
|
|
|
|
|
// Create a temporary file and write the CSV to it.
|
|
|
|
$csvFileName = tempnam(TEMP_FOLDER, 'csv-export');
|
2010-02-07 03:14:54 +01:00
|
|
|
$csvFile = fopen($csvFileName, 'wb');
|
2008-10-08 04:00:12 +02:00
|
|
|
fwrite($csvFile, $csvOutput);
|
|
|
|
fclose($csvFile);
|
|
|
|
|
2010-02-07 03:14:54 +01:00
|
|
|
$csvFile = fopen($csvFileName, 'rb');
|
2008-10-08 04:00:12 +02:00
|
|
|
$csvRow = fgetcsv($csvFile);
|
|
|
|
$this->assertEquals(
|
|
|
|
$csvRow,
|
|
|
|
array('Col A', 'Col B')
|
|
|
|
);
|
|
|
|
|
2010-02-04 04:52:40 +01:00
|
|
|
// fgetcsv doesn't handle escaped quotes in the string in PHP 5.2, so we're asserting the
|
|
|
|
// raw string instead.
|
2008-10-08 04:00:12 +02:00
|
|
|
$this->assertEquals(
|
2010-02-04 04:52:40 +01:00
|
|
|
'"\"A field, with a comma\"","A second field"',
|
|
|
|
trim(fgets($csvFile))
|
2008-10-08 04:00:12 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
fclose($csvFile);
|
|
|
|
|
|
|
|
unlink($csvFileName);
|
|
|
|
}
|
2010-05-20 12:09:08 +02:00
|
|
|
|
|
|
|
function testPreservedSortOptionsInPaginationLink() {
|
|
|
|
$item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
|
|
|
|
$item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
|
|
|
|
$item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
|
|
|
|
$item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
|
|
|
|
$item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
|
|
|
|
|
|
|
|
/* With pagination enabled, only the first page of items should be shown */
|
|
|
|
$table = new TableListField("Tester", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B",
|
|
|
|
"C" => "Col C",
|
|
|
|
"D" => "Col D",
|
|
|
|
"E" => "Col E",
|
|
|
|
));
|
|
|
|
// A TableListField must be inside a form for its links to be generated
|
|
|
|
$form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
|
|
|
|
|
|
|
$table->ShowPagination = true;
|
|
|
|
$table->PageSize = 2;
|
|
|
|
|
|
|
|
// first page & sort A column by ASC
|
|
|
|
$_REQUEST['ctf']['Tester']['start'] = 0;
|
|
|
|
$_REQUEST['ctf']['Tester']['sort'] = 'A';
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->NextLink());
|
|
|
|
$this->assertNotContains('ctf[Tester][dir]', $table->NextLink());
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->LastLink());
|
|
|
|
$this->assertNotContains('ctf[Tester][dir]', $table->LastLink());
|
|
|
|
|
|
|
|
// second page & sort A column by ASC
|
|
|
|
$_REQUEST['ctf']['Tester']['start'] = 2;
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->PrevLink());
|
|
|
|
$this->assertNotContains('&ctf[Tester][dir]', $table->PrevLink());
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->FirstLink());
|
|
|
|
$this->assertNotContains('&ctf[Tester][dir]', $table->FirstLink());
|
|
|
|
|
|
|
|
// first page & sort A column by DESC
|
|
|
|
$_REQUEST['ctf']['Tester']['start'] = 0;
|
|
|
|
$_REQUEST['ctf']['Tester']['sort'] = 'A';
|
|
|
|
$_REQUEST['ctf']['Tester']['dir'] = 'desc';
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->NextLink());
|
|
|
|
$this->assertContains('&ctf[Tester][dir]=desc', $table->NextLink());
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->LastLink());
|
|
|
|
$this->assertContains('&ctf[Tester][dir]=desc', $table->LastLink());
|
|
|
|
|
|
|
|
// second page & sort A column by DESC
|
|
|
|
$_REQUEST['ctf']['Tester']['start'] = 2;
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->PrevLink());
|
|
|
|
$this->assertContains('&ctf[Tester][dir]=desc', $table->PrevLink());
|
|
|
|
$this->assertContains('&ctf[Tester][sort]=A', $table->FirstLink());
|
|
|
|
$this->assertContains('&ctf[Tester][dir]=desc', $table->FirstLink());
|
|
|
|
|
|
|
|
unset($_REQUEST['ctf']);
|
|
|
|
}
|
2008-08-12 02:12:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class TableListFieldTest_Obj extends DataObject implements TestOnly {
|
|
|
|
static $db = array(
|
|
|
|
"A" => "Varchar",
|
|
|
|
"B" => "Varchar",
|
|
|
|
"C" => "Varchar",
|
2010-05-20 09:28:05 +02:00
|
|
|
"F" => "Boolean",
|
2008-08-12 02:12:29 +02:00
|
|
|
);
|
2009-06-16 06:03:47 +02:00
|
|
|
static $default_sort = "A";
|
2008-08-12 02:12:29 +02:00
|
|
|
|
|
|
|
function D() {
|
|
|
|
return $this->A . '/' . $this->B . '/' . $this->C;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getE() {
|
|
|
|
return $this->A . '-e';
|
|
|
|
}
|
|
|
|
}
|
2008-10-08 04:00:12 +02:00
|
|
|
|
|
|
|
class TableListFieldTest_CsvExport extends DataObject implements TestOnly {
|
|
|
|
static $db = array(
|
|
|
|
"A" => "Varchar",
|
|
|
|
"B" => "Varchar"
|
|
|
|
);
|
2009-06-16 06:03:47 +02:00
|
|
|
static $default_sort = "A";
|
2008-10-08 04:00:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class TableListFieldTest_TestController extends Controller {
|
2009-10-11 02:07:16 +02:00
|
|
|
function Link($action = null) {
|
|
|
|
return Controller::join_links("TableListFieldTest_TestController/", $action);
|
2008-10-08 04:00:12 +02:00
|
|
|
}
|
2008-10-08 05:32:33 +02:00
|
|
|
function TestForm() {
|
|
|
|
$table = new TableListField("Table", "TableListFieldTest_Obj", array(
|
|
|
|
"A" => "Col A",
|
|
|
|
"B" => "Col B",
|
|
|
|
"C" => "Col C",
|
|
|
|
"D" => "Col D",
|
|
|
|
"E" => "Col E",
|
|
|
|
));
|
2009-10-15 23:58:15 +02:00
|
|
|
$table->disableSorting();
|
2008-10-08 05:32:33 +02:00
|
|
|
|
|
|
|
// A TableListField must be inside a form for its links to be generated
|
|
|
|
return new Form($this, "TestForm", new FieldSet(
|
|
|
|
$table
|
|
|
|
), new FieldSet());
|
|
|
|
}
|
2008-10-08 04:00:12 +02:00
|
|
|
}
|