profile.test

Tests for profile.module.

File

drupal-7.x/modules/profile/profile.test
View source
  1. <?php
  2. /**
  3. * @file
  4. * Tests for profile.module.
  5. */
  6. /**
  7. * A class for common methods for testing profile fields.
  8. */
  9. class ProfileTestCase extends DrupalWebTestCase {
  10. protected $admin_user;
  11. protected $normal_user;
  12. function setUp() {
  13. parent::setUp('profile');
  14. variable_set('user_register', USER_REGISTER_VISITORS);
  15. $this->admin_user = $this->drupalCreateUser(array('administer users', 'access user profiles', 'administer blocks'));
  16. // This is the user whose profile will be edited.
  17. $this->normal_user = $this->drupalCreateUser();
  18. }
  19. /**
  20. * Create a profile field.
  21. *
  22. * @param $type
  23. * The field type to be created.
  24. * @param $category
  25. * The category in which the field should be created.
  26. * @param $edit
  27. * Additional parameters to be submitted.
  28. * @return
  29. * The fid of the field that was just created.
  30. */
  31. function createProfileField($type = 'textfield', $category = 'simpletest', $edit = array()) {
  32. $edit['title'] = $title = $this->randomName(8);
  33. $edit['name'] = $form_name = 'profile_' . $title;
  34. $edit['category'] = $category;
  35. $edit['explanation'] = $this->randomName(50);
  36. $this->drupalPost('admin/config/people/profile/add/' . $type, $edit, t('Save field'));
  37. $fid = db_query("SELECT fid FROM {profile_field} WHERE title = :title", array(':title' => $title))->fetchField();
  38. $this->assertTrue($fid, 'New Profile field has been entered in the database');
  39. // Check that the new field is appearing on the user edit form.
  40. $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
  41. // Checking field.
  42. if ($type == 'date') {
  43. $this->assertField($form_name . '[month]', 'Found month selection field');
  44. $this->assertField($form_name . '[day]', 'Found day selection field');
  45. $this->assertField($form_name . '[year]', 'Found day selection field');
  46. }
  47. else {
  48. $this->assertField($form_name , format_string('Found form named @name', array('@name' => $form_name)));
  49. }
  50. // Checking name.
  51. $this->assertText($title, format_string('Checking title for field %title', array('%title' => $title)));
  52. // Checking explanation.
  53. $this->assertText($edit['explanation'], format_string('Checking explanation for field %title', array('%title' => $title)));
  54. return array(
  55. 'fid' => $fid,
  56. 'type' => $type,
  57. 'form_name' => $form_name,
  58. 'title' => $title,
  59. 'category' => $category,
  60. );
  61. }
  62. /**
  63. * Update a profile field.
  64. *
  65. * @param $fid
  66. * The fid of the field to be updated.
  67. * @param $type
  68. * The type of field to be updated.
  69. * @param $edit
  70. * Field parameters to be submitted.
  71. * @return
  72. * Array representation of the updated field.
  73. */
  74. function updateProfileField($fid, $type = 'textfield', $edit = array()) {
  75. $form_name = $edit['name'];
  76. $title = $edit['title'];
  77. $category = $edit['category'];
  78. $this->drupalPost('admin/config/people/profile/edit/' . $fid, $edit, t('Save field'));
  79. // Check that the updated field is appearing on the user edit form.
  80. $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
  81. // Checking field.
  82. if ($type == 'date') {
  83. $this->assertField($form_name . '[month]', 'Found month selection field');
  84. $this->assertField($form_name . '[day]', 'Found day selection field');
  85. $this->assertField($form_name . '[year]', 'Found day selection field');
  86. }
  87. else {
  88. $this->assertField($form_name , format_string('Found form named @name', array('@name' => $form_name)));
  89. }
  90. // Checking name.
  91. $this->assertText($title, format_string('Checking title for field %title', array('%title' => $title)));
  92. // Checking explanation.
  93. $this->assertText($edit['explanation'], format_string('Checking explanation for field %title', array('%title' => $title)));
  94. return array(
  95. 'fid' => $fid,
  96. 'type' => $type,
  97. 'form_name' => $form_name,
  98. 'title' => $title,
  99. 'category' => $category,
  100. );
  101. }
  102. /**
  103. * Set the profile field to a random value
  104. *
  105. * @param $field
  106. * The field that should be set.
  107. * @param $value
  108. * The value for the field, defaults to a random string.
  109. * @return
  110. * The value that has been assigned to
  111. */
  112. function setProfileField($field, $value = NULL) {
  113. if (!isset($value)) {
  114. $value = $this->randomName();
  115. }
  116. $edit = array(
  117. $field['form_name'] => $value,
  118. );
  119. $this->drupalPost('user/' . $this->normal_user->uid . '/edit/' . $field['category'], $edit, t('Save'));
  120. // Check profile page.
  121. $content = $this->drupalGet('user/' . $this->normal_user->uid);
  122. $this->assertText($field['title'], format_string('Found profile field with title %title', array('%title' => $field['title'])));
  123. if ($field['type'] != 'checkbox') {
  124. // $value must be cast to a string in order to be found by assertText.
  125. $this->assertText("$value", format_string('Found profile field with value %value', array('%value' => $value)));
  126. }
  127. return $value;
  128. }
  129. /**
  130. * Delete a profile field.
  131. *
  132. * @param $field
  133. * The field to be deleted.
  134. */
  135. function deleteProfileField($field) {
  136. $this->drupalPost('admin/config/people/profile/delete/' . $field['fid'], array(), t('Delete'));
  137. $this->drupalGet('admin/config/people/profile');
  138. $this->assertNoText($field['title'], format_string('Checking deleted field %title', array('%title' => $field['title'])));
  139. }
  140. }
  141. class ProfileTestFields extends ProfileTestCase {
  142. public static function getInfo() {
  143. return array(
  144. 'name' => 'Test single fields',
  145. 'description' => 'Testing profile module with add/edit/delete textfield, textarea, list, checkbox, and url fields into profile page',
  146. 'group' => 'Profile'
  147. );
  148. }
  149. /**
  150. * Test each of the field types. List selection and date fields are tested
  151. * separately because they need some special handling.
  152. */
  153. function testProfileFields() {
  154. $this->drupalLogin($this->admin_user);
  155. // Set test values for every field type.
  156. $field_types = array(
  157. 'textfield' => $this->randomName(),
  158. 'textarea' => $this->randomName(),
  159. 'list' => $this->randomName(),
  160. 'checkbox' => 1,
  161. // An underscore is an invalid character in a domain name. The method randomName can
  162. // return an underscore.
  163. 'url' => 'http://www.' . str_replace('_', '', $this->randomName(10)) . '.org',
  164. );
  165. // For each field type, create a field, give it a value, update the field,
  166. // and delete the field.
  167. foreach ($field_types as $type => $value) {
  168. $field = $this->createProfileField($type);
  169. $this->setProfileField($field, $value);
  170. $edit = array(
  171. 'name' => $field['form_name'],
  172. 'title' => $this->randomName(),
  173. 'category' => $field['category'],
  174. 'explanation' => $this->randomName(),
  175. );
  176. $field = $this->updateProfileField($field['fid'], $field['type'], $edit);
  177. $this->deleteProfileField($field);
  178. }
  179. }
  180. }
  181. class ProfileTestSelect extends ProfileTestCase {
  182. public static function getInfo() {
  183. return array(
  184. 'name' => 'Test select field',
  185. 'description' => 'Testing profile module with add/edit/delete a select field',
  186. 'group' => 'Profile'
  187. );
  188. }
  189. /**
  190. * Create a list selection field, give it a value, update and delete the field.
  191. */
  192. function testProfileSelectionField() {
  193. $this->drupalLogin($this->admin_user);
  194. $edit = array(
  195. 'options' => implode("\n", range(1, 10)),
  196. );
  197. $field = $this->createProfileField('selection', 'simpletest', $edit);
  198. $this->setProfileField($field, rand(1, 10));
  199. $edit = array(
  200. 'name' => $field['form_name'],
  201. 'title' => $this->randomName(),
  202. 'category' => $field['category'],
  203. 'explanation' => $this->randomName(),
  204. );
  205. $field = $this->updateProfileField($field['fid'], $field['type'], $edit);
  206. $this->deleteProfileField($field);
  207. }
  208. }
  209. class ProfileTestDate extends ProfileTestCase {
  210. public static function getInfo() {
  211. return array(
  212. 'name' => 'Test date field',
  213. 'description' => 'Testing profile module with add/edit/delete a date field',
  214. 'group' => 'Profile'
  215. );
  216. }
  217. /**
  218. * Create a date field, give it a value, update and delete the field.
  219. */
  220. function testProfileDateField() {
  221. $this->drupalLogin($this->admin_user);
  222. variable_set('date_format_short', 'm/d/Y - H:i');
  223. $field = $this->createProfileField('date');
  224. // Set date to January 09, 1983
  225. $edit = array(
  226. $field['form_name'] . '[month]' => 1,
  227. $field['form_name'] . '[day]' => 9,
  228. $field['form_name'] . '[year]' => 1983,
  229. );
  230. $this->drupalPost('user/' . $this->normal_user->uid . '/edit/' . $field['category'], $edit, t('Save'));
  231. // Check profile page.
  232. $this->drupalGet('user/' . $this->normal_user->uid);
  233. $this->assertText($field['title'], format_string('Found profile field with title %title', array('%title' => $field['title'])));
  234. $this->assertText('01/09/1983', 'Found date profile field.');
  235. $edit = array(
  236. 'name' => $field['form_name'],
  237. 'title' => $this->randomName(),
  238. 'category' => $field['category'],
  239. 'explanation' => $this->randomName(),
  240. );
  241. $field = $this->updateProfileField($field['fid'], $field['type'], $edit);
  242. $this->deleteProfileField($field);
  243. }
  244. }
  245. class ProfileTestWeights extends ProfileTestCase {
  246. public static function getInfo() {
  247. return array(
  248. 'name' => 'Test field weights',
  249. 'description' => 'Testing profile modules weigting of fields',
  250. 'group' => 'Profile'
  251. );
  252. }
  253. function testProfileFieldWeights() {
  254. $this->drupalLogin($this->admin_user);
  255. $category = $this->randomName();
  256. $field1 = $this->createProfileField('textfield', $category, array('weight' => 1));
  257. $field2 = $this->createProfileField('textfield', $category, array('weight' => -1));
  258. $this->setProfileField($field1, $this->randomName(8));
  259. $this->setProfileField($field2, $this->randomName(8));
  260. $profile_edit = $this->drupalGet('user/' . $this->normal_user->uid . '/edit/' . $category);
  261. $this->assertTrue(strpos($profile_edit, $field1['title']) > strpos($profile_edit, $field2['title']), 'Profile field weights are respected on the user edit form.');
  262. $profile_page = $this->drupalGet('user/' . $this->normal_user->uid);
  263. $this->assertTrue(strpos($profile_page, $field1['title']) > strpos($profile_page, $field2['title']), 'Profile field weights are respected on the user profile page.');
  264. }
  265. }
  266. /**
  267. * Test profile field autocompletion and access.
  268. */
  269. class ProfileTestAutocomplete extends ProfileTestCase {
  270. public static function getInfo() {
  271. return array(
  272. 'name' => 'Autocompletion',
  273. 'description' => 'Test profile fields with autocompletion.',
  274. 'group' => 'Profile'
  275. );
  276. }
  277. /**
  278. * Tests profile field autocompletion and access.
  279. */
  280. function testAutocomplete() {
  281. $this->drupalLogin($this->admin_user);
  282. // Create a new profile field with autocompletion enabled.
  283. $category = $this->randomName();
  284. $field = $this->createProfileField('textfield', $category, array('weight' => 1, 'autocomplete' => 1));
  285. // Enter profile field value.
  286. $field['value'] = $this->randomName();
  287. $this->setProfileField($field, $field['value']);
  288. // Set some html for what we want to see in the page output later.
  289. $autocomplete_html = '<input type="hidden" id="' . drupal_html_id('edit-' . $field['form_name'] . '-autocomplete') . '" value="' . url('profile/autocomplete/' . $field['fid'], array('absolute' => TRUE)) . '" disabled="disabled" class="autocomplete" />';
  290. $field_html = '<input type="text" maxlength="255" name="' . $field['form_name'] . '" id="' . drupal_html_id('edit-' . $field['form_name']) . '" size="60" value="' . $field['value'] . '" class="form-text form-autocomplete required" />';
  291. // Check that autocompletion html is found on the user's profile edit page.
  292. $this->drupalGet('user/' . $this->admin_user->uid . '/edit/' . $category);
  293. $this->assertRaw($autocomplete_html, 'Autocomplete found.');
  294. $this->assertRaw('misc/autocomplete.js', 'Autocomplete JavaScript found.');
  295. $this->assertRaw('class="form-text form-autocomplete"', 'Autocomplete form element class found.');
  296. // Check the autocompletion path using the first letter of our user's profile
  297. // field value to make sure access is allowed and a valid result if found.
  298. $this->drupalGet('profile/autocomplete/' . $field['fid'] . '/' . $field['value'][0]);
  299. $this->assertResponse(200, 'Autocomplete path allowed to user with permission.');
  300. $this->assertRaw($field['value'], 'Autocomplete value found.');
  301. // Logout and login with a user without the 'access user profiles' permission.
  302. $this->drupalLogout();
  303. $this->drupalLogin($this->normal_user);
  304. // Check that autocompletion html is not found on the user's profile edit page.
  305. $this->drupalGet('user/' . $this->normal_user->uid . '/edit/' . $category);
  306. $this->assertNoRaw($autocomplete_html, 'Autocomplete not found.');
  307. // User should be denied access to the profile autocomplete path.
  308. $this->drupalGet('profile/autocomplete/' . $field['fid'] . '/' . $field['value'][0]);
  309. $this->assertResponse(403, 'Autocomplete path denied to user without permission.');
  310. }
  311. }
  312. class ProfileBlockTestCase extends ProfileTestCase {
  313. public static function getInfo() {
  314. return array(
  315. 'name' => 'Block availability',
  316. 'description' => 'Check if the Author Information block is available.',
  317. 'group' => 'Profile',
  318. );
  319. }
  320. function setUp() {
  321. parent::setUp();
  322. // Login the admin user.
  323. $this->drupalLogin($this->admin_user);
  324. // Create two fields.
  325. $category = $this->randomName();
  326. $this->field1 = $this->createProfileField('textfield', $category, array('weight' => 0));
  327. $this->field2 = $this->createProfileField('textfield', $category, array('weight' => 1));
  328. // Assign values to those fields.
  329. $this->value1 = $this->setProfileField($this->field1);
  330. $this->value2 = $this->setProfileField($this->field2);
  331. // Create a node authored by the normal user.
  332. $this->node = $this->drupalCreateNode(array(
  333. 'uid' => $this->normal_user->uid,
  334. ));
  335. }
  336. function testAuthorInformationBlock() {
  337. // Set the block to a region to confirm the block is available.
  338. $edit = array();
  339. $edit['blocks[profile_author-information][region]'] = 'footer';
  340. $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
  341. $this->assertText(t('The block settings have been updated.'), 'Block successfully move to footer region.');
  342. // Enable field 1.
  343. $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
  344. 'profile_block_author_fields[' . $this->field1['form_name'] . ']' => TRUE,
  345. ), t('Save block'));
  346. $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
  347. // Visit the node and confirm that the field is displayed.
  348. $this->drupalGet('node/' . $this->node->nid);
  349. $this->assertRaw($this->value1, 'Field 1 is displayed');
  350. $this->assertNoRaw($this->value2, 'Field 2 is not displayed');
  351. // Enable only field 2.
  352. $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
  353. 'profile_block_author_fields[' . $this->field1['form_name'] . ']' => FALSE,
  354. 'profile_block_author_fields[' . $this->field2['form_name'] . ']' => TRUE,
  355. ), t('Save block'));
  356. $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
  357. // Visit the node and confirm that the field is displayed.
  358. $this->drupalGet('node/' . $this->node->nid);
  359. $this->assertNoRaw($this->value1, 'Field 1 is not displayed');
  360. $this->assertRaw($this->value2, 'Field 2 is displayed');
  361. // Enable both fields.
  362. $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
  363. 'profile_block_author_fields[' . $this->field1['form_name'] . ']' => TRUE,
  364. 'profile_block_author_fields[' . $this->field2['form_name'] . ']' => TRUE,
  365. ), t('Save block'));
  366. $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
  367. // Visit the node and confirm that the field is displayed.
  368. $this->drupalGet('node/' . $this->node->nid);
  369. $this->assertRaw($this->value1, 'Field 1 is displayed');
  370. $this->assertRaw($this->value2, 'Field 2 is displayed');
  371. // Enable the link to the user profile.
  372. $this->drupalPost('admin/structure/block/manage/profile/author-information/configure', array(
  373. 'profile_block_author_fields[user_profile]' => TRUE,
  374. ), t('Save block'));
  375. $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
  376. // Visit the node and confirm that the user profile link is displayed.
  377. $this->drupalGet('node/' . $this->node->nid);
  378. $this->clickLink(t('View full user profile'));
  379. $this->assertEqual($this->getUrl(), url('user/' . $this->normal_user->uid, array('absolute' => TRUE)));
  380. }
  381. }
  382. /**
  383. * Test profile browsing.
  384. */
  385. class ProfileTestBrowsing extends ProfileTestCase {
  386. public static function getInfo() {
  387. return array(
  388. 'name' => 'Profile browsing',
  389. 'description' => 'Test profile browsing.',
  390. 'group' => 'Profile',
  391. );
  392. }
  393. /**
  394. * Test profile browsing.
  395. */
  396. function testProfileBrowsing() {
  397. $this->drupalLogin($this->admin_user);
  398. $field = $this->createProfileField('list', 'simpletest', array('page' => '%value'));
  399. // Set a random value for the profile field.
  400. $value = $this->setProfileField($field);
  401. // Check that user is found on the profile browse page.
  402. $this->drupalGet("profile/{$field['form_name']}/$value");
  403. $this->assertText($this->normal_user->name);
  404. }
  405. }
  406. /**
  407. * Test profile integration with user CRUD operations.
  408. */
  409. class ProfileCrudTestCase extends ProfileTestCase {
  410. public static function getInfo() {
  411. return array(
  412. 'name' => 'Profile CRUD tests',
  413. 'description' => 'Test profile integration with user create, read, update, delete.',
  414. 'group' => 'Profile',
  415. );
  416. }
  417. /**
  418. * Test profile integration with user CRUD operations.
  419. */
  420. public function testUserCRUD() {
  421. // @todo Add profile fields in addition to base user properties.
  422. $edit = array(
  423. 'name' => 'Test user',
  424. 'mail' => 'test@example.com',
  425. );
  426. // Create.
  427. // @todo Add assertions.
  428. $account = user_save(NULL, $edit);
  429. // Read.
  430. // @todo Add assertions.
  431. $account = user_load($account->uid);
  432. // Update.
  433. // @todo Add assertions.
  434. $account = user_save($account, $edit);
  435. // Delete.
  436. // @todo Add assertions.
  437. user_delete($account->uid);
  438. }
  439. }
  440. /**
  441. * TODO:
  442. * - Test field visibility
  443. * - Test required fields
  444. * - Test fields on registration form
  445. * - Test updating fields
  446. */