faq.test 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <?php
  2. /**
  3. * @file
  4. * Test FAQ functionality Base test class. All tests inherits this one.
  5. * Hugely based on code from the test file block.test by boombatower
  6. */
  7. /**
  8. * Base class that is extended by test cases
  9. */
  10. class FaqTestCase extends DrupalWebTestCase {
  11. protected $admin_user, $faq_user;
  12. protected $taxonomy;
  13. protected $term, $faq1, $faq2;
  14. /**
  15. * Implementation of getInfo().
  16. */
  17. public static function getInfo() {
  18. return array(
  19. 'name' => t('FAQ functionality'),
  20. 'description' => t('Base class. No tests here.'),
  21. 'group' => t('Frequently Asked Questions'),
  22. );
  23. }
  24. /**
  25. * Implementation of setUp().
  26. */
  27. function setUp() {
  28. // Install FAQ Module.
  29. parent::setUp('taxonomy', 'faq');
  30. // Create and log in user with administer taxonomy permissions.
  31. $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'administer faq', 'administer faq order', 'administer blocks'));
  32. $this->drupalLogin($this->admin_user);
  33. $this->faq_user = $this->drupalCreateUser(array('create faq content', 'edit any faq content', 'delete any faq content', 'view faq page', 'access content'));
  34. // Set up the vocab and terms.
  35. $this->setupTaxonomy();
  36. // Categorize questions.
  37. $this->drupalPost('admin/config/content/faq/categories', array('faq_use_categories' => '1'), t('Save configuration'));
  38. // Set answer_user as default expert.
  39. $roles = $this->faq_user->roles;
  40. end($roles); // Set to last role (the unique one)
  41. // Start all tests logged out.
  42. $this->drupalLogout();
  43. }
  44. /**
  45. * Tear the whole thing down again
  46. */
  47. function tearDown() {
  48. // Things to tidy up like vars and stuff
  49. parent::tearDown();
  50. }
  51. /**
  52. * Generates a random string of ASCII numeric characters (values 48 to 57).
  53. *
  54. * @param $length
  55. * Length of random string to generate .
  56. * @return
  57. * Randomly generated string.
  58. */
  59. protected static function randomNumber($length = 8) {
  60. $str = '';
  61. for ($i = 0; $i < $length; $i++) {
  62. $str .= chr(mt_rand(48, 57));
  63. }
  64. return $str;
  65. }
  66. /**
  67. * Verify that current user has no access to page.
  68. *
  69. * @param $url
  70. * URL to verify.
  71. */
  72. function faqVerifyNoAccess($url) {
  73. // Test that page returns 403 Access Denied
  74. $this->drupalGet($url);
  75. $this->assertResponse(403);
  76. }
  77. /**
  78. * Set up the taxonomy - all vocabularies and stuff
  79. * Values also stored in protected variable $tax
  80. */
  81. function setupTaxonomy() {
  82. // Create vocabulary.
  83. $this->vocabulary = $vocabulary = new stdClass();
  84. $vocabulary->name = $this->randomName(8);
  85. $vocabulary->description = $this->randomName(64);
  86. $vocabulary->machine_name = drupal_strtolower($this->randomName());
  87. $vocabulary->help = '';
  88. $vocabulary->nodes = array('faq' => 'faq');
  89. $vocabulary->weight = mt_rand(0, 10);
  90. taxonomy_vocabulary_save($vocabulary);
  91. $field = array(
  92. 'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
  93. 'type' => 'taxonomy_term_reference',
  94. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  95. 'settings' => array(
  96. 'allowed_values' => array(
  97. array(
  98. 'vocabulary' => $this->vocabulary->machine_name,
  99. 'parent' => 0,
  100. ),
  101. ),
  102. ),
  103. );
  104. field_create_field($field);
  105. $this->instance = array(
  106. 'field_name' => 'taxonomy_' . $this->vocabulary->machine_name,
  107. 'bundle' => 'faq',
  108. 'entity_type' => 'node',
  109. 'widget' => array(
  110. 'type' => 'taxonomy_autocomplete',
  111. ),
  112. 'display' => array(
  113. 'default' => array(
  114. 'type' => 'taxonomy_term_reference_link',
  115. ),
  116. ),
  117. );
  118. field_create_instance($this->instance);
  119. // Add term
  120. // Click the last occurrence of the link.
  121. $this->term = $term = new stdClass();
  122. $term->name = $this->randomName(8);
  123. $term->description = $this->randomName(64);
  124. // Use the first available text format.
  125. $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField();
  126. $term->vid = $vocabulary->vid;
  127. taxonomy_term_save($term);
  128. }
  129. /**
  130. * Test accessing the FAQ page
  131. */
  132. }
  133. class FaqAccessTestClass extends FaqTestCase {
  134. /**
  135. * Implementation of getInfo().
  136. */
  137. public static function getInfo() {
  138. return array(
  139. 'name' => t('Access to FAQ pages'),
  140. 'description' => t('Access to pages by anonymous user and logged in user with rights.'),
  141. 'group' => t('Frequently Asked Questions'),
  142. );
  143. }
  144. function testFaqAccess() {
  145. // Verify that anonymous user has no access to the faq page
  146. $this->faqVerifyNoAccess(_faq_path());
  147. // Create and login user
  148. $normal_user = $this->drupalCreateUser();
  149. $this->drupalLogin($normal_user);
  150. // Verify that logged in user has no access to the faq page
  151. $this->faqVerifyNoAccess(_faq_path());
  152. $this->drupalLogout();
  153. $view_faq_user = $this->drupalCreateUser(array('view faq page'));
  154. $this->drupalLogin($view_faq_user);
  155. // Verify that the faq page is visible and available but empty
  156. $this->drupalGet(_faq_path());
  157. $this->assertText(t('Frequently Asked Questions'), t('FAQ page is available for view faq page permissions.'));
  158. }
  159. }
  160. class CreateFaqTestCase extends FaqTestCase {
  161. /**
  162. * Implementation of getInfo().
  163. */
  164. public static function getInfo() {
  165. return array(
  166. 'name' => t('Create FAQ node'),
  167. 'description' => t('Add, edit and delete FAQ nodes when FAQ module is enabled.'),
  168. 'group' => t('Frequently Asked Questions'),
  169. );
  170. }
  171. /**
  172. * Test creating a FAQ node
  173. *
  174. * This test creates a faq with detailed question shown and labeled questions and answers
  175. */
  176. function testFaqCreate() {
  177. // Create and log in user with create FAQ permissions
  178. $this->drupalLogin($this->admin_user);
  179. // Show the detailed question
  180. $this->drupalGet('admin/config/content/faq/questions');
  181. // Set faq to allow long question text and labeled questions and answers
  182. $this->drupalPost('admin/config/content/faq/questions', array('faq_question_long_form' => '1', 'faq_qa_mark' => '1'), t('Save configuration'));
  183. $this->drupalPost('admin/config/content/faq/questions', array('faq_question_length' => 'both'), t('Save configuration'));
  184. $this->afaq_user = $this->drupalCreateUser(array('create faq content', 'view faq page'));
  185. $this->drupalLogin($this->afaq_user);
  186. // Verify that the faq page is visible and available but empty
  187. $this->drupalGet(_faq_path());
  188. $this->assertText(t('Frequently Asked Questions'), t('FAQ page is available for view faq page permissions.'));
  189. // Fill in the Create FAQ node 1 form and post it
  190. $langcode = LANGUAGE_NONE;
  191. $this->faq1 = array();
  192. $this->faq1['title'] = 'faq1_'. $this->randomName(8);
  193. $this->faq1[$this->instance['field_name'] . '[' . $langcode .']'] = $this->term->name;
  194. $this->faq1["field_detailed_question[$langcode][0][value]"] = $this->randomName(16);
  195. $this->faq1["body[$langcode][0][value]"] = $this->randomName(16);
  196. $this->drupalPost('node/add/faq', $this->faq1, t('Save'));
  197. // Check that new FAQ node has actually been created
  198. $this->assertText(t('FAQ @title has been created.', array('@title' => $this->faq1['title'])));
  199. // Check that faq is found on the correct taxonomy term page too
  200. $this->drupalGet('taxonomy/term/' . $this->term->tid);
  201. $this->assertText(t('@title', array('@title' => $this->faq1['title'])));
  202. // Fill in the Create FAQ node 2 form and post it
  203. $this->faq2 = array();
  204. $this->faq2['title'] = 'faq2_'. $this->randomName(8);
  205. $this->faq2[$this->instance['field_name'] . '[' . $langcode .']'] = $this->randomName(8); // Add new term
  206. $this->faq2["field_detailed_question[$langcode][0][value]"] = $this->randomName(16);
  207. $this->faq2["body[$langcode][0][value]"] = $this->randomName(16);
  208. $this->drupalPost('node/add/faq', $this->faq2, t('Save'));
  209. // Check that new FAQ node has actually been created
  210. $this->assertText(t('FAQ @title has been created.', array('@title' => $this->faq2['title'])));
  211. // New user
  212. $this->drupalLogout();
  213. // Verify that logged in user has no access to the faq page
  214. $this->faqVerifyNoAccess(_faq_path());
  215. // Check that the FAQ page is available and that the correct term is listed as grouping for the new FAQ node
  216. $view_faq_user = $this->drupalCreateUser(array('view faq page'));
  217. $this->drupalLogin($view_faq_user);
  218. $this->drupalGet(_faq_path());
  219. $this->assertText(t('Frequently Asked Questions'), t('FAQ page is available for view faq page permissions.'));
  220. $this->assertText($this->faq1['title'], t('Created FAQ node 1 available on FAQ page.'));
  221. $this->assertText($this->faq1[$this->instance['field_name'] . '[' . $langcode .']'], t('Term for node 1 available on FAQ page.'));
  222. $this->assertText($this->faq2['title'], t('Created FAQ node 2 available on FAQ page.'));
  223. $this->assertText($this->faq2[$this->instance['field_name'] . '[' . $langcode .']'], t('Term for node 2 available on FAQ page.'));
  224. // Navigate to FAQ node created on FAQ page
  225. $this->clickLink(t($this->faq1['title']));
  226. $this->assertText(t($this->faq1["field_detailed_question[$langcode][0][value]"]), t('Detailed question visible')); // Dependant on the question setting
  227. $this->assertText(t($this->faq1["body[$langcode][0][value]"]), t('Answer visible'));
  228. // Enable categorisation of FAQ nodes
  229. // Create and log in user with create and administer FAQ permissions
  230. $this->admin_user = $this->drupalCreateUser(array('create faq content', 'view faq page', 'administer faq'));
  231. $this->drupalLogin($this->admin_user);
  232. // faq_use_categories
  233. $faqcfg = array();
  234. $faqcfg['faq_use_categories'] = '1'; // Enable categorised FAQs
  235. $this->drupalPost('admin/config/content/faq/categories', $faqcfg, t('Save configuration'));
  236. $this->drupalLogout();
  237. $this->drupalLogin($view_faq_user);
  238. $this->drupalGet(_faq_path());
  239. $this->assertText(t('Frequently Asked Questions'), t('FAQ page is available for view faq page permissions.'));
  240. $this->assertText($this->faq1['title'], t('Created FAQ node 1 available on FAQ page.'));
  241. $this->assertText($this->faq1[$this->instance['field_name'] . '[' . $langcode .']'], t('Term for node 1 not available on FAQ page.'));
  242. $this->assertText($this->faq2['title'], t('Created FAQ node 2 available on FAQ page.'));
  243. $this->assertText($this->faq2[$this->instance['field_name'] . '[' . $langcode .']'], t('Term for node 2 not available on FAQ page.'));
  244. // TODO: Add update and Delete of FAQ nodes
  245. }
  246. }
  247. class CRAUDFaqTestCase extends FaqTestCase {
  248. /**
  249. * Implementation of getInfo().
  250. */
  251. public static function getInfo() {
  252. return array(
  253. 'name' => t('CRUD Question'),
  254. 'description' => t('Create, read, update and delete a question'),
  255. 'group' => t('Frequently Asked Questions'),
  256. );
  257. }
  258. /**
  259. * Test creating an FAQ and verify its status
  260. */
  261. public function testFaqCreate() {
  262. // Verify that logged in user has no access to the faq page
  263. $this->faqVerifyNoAccess(_faq_path());
  264. // Log in user with create FAQ permissions
  265. $this->drupalLogin($this->faq_user);
  266. // Create a FAQ node.
  267. $edit = array();
  268. $edit['title'] = $this->randomName(8);
  269. $edit[$this->instance['field_name'] . '['. LANGUAGE_NONE .']'] = $this->randomName(8);
  270. $edit['field_detailed_question['. LANGUAGE_NONE .'][0][value]'] = $this->randomName(64);
  271. $edit['body['. LANGUAGE_NONE .'][0][value]'] = $this->randomString(264);
  272. $this->drupalPost('node/add/faq', $edit, t('Save'));
  273. $this->assertText(t('FAQ @title has been created.', array('@title' => $edit['title'])));
  274. // Check status for FAQ node - should be published
  275. $node = $this->drupalGetNodeByTitle($edit['title']);
  276. $this->assertTrue($node->status);
  277. $this->drupalLogout();
  278. // Verify that anonymous user has no access to the unanswered node display
  279. // $this->faqVerifyNoAccess('node/' . $node->nid);
  280. $this->drupalGet('node/' . $node->nid . '/edit'); // Open edit page with node
  281. // $this->assertResponse(200);
  282. // Create and log in user with view FAQ permissions
  283. $faq_view_user = $this->drupalCreateUser(array('view faq page'));
  284. $this->drupalLogin($faq_view_user);
  285. // Verify visibility on faq page
  286. $this->drupalGet(_faq_path()); // Load faq page
  287. $this->assertText($edit['title']); // Node should be listed here
  288. $this->drupalGet('node/' . $node->nid); // It should also be possible to open the node directly
  289. // Update FAQ
  290. // Log in user with answer question. Must also have edit any faq content and view faq page permissions.
  291. $this->drupalLogin($this->faq_user);
  292. $edit2['title'] = 'title-' . $this->randomName(8);
  293. $edit2['body['. LANGUAGE_NONE .'][0][value]'] = 'body-' . $this->randomName(64);
  294. $this->drupalPost('node/' . $node->nid . '/edit', $edit2, t('Save'));
  295. $this->assertText(t('FAQ @title has been updated.', array('@title' => $edit2['title'])));
  296. $this->assertText($edit2['title'], 'Title has changed');
  297. $this->assertText($edit2['body['. LANGUAGE_NONE .'][0][value]'], 'Body has changed');
  298. // Delete FAQ
  299. // Try deleting faq by edit faq permission
  300. $this->drupalPost('node/' . $node->nid . '/edit', array(), t('Delete'));
  301. // Log in user with delete FAQ permissions
  302. $this->drupalLogin($this->admin_user);
  303. $this->drupalPost('node/' . $node->nid . '/edit', array(), t('Delete'));
  304. $this->assertText(t('Are you sure you want to delete @title?', array('@title' => $edit2['title'])));
  305. $this->drupalPost('node/' . $node->nid . '/delete', array(), t('Delete'));
  306. $this->assertText(t('FAQ @title has been deleted.', array('@title' => $edit2['title'])));
  307. }
  308. }