sbo__relationship_widgetTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <?php
  2. namespace Tests\tripal_chado\fields;
  3. use StatonLab\TripalTestSuite\DBTransaction;
  4. use StatonLab\TripalTestSuite\TripalTestCase;
  5. module_load_include('php', 'tripal_chado', '../tests/TripalFieldTestHelper');
  6. class sbo__relationship_widgetTest extends TripalTestCase {
  7. // Uncomment to auto start and rollback db transactions per test method.
  8. use DBTransaction;
  9. /**
  10. * Data Provider: provides entities matching important test cases.
  11. *
  12. * Specifically, we will cover three relationship tables, which represent
  13. * the diversity in the chado schema v1.3:
  14. * organism_relationship: subject_id, type_id, object_id,
  15. * stock_relationship: subject_id, type_id, object_id, value, rank,
  16. * project_relationship: subject_project_id, type_id, object_project_id, rank
  17. *
  18. * @returns
  19. * Returns an array where each item to be tested has the paramaters
  20. * needed for initializeWidgetClass(). Specfically, $bundle_name,
  21. * $field_name, $widget_name, $entity_id.
  22. */
  23. public function provideEntities() {
  24. $data = [];
  25. foreach (['organism', 'stock', 'project'] as $base_table) {
  26. $field_name = 'sbo__relationship';
  27. $widget_name = 'sbo__relationship_widget';
  28. // find a bundle which stores it's data in the given base table.
  29. // This will work on Travis since Tripal creates matching bundles by default.
  30. // @todo ideally we would create a fake bundle here.
  31. $bundle_id = db_query("
  32. SELECT bundle_id
  33. FROM chado_bundle b
  34. LEFT JOIN tripal_entity e ON e.bundle='bio_data_'||b.bundle_id
  35. WHERE data_table=:table AND id IS NOT NULL LIMIT 1",
  36. array(':table' => $base_table))->fetchField();
  37. if (!$bundle_id) {
  38. continue;
  39. }
  40. $bundle_name = 'bio_data_'.$bundle_id;
  41. // Find an entity from the above bundle.
  42. // @todo find a way to create a fake entity for use here.
  43. $entity_id = db_query('SELECT id FROM tripal_entity WHERE bundle=:bundle LIMIT 1',
  44. array(':bundle' => $bundle_name))->fetchField();
  45. // set variables to guide testing.
  46. $expect = [
  47. 'has_rank' => TRUE,
  48. 'has_value' => FALSE,
  49. 'subject_key' => 'subject_id',
  50. 'object_key' => 'object_id',
  51. 'base_table' => $base_table,
  52. 'relationship_table' => $base_table.'_relationship'
  53. ];
  54. if ($base_table == 'organism') { $expect['has_rank'] = FALSE; }
  55. if ($base_table == 'stock') { $expect['has_value'] = TRUE; }
  56. if ($base_table == 'project') {
  57. $expect['subject_key'] = 'subject_project_id';
  58. $expect['object_key'] = 'object_project_id';
  59. }
  60. $data[] = [$bundle_name, $field_name, $widget_name, $entity_id, $expect];
  61. }
  62. return $data;
  63. }
  64. /**
  65. * Test that we can initialize the widget properly.
  66. *
  67. * @dataProvider provideEntities()
  68. *
  69. * @group widget
  70. * @group sbo__relationship
  71. */
  72. public function testWidgetClassInitialization($bundle_name, $field_name, $widget_name, $entity_id, $expect) {
  73. // Load the entity.
  74. $entity = entity_load('TripalEntity', [$entity_id]);
  75. $entity = $entity[$entity_id];
  76. // Initialize the widget class via the TripalFieldTestHelper class.
  77. $machine_names = array(
  78. 'field_name' => $field_name,
  79. 'widget_name' => $widget_name,
  80. );
  81. $field_info = field_info_field($field_name);
  82. $instance_info = field_info_instance('TripalEntity', $field_name, $bundle_name);
  83. $helper = new \TripalFieldTestHelper($bundle_name, $machine_names, $entity, $field_info, $instance_info);
  84. $widget_class = $helper->getInitializedClass();
  85. // Check we have the variables we initialized.
  86. $this->assertNotEmpty($helper->bundle,
  87. "Could not load the bundle.");
  88. $this->assertNotEmpty($helper->getFieldInfo(),
  89. "Could not lookup the field information.");
  90. $this->assertNotEmpty($helper->getInstanceInfo(),
  91. "Could not lookup the instance information.");
  92. $this->assertNotEmpty($widget_class,
  93. "Couldn't create a widget class instance.");
  94. $this->assertNotEmpty($entity,
  95. "Couldn't load an entity.");
  96. // Check a little deeper...
  97. $this->assertEquals($helper->instance_info['settings']['chado_table'], $expect['relationship_table'],
  98. "Instance settings were not initialized fully.");
  99. }
  100. /**
  101. * Test the widget Form.
  102. *
  103. * @dataProvider provideEntities()
  104. *
  105. * @group widget
  106. * @group sbo__relationship
  107. */
  108. public function testWidgetForm($bundle_name, $field_name, $widget_name, $entity_id, $expect) {
  109. // Load the entity.
  110. $entity = entity_load('TripalEntity', [$entity_id]);
  111. $entity = $entity[$entity_id];
  112. // Initialize the widget class via the TripalFieldTestHelper class.
  113. $machine_names = array(
  114. 'field_name' => $field_name,
  115. 'widget_name' => $widget_name,
  116. );
  117. $field_info = field_info_field($field_name);
  118. $instance_info = field_info_instance('TripalEntity', $field_name, $bundle_name);
  119. $helper = new \TripalFieldTestHelper($bundle_name, $machine_names, $entity, $field_info, $instance_info);
  120. $widget_class = $helper->getInitializedClass();
  121. $base_table = $entity->chado_table;
  122. // Stub out a fake objects.
  123. $delta = 1;
  124. $langcode = LANGUAGE_NONE;
  125. $widget = $helper->mockElement($delta, $langcode);
  126. $form = $helper->mockForm($delta, $langcode);
  127. $form_state = $helper->mockFormState($delta, $langcode);
  128. $element = $helper->mockElement($delta, $langcode);
  129. $items = [
  130. 'value' => '',
  131. 'chado-'.$base_table.'_relationship__organism_relationship_id' => '',
  132. 'chado-'.$base_table.'_relationship__subject_id' => '',
  133. 'chado-'.$base_table.'_relationship__object_id' => '',
  134. 'chado-'.$base_table.'_relationship__type_id' => '',
  135. 'object_name' => '',
  136. 'subject_name' => '',
  137. 'type_name' => '',
  138. ];
  139. // Execute the form method.
  140. $widget_class->form($widget, $form, $form_state, $langcode, $items, $delta, $element);
  141. // Check the resulting for array
  142. $this->assertArrayHasKey('subject_name', $widget,
  143. "The form for $bundle_name($base_table) does not have a subject element.");
  144. $this->assertArrayHasKey('type_name', $widget,
  145. "The form for $bundle_name($base_table) does not have a type element.");
  146. $this->assertArrayHasKey('object_name', $widget,
  147. "The form for $bundle_name($base_table) does not have a object element.");
  148. // Check the subject/object keys were correctly determined.
  149. $this->assertEquals($expect['subject_key'], $widget['#subject_id_key'],
  150. "The form didn't determine the subject key correctly.");
  151. $this->assertEquals($expect['object_key'], $widget['#object_id_key'],
  152. "The form didn't determine the object key correctly.");
  153. }
  154. /**
  155. * DataProvider: Provides datasets to validate.
  156. */
  157. public function provideThings2Validate() {
  158. $data = [];
  159. foreach (['organism', 'stock', 'project'] as $base_table) {
  160. $base_table = $base_table;
  161. $field_name = 'sbo__relationship';
  162. $widget_name = 'sbo__relationship_widget';
  163. // find a bundle which stores it's data in the given base table.
  164. // This will work on Travis since Tripal creates matching bundles by default.
  165. // @todo ideally we would create a fake bundle here.
  166. $bundle_id = db_query("
  167. SELECT bundle_id
  168. FROM chado_bundle b
  169. LEFT JOIN tripal_entity e ON e.bundle='bio_data_'||b.bundle_id
  170. WHERE data_table=:table AND id IS NOT NULL LIMIT 1",
  171. array(':table' => $base_table))->fetchField();
  172. if (!$bundle_id) {
  173. continue;
  174. }
  175. $bundle_name = 'bio_data_'.$bundle_id;
  176. // Find an entity from the above bundle.
  177. // @todo find a way to create a fake entity for use here.
  178. $entity_id = db_query('SELECT id FROM tripal_entity WHERE bundle=:bundle LIMIT 1',
  179. array(':bundle' => $bundle_name))->fetchField();
  180. $entity = entity_load('TripalEntity', [ $entity_id ]);
  181. $entity = $entity[ $entity_id ];
  182. $values = [
  183. 'subject_name' => 'Fake Non-existant Name '.uniqid(),
  184. 'type_name' => 'organism',
  185. 'vocabulary' => 47,
  186. 'object_name' => $entity->chado_record->name,
  187. ];
  188. if ($base_table == 'organism') {
  189. $values['object_name'] = $entity->chado_record->species;
  190. }
  191. // set variables to guide testing.
  192. $expect = [
  193. 'has_rank' => TRUE,
  194. 'has_value' => FALSE,
  195. 'subject_key' => 'subject_id',
  196. 'object_key' => 'object_id',
  197. 'base_table' => $base_table,
  198. 'relationship_table' => $base_table.'_relationship',
  199. 'num_errors' => 0,
  200. ];
  201. if ($base_table == 'organism') { $expect['has_rank'] = FALSE; }
  202. if ($base_table == 'stock') { $expect['has_value'] = TRUE; }
  203. if ($base_table == 'project') {
  204. $expect['subject_key'] = 'subject_project_id';
  205. $expect['object_key'] = 'object_project_id';
  206. }
  207. $data[] = [
  208. [
  209. 'field_name' => $field_name,
  210. 'widget_name' => $widget_name,
  211. 'bundle_id' => $bundle_id,
  212. 'bundle_name' => $bundle_name,
  213. ],
  214. $entity,
  215. $values,
  216. $expect,
  217. ];
  218. }
  219. return $data;
  220. }
  221. /**
  222. * Test sbo__relationship_widget->validate().
  223. *
  224. * @dataProvider provideThings2Validate()
  225. *
  226. * @group lacey-wip
  227. * @group widget
  228. * @group sbo__relationship
  229. */
  230. public function testWidgetValidate($info, $entity, $initial_values, $expect) {
  231. $base_table = $entity->chado_table;
  232. // Initialize the widget class via the TripalFieldTestHelper class.
  233. $machine_names = array(
  234. 'field_name' => $info['field_name'],
  235. 'widget_name' => $info['widget_name'],
  236. );
  237. $field_info = field_info_field($info['field_name']);
  238. $instance_info = field_info_instance('TripalEntity', $info['field_name'], $info['bundle_name']);
  239. $helper = new \TripalFieldTestHelper($info['bundle_name'], $machine_names, $entity, $field_info, $instance_info);
  240. $widget_class = $helper->getInitializedClass();
  241. // Mock objects.
  242. $delta = 1;
  243. $langcode = LANGUAGE_NONE;
  244. $widget = $helper->mockElement($delta, $langcode);
  245. $form = $helper->mockForm($delta, $langcode);
  246. $form_state = $helper->mockFormState($delta, $langcode, $initial_values);
  247. $element = $helper->mockElement($delta, $langcode);
  248. $widget_class->validate($element, $form, $form_state, $langcode, $delta);
  249. // @debug print_r($form_state['values'][$field_name][$langcode][$delta]);
  250. // Ensure the chado-table__column entries are there.
  251. $this->assertArrayHasKey(
  252. 'chado-'.$base_table.'_relationship__'.$expect['subject_key'],
  253. $form_state['values'][$field_name][$langcode][$delta],
  254. 'Failed to find the subject_id in the processed values (Base: '.$base_table.'). This implies the validate function was not able to validate the subject.'
  255. );
  256. $this->assertArrayHasKey(
  257. 'chado-'.$base_table.'_relationship__'.$expect['object_key'],
  258. $form_state['values'][$field_name][$langcode][$delta],
  259. 'Failed to find the object_id in the processed values (Base: '.$base_table.'). This implies the validate function was not able to validate the object.'
  260. );
  261. $this->assertArrayHasKey(
  262. 'chado-'.$base_table.'_relationship__type_id',
  263. $form_state['values'][$field_name][$langcode][$delta],
  264. 'Failed to find the type_id in the processed values (Base: '.$base_table.'). This implies the validate function was not able to validate the type.'
  265. );
  266. // Check for errors.
  267. $errors = form_get_errors();
  268. $this->assertEmpty($errors,
  269. "There should be no form errors! But these were registered: ".print_r($errors, TRUE));
  270. // Clean up after ourselves by removing any errors we logged.
  271. form_clear_error();
  272. }
  273. /**
  274. * Test the Relationship Type Options.
  275. * Specfically, sbo__relationship_widget->get_rtype_select_options().
  276. *
  277. * @dataProvider provideEntities()
  278. *
  279. * @group widget
  280. * @group sbo__relationship
  281. */
  282. public function testGetRTypeSelectOptions($bundle_name, $field_name, $widget_name, $entity_id, $expect) {
  283. // The different options are set in the instance.
  284. // Therefore we want to make a fake instance to control this setting.
  285. $fake_instance = field_info_instance('TripalEntity', $field_name, $bundle_name);
  286. //$fake_instance['settings']['relationships']['option1_vocabs'] = 5;
  287. $this->assertTrue(true);
  288. }
  289. }