entityreference.handlers.test 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. <?php
  2. /**
  3. * @file
  4. * Contains EntityReferenceHandlersTestCase
  5. */
  6. /**
  7. * Test for Entity Reference handlers.
  8. */
  9. class EntityReferenceHandlersTestCase extends DrupalWebTestCase {
  10. public static function getInfo() {
  11. return array(
  12. 'name' => 'Entity Reference Handlers',
  13. 'description' => 'Tests for the base handlers provided by Entity Reference.',
  14. 'group' => 'Entity Reference',
  15. );
  16. }
  17. public function setUp() {
  18. parent::setUp('entityreference');
  19. }
  20. protected function assertReferencable($field, $tests, $handler_name) {
  21. $handler = entityreference_get_selection_handler($field);
  22. foreach ($tests as $test) {
  23. foreach ($test['arguments'] as $arguments) {
  24. $result = call_user_func_array(array($handler, 'getReferencableEntities'), $arguments);
  25. $this->assertEqual($result, $test['result'], format_string('Valid result set returned by @handler.', array('@handler' => $handler_name)));
  26. $result = call_user_func_array(array($handler, 'countReferencableEntities'), $arguments);
  27. if (!empty($test['result'])) {
  28. $bundle = key($test['result']);
  29. $count = count($test['result'][$bundle]);
  30. }
  31. else {
  32. $count = 0;
  33. }
  34. $this->assertEqual($result, $count, format_string('Valid count returned by @handler.', array('@handler' => $handler_name)));
  35. }
  36. }
  37. }
  38. /**
  39. * Test the node-specific overrides of the entity handler.
  40. */
  41. public function testNodeHandler() {
  42. // Build a fake field instance.
  43. $field = array(
  44. 'translatable' => FALSE,
  45. 'entity_types' => array(),
  46. 'settings' => array(
  47. 'handler' => 'base',
  48. 'target_type' => 'node',
  49. 'handler_settings' => array(
  50. 'target_bundles' => array(),
  51. ),
  52. ),
  53. 'field_name' => 'test_field',
  54. 'type' => 'entityreference',
  55. 'cardinality' => '1',
  56. );
  57. // Build a set of test data.
  58. // Titles contain HTML-special characters to test escaping.
  59. $nodes = array(
  60. 'published1' => (object) array(
  61. 'type' => 'article',
  62. 'status' => 1,
  63. 'title' => 'Node published1 (<&>)',
  64. 'uid' => 1,
  65. ),
  66. 'published2' => (object) array(
  67. 'type' => 'article',
  68. 'status' => 1,
  69. 'title' => 'Node published2 (<&>)',
  70. 'uid' => 1,
  71. ),
  72. 'unpublished' => (object) array(
  73. 'type' => 'article',
  74. 'status' => 0,
  75. 'title' => 'Node unpublished (<&>)',
  76. 'uid' => 1,
  77. ),
  78. );
  79. $node_labels = array();
  80. foreach ($nodes as $key => $node) {
  81. node_save($node);
  82. $node_labels[$key] = check_plain($node->title);
  83. }
  84. // Test as a non-admin.
  85. $normal_user = $this->drupalCreateUser(array('access content'));
  86. $GLOBALS['user'] = $normal_user;
  87. $referencable_tests = array(
  88. array(
  89. 'arguments' => array(
  90. array(NULL, 'CONTAINS'),
  91. ),
  92. 'result' => array(
  93. 'article' => array(
  94. $nodes['published1']->nid => $node_labels['published1'],
  95. $nodes['published2']->nid => $node_labels['published2'],
  96. ),
  97. ),
  98. ),
  99. array(
  100. 'arguments' => array(
  101. array('published1', 'CONTAINS'),
  102. array('Published1', 'CONTAINS'),
  103. ),
  104. 'result' => array(
  105. 'article' => array(
  106. $nodes['published1']->nid => $node_labels['published1'],
  107. ),
  108. ),
  109. ),
  110. array(
  111. 'arguments' => array(
  112. array('published2', 'CONTAINS'),
  113. array('Published2', 'CONTAINS'),
  114. ),
  115. 'result' => array(
  116. 'article' => array(
  117. $nodes['published2']->nid => $node_labels['published2'],
  118. ),
  119. ),
  120. ),
  121. array(
  122. 'arguments' => array(
  123. array('invalid node', 'CONTAINS'),
  124. ),
  125. 'result' => array(),
  126. ),
  127. array(
  128. 'arguments' => array(
  129. array('Node unpublished', 'CONTAINS'),
  130. ),
  131. 'result' => array(),
  132. ),
  133. );
  134. $this->assertReferencable($field, $referencable_tests, 'Node handler');
  135. // Test as an admin.
  136. $admin_user = $this->drupalCreateUser(array('access content', 'bypass node access'));
  137. $GLOBALS['user'] = $admin_user;
  138. $referencable_tests = array(
  139. array(
  140. 'arguments' => array(
  141. array(NULL, 'CONTAINS'),
  142. ),
  143. 'result' => array(
  144. 'article' => array(
  145. $nodes['published1']->nid => $node_labels['published1'],
  146. $nodes['published2']->nid => $node_labels['published2'],
  147. $nodes['unpublished']->nid => $node_labels['unpublished'],
  148. ),
  149. ),
  150. ),
  151. array(
  152. 'arguments' => array(
  153. array('Node unpublished', 'CONTAINS'),
  154. ),
  155. 'result' => array(
  156. 'article' => array(
  157. $nodes['unpublished']->nid => $node_labels['unpublished'],
  158. ),
  159. ),
  160. ),
  161. );
  162. $this->assertReferencable($field, $referencable_tests, 'Node handler (admin)');
  163. }
  164. /**
  165. * Test the user-specific overrides of the entity handler.
  166. */
  167. public function testUserHandler() {
  168. // Build a fake field instance.
  169. $field = array(
  170. 'translatable' => FALSE,
  171. 'entity_types' => array(),
  172. 'settings' => array(
  173. 'handler' => 'base',
  174. 'target_type' => 'user',
  175. 'handler_settings' => array(
  176. 'target_bundles' => array(),
  177. ),
  178. ),
  179. 'field_name' => 'test_field',
  180. 'type' => 'entityreference',
  181. 'cardinality' => '1',
  182. );
  183. // Build a set of test data.
  184. $users = array(
  185. 'anonymous' => user_load(0),
  186. 'admin' => user_load(1),
  187. 'non_admin' => (object) array(
  188. 'name' => 'non_admin <&>',
  189. 'mail' => 'non_admin@example.com',
  190. 'roles' => array(),
  191. 'pass' => user_password(),
  192. 'status' => 1,
  193. ),
  194. 'blocked' => (object) array(
  195. 'name' => 'blocked <&>',
  196. 'mail' => 'blocked@example.com',
  197. 'roles' => array(),
  198. 'pass' => user_password(),
  199. 'status' => 0,
  200. ),
  201. );
  202. // The label of the anonymous user is variable_get('anonymous').
  203. $users['anonymous']->name = variable_get('anonymous', t('Anonymous'));
  204. $user_labels = array();
  205. foreach ($users as $key => $user) {
  206. if (!isset($user->uid)) {
  207. $users[$key] = $user = user_save(drupal_anonymous_user(), (array) $user);
  208. }
  209. $user_labels[$key] = check_plain($user->name);
  210. }
  211. // Test as a non-admin.
  212. $GLOBALS['user'] = $users['non_admin'];
  213. $referencable_tests = array(
  214. array(
  215. 'arguments' => array(
  216. array(NULL, 'CONTAINS'),
  217. ),
  218. 'result' => array(
  219. 'user' => array(
  220. $users['admin']->uid => $user_labels['admin'],
  221. $users['non_admin']->uid => $user_labels['non_admin'],
  222. ),
  223. ),
  224. ),
  225. array(
  226. 'arguments' => array(
  227. array('non_admin', 'CONTAINS'),
  228. array('NON_ADMIN', 'CONTAINS'),
  229. ),
  230. 'result' => array(
  231. 'user' => array(
  232. $users['non_admin']->uid => $user_labels['non_admin'],
  233. ),
  234. ),
  235. ),
  236. array(
  237. 'arguments' => array(
  238. array('invalid user', 'CONTAINS'),
  239. ),
  240. 'result' => array(),
  241. ),
  242. array(
  243. 'arguments' => array(
  244. array('blocked', 'CONTAINS'),
  245. ),
  246. 'result' => array(),
  247. ),
  248. );
  249. $this->assertReferencable($field, $referencable_tests, 'User handler');
  250. $GLOBALS['user'] = $users['admin'];
  251. $referencable_tests = array(
  252. array(
  253. 'arguments' => array(
  254. array(NULL, 'CONTAINS'),
  255. ),
  256. 'result' => array(
  257. 'user' => array(
  258. $users['anonymous']->uid => $user_labels['anonymous'],
  259. $users['admin']->uid => $user_labels['admin'],
  260. $users['non_admin']->uid => $user_labels['non_admin'],
  261. $users['blocked']->uid => $user_labels['blocked'],
  262. ),
  263. ),
  264. ),
  265. array(
  266. 'arguments' => array(
  267. array('blocked', 'CONTAINS'),
  268. ),
  269. 'result' => array(
  270. 'user' => array(
  271. $users['blocked']->uid => $user_labels['blocked'],
  272. ),
  273. ),
  274. ),
  275. array(
  276. 'arguments' => array(
  277. array('Anonymous', 'CONTAINS'),
  278. array('anonymous', 'CONTAINS'),
  279. ),
  280. 'result' => array(
  281. 'user' => array(
  282. $users['anonymous']->uid => $user_labels['anonymous'],
  283. ),
  284. ),
  285. ),
  286. );
  287. $this->assertReferencable($field, $referencable_tests, 'User handler (admin)');
  288. }
  289. /**
  290. * Test the comment-specific overrides of the entity handler.
  291. */
  292. public function testCommentHandler() {
  293. // Build a fake field instance.
  294. $field = array(
  295. 'translatable' => FALSE,
  296. 'entity_types' => array(),
  297. 'settings' => array(
  298. 'handler' => 'base',
  299. 'target_type' => 'comment',
  300. 'handler_settings' => array(
  301. 'target_bundles' => array(),
  302. ),
  303. ),
  304. 'field_name' => 'test_field',
  305. 'type' => 'entityreference',
  306. 'cardinality' => '1',
  307. );
  308. // Build a set of test data.
  309. $nodes = array(
  310. 'published' => (object) array(
  311. 'type' => 'article',
  312. 'status' => 1,
  313. 'title' => 'Node published',
  314. 'uid' => 1,
  315. ),
  316. 'unpublished' => (object) array(
  317. 'type' => 'article',
  318. 'status' => 0,
  319. 'title' => 'Node unpublished',
  320. 'uid' => 1,
  321. ),
  322. );
  323. foreach ($nodes as $node) {
  324. node_save($node);
  325. }
  326. $comments = array(
  327. 'published_published' => (object) array(
  328. 'nid' => $nodes['published']->nid,
  329. 'uid' => 1,
  330. 'cid' => NULL,
  331. 'pid' => 0,
  332. 'status' => COMMENT_PUBLISHED,
  333. 'subject' => 'Comment Published <&>',
  334. 'hostname' => ip_address(),
  335. 'language' => LANGUAGE_NONE,
  336. ),
  337. 'published_unpublished' => (object) array(
  338. 'nid' => $nodes['published']->nid,
  339. 'uid' => 1,
  340. 'cid' => NULL,
  341. 'pid' => 0,
  342. 'status' => COMMENT_NOT_PUBLISHED,
  343. 'subject' => 'Comment Unpublished <&>',
  344. 'hostname' => ip_address(),
  345. 'language' => LANGUAGE_NONE,
  346. ),
  347. 'unpublished_published' => (object) array(
  348. 'nid' => $nodes['unpublished']->nid,
  349. 'uid' => 1,
  350. 'cid' => NULL,
  351. 'pid' => 0,
  352. 'status' => COMMENT_NOT_PUBLISHED,
  353. 'subject' => 'Comment Published on Unpublished node <&>',
  354. 'hostname' => ip_address(),
  355. 'language' => LANGUAGE_NONE,
  356. ),
  357. );
  358. $comment_labels = array();
  359. foreach ($comments as $key => $comment) {
  360. comment_save($comment);
  361. $comment_labels[$key] = check_plain($comment->subject);
  362. }
  363. // Test as a non-admin.
  364. $normal_user = $this->drupalCreateUser(array('access content', 'access comments'));
  365. $GLOBALS['user'] = $normal_user;
  366. $referencable_tests = array(
  367. array(
  368. 'arguments' => array(
  369. array(NULL, 'CONTAINS'),
  370. ),
  371. 'result' => array(
  372. 'comment_node_article' => array(
  373. $comments['published_published']->cid => $comment_labels['published_published'],
  374. ),
  375. ),
  376. ),
  377. array(
  378. 'arguments' => array(
  379. array('Published', 'CONTAINS'),
  380. ),
  381. 'result' => array(
  382. 'comment_node_article' => array(
  383. $comments['published_published']->cid => $comment_labels['published_published'],
  384. ),
  385. ),
  386. ),
  387. array(
  388. 'arguments' => array(
  389. array('invalid comment', 'CONTAINS'),
  390. ),
  391. 'result' => array(),
  392. ),
  393. array(
  394. 'arguments' => array(
  395. array('Comment Unpublished', 'CONTAINS'),
  396. ),
  397. 'result' => array(),
  398. ),
  399. );
  400. $this->assertReferencable($field, $referencable_tests, 'Comment handler');
  401. // Test as a comment admin.
  402. $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments'));
  403. $GLOBALS['user'] = $admin_user;
  404. $referencable_tests = array(
  405. array(
  406. 'arguments' => array(
  407. array(NULL, 'CONTAINS'),
  408. ),
  409. 'result' => array(
  410. 'comment_node_article' => array(
  411. $comments['published_published']->cid => $comment_labels['published_published'],
  412. $comments['published_unpublished']->cid => $comment_labels['published_unpublished'],
  413. ),
  414. ),
  415. ),
  416. );
  417. $this->assertReferencable($field, $referencable_tests, 'Comment handler (comment admin)');
  418. // Test as a node and comment admin.
  419. $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access'));
  420. $GLOBALS['user'] = $admin_user;
  421. $referencable_tests = array(
  422. array(
  423. 'arguments' => array(
  424. array(NULL, 'CONTAINS'),
  425. ),
  426. 'result' => array(
  427. 'comment_node_article' => array(
  428. $comments['published_published']->cid => $comment_labels['published_published'],
  429. $comments['published_unpublished']->cid => $comment_labels['published_unpublished'],
  430. $comments['unpublished_published']->cid => $comment_labels['unpublished_published'],
  431. ),
  432. ),
  433. ),
  434. );
  435. $this->assertReferencable($field, $referencable_tests, 'Comment handler (comment + node admin)');
  436. }
  437. /**
  438. * Assert sorting by field works for non-admins.
  439. *
  440. * Since we are sorting on a field, we need to make sure the base-table
  441. * is added, and access-control is behaving as expected.
  442. */
  443. public function testSortByField() {
  444. // Add text field to entity, to sort by.
  445. $field_info = array(
  446. 'field_name' => 'field_text',
  447. 'type' => 'text',
  448. 'entity_types' => array('node'),
  449. );
  450. field_create_field($field_info);
  451. $instance = array(
  452. 'label' => 'Text Field',
  453. 'field_name' => 'field_text',
  454. 'entity_type' => 'node',
  455. 'bundle' => 'article',
  456. 'settings' => array(),
  457. 'required' => FALSE,
  458. );
  459. field_create_instance($instance);
  460. // Build a fake field instance.
  461. $field = array(
  462. 'translatable' => FALSE,
  463. 'entity_types' => array(),
  464. 'settings' => array(
  465. 'handler' => 'base',
  466. 'target_type' => 'node',
  467. 'handler_settings' => array(
  468. 'target_bundles' => array(),
  469. // Add sorting.
  470. 'sort' => array(
  471. 'type' => 'field',
  472. 'field' => 'field_text:value',
  473. 'direction' => 'DESC',
  474. ),
  475. ),
  476. ),
  477. 'field_name' => 'test_field',
  478. 'type' => 'entityreference',
  479. 'cardinality' => '1',
  480. );
  481. // Build a set of test data.
  482. $nodes = array(
  483. 'published1' => (object) array(
  484. 'type' => 'article',
  485. 'status' => 1,
  486. 'title' => 'Node published1 (<&>)',
  487. 'uid' => 1,
  488. 'field_text' => array(
  489. LANGUAGE_NONE => array(
  490. array(
  491. 'value' => 1,
  492. ),
  493. ),
  494. ),
  495. ),
  496. 'published2' => (object) array(
  497. 'type' => 'article',
  498. 'status' => 1,
  499. 'title' => 'Node published2 (<&>)',
  500. 'uid' => 1,
  501. 'field_text' => array(
  502. LANGUAGE_NONE => array(
  503. array(
  504. 'value' => 2,
  505. ),
  506. ),
  507. ),
  508. ),
  509. 'unpublished' => (object) array(
  510. 'type' => 'article',
  511. 'status' => 0,
  512. 'title' => 'Node unpublished (<&>)',
  513. 'uid' => 1,
  514. 'field_text' => array(
  515. LANGUAGE_NONE => array(
  516. array(
  517. 'value' => 3,
  518. ),
  519. ),
  520. ),
  521. ),
  522. );
  523. $node_labels = array();
  524. foreach ($nodes as $key => $node) {
  525. node_save($node);
  526. $node_labels[$key] = check_plain($node->title);
  527. }
  528. // Test as a non-admin.
  529. $normal_user = $this->drupalCreateUser(array('access content'));
  530. $GLOBALS['user'] = $normal_user;
  531. $handler = entityreference_get_selection_handler($field);
  532. // Not only assert the result, but make sure the keys are sorted as
  533. // expected.
  534. $result = $handler->getReferencableEntities();
  535. $expected_result = array(
  536. $nodes['published2']->nid => $node_labels['published2'],
  537. $nodes['published1']->nid => $node_labels['published1'],
  538. );
  539. $this->assertIdentical($result['article'], $expected_result, 'Query sorted by field returned expected values for non-admin.');
  540. }
  541. }