PageRenderTime 27ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/forms/TableListFieldTest.php

http://github.com/silverstripe/sapphire
PHP | 374 lines | 288 code | 58 blank | 28 comment | 0 complexity | af096bdc52c189a164f17525dce14651 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, CC-BY-3.0, GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. class TableListFieldTest extends SapphireTest {
  3. static $fixture_file = 'TableListFieldTest.yml';
  4. protected $extraDataObjects = array(
  5. 'TableListFieldTest_Obj',
  6. 'TableListFieldTest_CsvExport',
  7. );
  8. function testCanReferenceCustomMethodsAndFieldsOnObject() {
  9. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  10. "A" => "Col A",
  11. "B" => "Col B",
  12. "C" => "Col C",
  13. "D" => "Col D",
  14. "E" => "Col E",
  15. ));
  16. // A TableListField must be inside a form for its links to be generated
  17. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  18. $table
  19. ), new FieldList());
  20. $result = $table->FieldHolder();
  21. // Do a quick check to ensure that some of the D() and getE() values got through
  22. $this->assertRegExp('/>\s*a2\s*</', $result);
  23. $this->assertRegExp('/>\s*a2\/b2\/c2\s*</', $result);
  24. $this->assertRegExp('/>\s*a2-e</', $result);
  25. }
  26. function testUnpaginatedSourceItemGeneration() {
  27. $item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
  28. $item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
  29. $item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
  30. $item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
  31. $item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
  32. // In this simple case, the source items should just list all the data objects specified
  33. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  34. "A" => "Col A",
  35. "B" => "Col B",
  36. "C" => "Col C",
  37. "D" => "Col D",
  38. "E" => "Col E",
  39. ));
  40. // A TableListField must be inside a form for its links to be generated
  41. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  42. $table
  43. ), new FieldList());
  44. $items = $table->sourceItems();
  45. $this->assertNotNull($items);
  46. $itemMap = $items->map("ID", "A") ;
  47. $this->assertEquals(array(
  48. $item1->ID => "a1",
  49. $item2->ID => "a2",
  50. $item3->ID => "a3",
  51. $item4->ID => "a4",
  52. $item5->ID => "a5"
  53. ), $itemMap->toArray());
  54. }
  55. function testFirstPageOfPaginatedSourceItemGeneration() {
  56. $item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
  57. $item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
  58. $item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
  59. $item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
  60. $item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
  61. // With pagination enabled, only the first page of items should be shown
  62. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  63. "A" => "Col A",
  64. "B" => "Col B",
  65. "C" => "Col C",
  66. "D" => "Col D",
  67. "E" => "Col E",
  68. ));
  69. // A TableListField must be inside a form for its links to be generated
  70. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  71. $table
  72. ), new FieldList());
  73. $table->ShowPagination = true;
  74. $table->PageSize = 2;
  75. $items = $table->sourceItems();
  76. $this->assertNotNull($items);
  77. $itemMap = $items->map("ID", "A") ;
  78. $this->assertEquals(array(
  79. $item1->ID => "a1",
  80. $item2->ID => "a2"
  81. ), $itemMap->toArray());
  82. }
  83. function testSecondPageOfPaginatedSourceItemGeneration() {
  84. $item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
  85. $item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
  86. $item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
  87. $item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
  88. $item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
  89. // With pagination enabled, only the first page of items should be shown
  90. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  91. "A" => "Col A",
  92. "B" => "Col B",
  93. "C" => "Col C",
  94. "D" => "Col D",
  95. "E" => "Col E",
  96. ));
  97. // A TableListField must be inside a form for its links to be generated
  98. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  99. $table
  100. ), new FieldList());
  101. $table->ShowPagination = true;
  102. $table->PageSize = 2;
  103. $_REQUEST['ctf']['Tester']['start'] = 2;
  104. $items = $table->sourceItems();
  105. $this->assertNotNull($items);
  106. $itemMap = $items->map("ID", "A") ;
  107. $this->assertEquals(array($item3->ID => "a3", $item4->ID => "a4"), $itemMap->toArray());
  108. }
  109. function testSelectOptionsAddRemove() {
  110. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  111. "A" => "Col A",
  112. ));
  113. $this->assertNull($table->SelectOptions(), 'Empty by default');
  114. $table->addSelectOptions(array("F"=>"FieldF", 'G'=>'FieldG'));
  115. $this->assertEquals($table->SelectOptions()->map('Key', 'Value'), array("F"=>"FieldF",'G'=>'FieldG'));
  116. $table->removeSelectOptions(array("F"));
  117. $this->assertEquals($table->SelectOptions()->map('Key', 'Value'), array("G"=>"FieldG"));
  118. }
  119. function testSelectOptionsRendering() {
  120. $obj1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
  121. $obj2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
  122. $obj3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
  123. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  124. "A" => "Col A",
  125. ));
  126. $table->Markable = true;
  127. $table->addSelectOptions(array("F"=>"FieldF"));
  128. $tableHTML = $table->FieldHolder();
  129. $p = new CSSContentParser($tableHTML);
  130. $this->assertContains('rel="F"', $tableHTML);
  131. $tbody = $p->getByXpath('//tbody');
  132. $this->assertContains('markingcheckbox F', (string)$tbody[0]->tr[0]->td[0]['class']);
  133. $this->assertContains('markingcheckbox', (string)$tbody[0]->tr[1]->td[0]['class']);
  134. $this->assertContains('markingcheckbox F', (string)$tbody[0]->tr[2]->td[0]['class']);
  135. }
  136. /**
  137. * Get that visiting the field's URL returns the content of the field.
  138. * This capability is used by ajax
  139. */
  140. function testAjaxRefreshing() {
  141. $controller = new TableListFieldTest_TestController();
  142. $table = $controller->TestForm()->Fields()->First();
  143. $ajaxResponse = Director::test($table->Link())->getBody();
  144. // Check that the column headings have been rendered
  145. $this->assertRegExp('/<th[^>]*>.*Col A.*<\/th>/si', $ajaxResponse);
  146. $this->assertRegExp('/<th[^>]*>.*Col B.*<\/th>/si', $ajaxResponse);
  147. $this->assertRegExp('/<th[^>]*>.*Col C.*<\/th>/si', $ajaxResponse);
  148. $this->assertRegExp('/<th[^>]*>.*Col D.*<\/th>/si', $ajaxResponse);
  149. $this->assertRegExp('/<th[^>]*>.*Col E.*<\/th>/si', $ajaxResponse);
  150. }
  151. function testCsvExport() {
  152. $table = new TableListField("Tester", "TableListFieldTest_CsvExport", array(
  153. "A" => "Col A",
  154. "B" => "Col B"
  155. ));
  156. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  157. $table
  158. ), new FieldList());
  159. $csvResponse = $table->export();
  160. $csvOutput = $csvResponse->getBody();
  161. $this->assertNotEquals($csvOutput, false);
  162. // Create a temporary file and write the CSV to it.
  163. $csvFileName = tempnam(TEMP_FOLDER, 'csv-export');
  164. $csvFile = fopen($csvFileName, 'wb');
  165. fwrite($csvFile, $csvOutput);
  166. fclose($csvFile);
  167. $csvFile = fopen($csvFileName, 'rb');
  168. $csvRow = fgetcsv($csvFile);
  169. $this->assertEquals(
  170. $csvRow,
  171. array('Col A', 'Col B')
  172. );
  173. // fgetcsv doesn't handle escaped quotes in the string in PHP 5.2, so we're asserting the
  174. // raw string instead.
  175. $this->assertEquals(
  176. '"\"A field, with a comma\"","A second field"',
  177. trim(fgets($csvFile))
  178. );
  179. fclose($csvFile);
  180. unlink($csvFileName);
  181. }
  182. function testLink() {
  183. // A TableListField must be inside a form for its links to be generated
  184. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  185. new TableListField("Tester", "TableListFieldTest_Obj", array(
  186. "A" => "Col A",
  187. "B" => "Col B",
  188. "C" => "Col C",
  189. "D" => "Col D",
  190. "E" => "Col E",
  191. ))
  192. ), new FieldList());
  193. $table = $form->Fields()->dataFieldByName('Tester');
  194. $this->assertEquals(
  195. $table->Link('test'),
  196. sprintf('TableListFieldTest_TestController/TestForm/field/Tester/test?SecurityID=%s', $form->Fields()->dataFieldByName('SecurityID')->Value())
  197. );
  198. }
  199. function testPreservedSortOptionsInPaginationLink() {
  200. $item1 = $this->objFromFixture('TableListFieldTest_Obj', 'one');
  201. $item2 = $this->objFromFixture('TableListFieldTest_Obj', 'two');
  202. $item3 = $this->objFromFixture('TableListFieldTest_Obj', 'three');
  203. $item4 = $this->objFromFixture('TableListFieldTest_Obj', 'four');
  204. $item5 = $this->objFromFixture('TableListFieldTest_Obj', 'five');
  205. /* With pagination enabled, only the first page of items should be shown */
  206. $table = new TableListField("Tester", "TableListFieldTest_Obj", array(
  207. "A" => "Col A",
  208. "B" => "Col B",
  209. "C" => "Col C",
  210. "D" => "Col D",
  211. "E" => "Col E",
  212. ));
  213. // A TableListField must be inside a form for its links to be generated
  214. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  215. $table
  216. ), new FieldList());
  217. $table->ShowPagination = true;
  218. $table->PageSize = 2;
  219. // first page & sort A column by ASC
  220. $_REQUEST['ctf']['Tester']['start'] = 0;
  221. $_REQUEST['ctf']['Tester']['sort'] = 'A';
  222. $this->assertContains('&ctf[Tester][sort]=A', $table->NextLink());
  223. $this->assertNotContains('ctf[Tester][dir]', $table->NextLink());
  224. $this->assertContains('&ctf[Tester][sort]=A', $table->LastLink());
  225. $this->assertNotContains('ctf[Tester][dir]', $table->LastLink());
  226. // second page & sort A column by ASC
  227. $_REQUEST['ctf']['Tester']['start'] = 2;
  228. $this->assertContains('&ctf[Tester][sort]=A', $table->PrevLink());
  229. $this->assertNotContains('&ctf[Tester][dir]', $table->PrevLink());
  230. $this->assertContains('&ctf[Tester][sort]=A', $table->FirstLink());
  231. $this->assertNotContains('&ctf[Tester][dir]', $table->FirstLink());
  232. // first page & sort A column by DESC
  233. $_REQUEST['ctf']['Tester']['start'] = 0;
  234. $_REQUEST['ctf']['Tester']['sort'] = 'A';
  235. $_REQUEST['ctf']['Tester']['dir'] = 'desc';
  236. $this->assertContains('&ctf[Tester][sort]=A', $table->NextLink());
  237. $this->assertContains('&ctf[Tester][dir]=desc', $table->NextLink());
  238. $this->assertContains('&ctf[Tester][sort]=A', $table->LastLink());
  239. $this->assertContains('&ctf[Tester][dir]=desc', $table->LastLink());
  240. // second page & sort A column by DESC
  241. $_REQUEST['ctf']['Tester']['start'] = 2;
  242. $this->assertContains('&ctf[Tester][sort]=A', $table->PrevLink());
  243. $this->assertContains('&ctf[Tester][dir]=desc', $table->PrevLink());
  244. $this->assertContains('&ctf[Tester][sort]=A', $table->FirstLink());
  245. $this->assertContains('&ctf[Tester][dir]=desc', $table->FirstLink());
  246. unset($_REQUEST['ctf']);
  247. }
  248. /**
  249. * Check that a SS_List can be passed to TableListField
  250. */
  251. function testDataObjectSet() {
  252. $one = new TableListFieldTest_Obj;
  253. $one->A = "A-one";
  254. $two = new TableListFieldTest_Obj;
  255. $two->A = "A-two";
  256. $three = new TableListFieldTest_Obj;
  257. $three->A = "A-three";
  258. $list = new ArrayList(array($one, $two, $three));
  259. // A TableListField must be inside a form for its links to be generated
  260. $form = new Form(new TableListFieldTest_TestController(), "TestForm", new FieldList(
  261. new TableListField("Tester", $list, array(
  262. "A" => "Col A",
  263. "B" => "Col B",
  264. "C" => "Col C",
  265. "D" => "Col D",
  266. "E" => "Col E",
  267. ))
  268. ), new FieldList());
  269. $table = $form->Fields()->dataFieldByName('Tester');
  270. $rendered = $table->FieldHolder();
  271. $this->assertContains('A-one', $rendered);
  272. $this->assertContains('A-two', $rendered);
  273. $this->assertContains('A-three', $rendered);
  274. }
  275. }
  276. class TableListFieldTest_Obj extends DataObject implements TestOnly {
  277. static $db = array(
  278. "A" => "Varchar",
  279. "B" => "Varchar",
  280. "C" => "Varchar",
  281. "F" => "Boolean",
  282. );
  283. static $default_sort = "A";
  284. function D() {
  285. return $this->A . '/' . $this->B . '/' . $this->C;
  286. }
  287. function getE() {
  288. return $this->A . '-e';
  289. }
  290. }
  291. class TableListFieldTest_CsvExport extends DataObject implements TestOnly {
  292. static $db = array(
  293. "A" => "Varchar",
  294. "B" => "Varchar"
  295. );
  296. static $default_sort = "A";
  297. }
  298. class TableListFieldTest_TestController extends Controller {
  299. function Link($action = null) {
  300. return Controller::join_links("TableListFieldTest_TestController/", $action);
  301. }
  302. function TestForm() {
  303. $table = new TableListField("Table", "TableListFieldTest_Obj", array(
  304. "A" => "Col A",
  305. "B" => "Col B",
  306. "C" => "Col C",
  307. "D" => "Col D",
  308. "E" => "Col E",
  309. ));
  310. $table->disableSorting();
  311. // A TableListField must be inside a form for its links to be generated
  312. return new Form($this, "TestForm", new FieldList(
  313. $table
  314. ), new FieldList());
  315. }
  316. }