/tests/php/Forms/GridField/GridFieldSortableHeaderTest.php

http://github.com/silverstripe/sapphire · PHP · 232 lines · 181 code · 28 blank · 23 comment · 0 complexity · 8316c2c46f38c5aea2f2d59e05ddbfd2 MD5 · raw file

  1. <?php
  2. namespace SilverStripe\Forms\Tests\GridField;
  3. use SilverStripe\Forms\GridField\GridFieldSortableHeader;
  4. use SilverStripe\Forms\Tests\GridField\GridFieldSortableHeaderTest\Cheerleader;
  5. use SilverStripe\Forms\Tests\GridField\GridFieldSortableHeaderTest\CheerleaderHat;
  6. use SilverStripe\Forms\Tests\GridField\GridFieldSortableHeaderTest\Team;
  7. use SilverStripe\Forms\Tests\GridField\GridFieldSortableHeaderTest\TeamGroup;
  8. use SilverStripe\Forms\Tests\GridField\GridFieldSortableHeaderTest\Mom;
  9. use SilverStripe\ORM\DataList;
  10. use SilverStripe\Core\Convert;
  11. use SilverStripe\Dev\SapphireTest;
  12. use SilverStripe\Forms\FieldList;
  13. use SilverStripe\Forms\Form;
  14. use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
  15. use SilverStripe\Forms\GridField\GridField;
  16. class GridFieldSortableHeaderTest extends SapphireTest
  17. {
  18. protected static $fixture_file = 'GridFieldSortableHeaderTest.yml';
  19. protected static $extra_dataobjects = [
  20. Team::class,
  21. TeamGroup::class,
  22. Cheerleader::class,
  23. CheerleaderHat::class,
  24. Mom::class,
  25. ];
  26. /**
  27. * Tests that the appropriate sortable headers are generated
  28. *
  29. * @skipUpgrade
  30. */
  31. public function testRenderHeaders()
  32. {
  33. // Generate sortable header and extract HTML
  34. $list = new DataList(Team::class);
  35. $config = new GridFieldConfig_RecordEditor();
  36. $form = new Form(null, 'Form', new FieldList(), new FieldList());
  37. $gridField = new GridField('testfield', 'testfield', $list, $config);
  38. $gridField->setForm($form);
  39. $component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
  40. $htmlFragment = $component->getHTMLFragments($gridField);
  41. // Check that the output shows name and hat as sortable fields, but not city
  42. $this->assertStringContainsString('<span class="non-sortable">City</span>', $htmlFragment['header']);
  43. $this->assertStringContainsString(
  44. 'value="Name" class="action grid-field__sort" id="action_SetOrderName"',
  45. $htmlFragment['header']
  46. );
  47. $this->assertStringContainsString(
  48. 'value="Cheerleader Hat" class="action grid-field__sort" id="action_SetOrderCheerleader-Hat-Colour"',
  49. $htmlFragment['header']
  50. );
  51. // Check inverse of above
  52. $this->assertStringNotContainsString(
  53. 'value="City" class="action grid-field__sort" id="action_SetOrderCity"',
  54. $htmlFragment['header']
  55. );
  56. $this->assertStringNotContainsString('<span class="non-sortable">Name</span>', $htmlFragment['header']);
  57. $this->assertStringNotContainsString('<span class="non-sortable">Cheerleader Hat</span>', $htmlFragment['header']);
  58. }
  59. public function testGetManipulatedData()
  60. {
  61. $list = Team::get()->filter([ 'ClassName' => Team::class ]);
  62. $config = new GridFieldConfig_RecordEditor();
  63. $gridField = new GridField('testfield', 'testfield', $list, $config);
  64. // Test normal sorting
  65. $state = $gridField->State->GridFieldSortableHeader;
  66. $state->SortColumn = 'City';
  67. $state->SortDirection = 'asc';
  68. $component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
  69. $listA = $component->getManipulatedData($gridField, $list);
  70. $state->SortDirection = 'desc';
  71. $listB = $component->getManipulatedData($gridField, $list);
  72. $this->assertEquals(
  73. ['Auckland', 'Cologne', 'Melbourne', 'Wellington'],
  74. $listA->column('City')
  75. );
  76. $this->assertEquals(
  77. ['Wellington', 'Melbourne', 'Cologne', 'Auckland'],
  78. $listB->column('City')
  79. );
  80. // Test one relation 'deep'
  81. $state->SortColumn = 'Cheerleader.Name';
  82. $state->SortDirection = 'asc';
  83. $relationListA = $component->getManipulatedData($gridField, $list);
  84. $state->SortDirection = 'desc';
  85. $relationListB = $component->getManipulatedData($gridField, $list);
  86. $this->assertEquals(
  87. ['Wellington', 'Melbourne', 'Cologne', 'Auckland'],
  88. $relationListA->column('City')
  89. );
  90. $this->assertEquals(
  91. ['Auckland', 'Cologne', 'Melbourne', 'Wellington'],
  92. $relationListB->column('City')
  93. );
  94. // Test two relations 'deep'
  95. $state->SortColumn = 'Cheerleader.Hat.Colour';
  96. $state->SortDirection = 'asc';
  97. $relationListC = $component->getManipulatedData($gridField, $list);
  98. $state->SortDirection = 'desc';
  99. $relationListD = $component->getManipulatedData($gridField, $list);
  100. $this->assertEquals(
  101. ['Cologne', 'Auckland', 'Wellington', 'Melbourne'],
  102. $relationListC->column('City')
  103. );
  104. $this->assertEquals(
  105. ['Melbourne', 'Wellington', 'Auckland', 'Cologne'],
  106. $relationListD->column('City')
  107. );
  108. }
  109. /**
  110. * Test getManipulatedData on subclassed dataobjects
  111. */
  112. public function testInheritedGetManiplatedData()
  113. {
  114. $list = TeamGroup::get();
  115. $config = new GridFieldConfig_RecordEditor();
  116. $gridField = new GridField('testfield', 'testfield', $list, $config);
  117. $state = $gridField->State->GridFieldSortableHeader;
  118. $component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
  119. // Test that inherited dataobjects will work correctly
  120. $state->SortColumn = 'Cheerleader.Hat.Colour';
  121. $state->SortDirection = 'asc';
  122. $relationListA = $component->getManipulatedData($gridField, $list);
  123. $relationListAsql = Convert::nl2os($relationListA->sql(), ' ');
  124. // Assert that all tables are joined properly
  125. $this->assertStringContainsString('FROM "GridFieldSortableHeaderTest_Team"', $relationListAsql);
  126. $this->assertStringContainsString(
  127. 'LEFT JOIN "GridFieldSortableHeaderTest_TeamGroup" '
  128. . 'ON "GridFieldSortableHeaderTest_TeamGroup"."ID" = "GridFieldSortableHeaderTest_Team"."ID"',
  129. $relationListAsql
  130. );
  131. $this->assertStringContainsString(
  132. 'LEFT JOIN "GridFieldSortableHeaderTest_Cheerleader" '
  133. . 'AS "cheerleader_GridFieldSortableHeaderTest_Cheerleader" '
  134. . 'ON "cheerleader_GridFieldSortableHeaderTest_Cheerleader"."ID" = '
  135. . '"GridFieldSortableHeaderTest_Team"."CheerleaderID"',
  136. $relationListAsql
  137. );
  138. $this->assertStringContainsString(
  139. 'LEFT JOIN "GridFieldSortableHeaderTest_CheerleaderHat" '
  140. . 'AS "cheerleader_hat_GridFieldSortableHeaderTest_CheerleaderHat" '
  141. . 'ON "cheerleader_hat_GridFieldSortableHeaderTest_CheerleaderHat"."ID" = '
  142. . '"cheerleader_GridFieldSortableHeaderTest_Cheerleader"."HatID"',
  143. $relationListAsql
  144. );
  145. // Test sorting is correct
  146. $this->assertEquals(
  147. ['Cologne', 'Auckland', 'Wellington', 'Melbourne'],
  148. $relationListA->column('City')
  149. );
  150. $state->SortDirection = 'desc';
  151. $relationListAdesc = $component->getManipulatedData($gridField, $list);
  152. $this->assertEquals(
  153. ['Melbourne', 'Wellington', 'Auckland', 'Cologne'],
  154. $relationListAdesc->column('City')
  155. );
  156. // Test subclasses of tables
  157. $state->SortColumn = 'CheerleadersMom.Hat.Colour';
  158. $state->SortDirection = 'asc';
  159. $relationListB = $component->getManipulatedData($gridField, $list);
  160. $relationListBsql = $relationListB->sql();
  161. // Assert that subclasses are included in the query
  162. $this->assertStringContainsString('FROM "GridFieldSortableHeaderTest_Team"', $relationListBsql);
  163. $this->assertStringContainsString(
  164. 'LEFT JOIN "GridFieldSortableHeaderTest_TeamGroup" '
  165. . 'ON "GridFieldSortableHeaderTest_TeamGroup"."ID" = "GridFieldSortableHeaderTest_Team"."ID"',
  166. $relationListBsql
  167. );
  168. // Joined tables are joined basetable first
  169. // Note: CheerLeader is base of Mom table, hence the alias
  170. $this->assertStringContainsString(
  171. 'LEFT JOIN "GridFieldSortableHeaderTest_Cheerleader" '
  172. . 'AS "cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader" '
  173. . 'ON "cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader"."ID" = '
  174. . '"GridFieldSortableHeaderTest_Team"."CheerleadersMomID"',
  175. $relationListBsql
  176. );
  177. // Then the basetable of the joined record is joined to the specific subtable
  178. $this->assertStringContainsString(
  179. 'LEFT JOIN "GridFieldSortableHeaderTest_Mom" '
  180. . 'AS "cheerleadersmom_GridFieldSortableHeaderTest_Mom" '
  181. . 'ON "cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader"."ID" = '
  182. . '"cheerleadersmom_GridFieldSortableHeaderTest_Mom"."ID"',
  183. $relationListBsql
  184. );
  185. $this->assertStringContainsString(
  186. 'LEFT JOIN "GridFieldSortableHeaderTest_CheerleaderHat" '
  187. . 'AS "cheerleadersmom_hat_GridFieldSortableHeaderTest_CheerleaderHat" '
  188. . 'ON "cheerleadersmom_hat_GridFieldSortableHeaderTest_CheerleaderHat"."ID" = '
  189. . '"cheerleadersmom_GridFieldSortableHeaderTest_Cheerleader"."HatID"',
  190. $relationListBsql
  191. );
  192. // Test sorting is correct
  193. $this->assertEquals(
  194. ['Cologne', 'Auckland', 'Wellington', 'Melbourne'],
  195. $relationListB->column('City')
  196. );
  197. $state->SortDirection = 'desc';
  198. $relationListBdesc = $component->getManipulatedData($gridField, $list);
  199. $this->assertEquals(
  200. ['Melbourne', 'Wellington', 'Auckland', 'Cologne'],
  201. $relationListBdesc->column('City')
  202. );
  203. }
  204. }