cms/drupal/modules/poll/poll.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Tests for poll.module.
       
     6  */
       
     7 
       
     8 class PollTestCase extends DrupalWebTestCase {
       
     9 
       
    10   /**
       
    11    * Creates a poll.
       
    12    *
       
    13    * @param string $title
       
    14    *   The title of the poll.
       
    15    * @param array $choices
       
    16    *   A list of choice labels.
       
    17    * @param boolean $preview
       
    18    *   (optional) Whether to test if the preview is working or not. Defaults to
       
    19    *   TRUE.
       
    20    *
       
    21    * @return
       
    22    *   The node id of the created poll, or FALSE on error.
       
    23    */
       
    24   function pollCreate($title, $choices, $preview = TRUE) {
       
    25     $this->assertTrue(TRUE, 'Create a poll');
       
    26 
       
    27     $admin_user = $this->drupalCreateUser(array('create poll content', 'administer nodes'));
       
    28     $web_user = $this->drupalCreateUser(array('create poll content', 'access content', 'edit own poll content'));
       
    29     $this->drupalLogin($admin_user);
       
    30 
       
    31     // Get the form first to initialize the state of the internal browser.
       
    32     $this->drupalGet('node/add/poll');
       
    33 
       
    34     // Prepare a form with two choices.
       
    35     list($edit, $index) = $this->_pollGenerateEdit($title, $choices);
       
    36 
       
    37     // Verify that the vote count element only allows non-negative integers.
       
    38     $edit['choice[new:1][chvotes]'] = -1;
       
    39     $edit['choice[new:0][chvotes]'] = $this->randomString(7);
       
    40     $this->drupalPost(NULL, $edit, t('Save'));
       
    41     $this->assertText(t('Negative values are not allowed.'));
       
    42     $this->assertText(t('Vote count for new choice must be an integer.'));
       
    43 
       
    44     // Repeat steps for initializing the state of the internal browser.
       
    45     $this->drupalLogin($web_user);
       
    46     $this->drupalGet('node/add/poll');
       
    47     list($edit, $index) = $this->_pollGenerateEdit($title, $choices);
       
    48 
       
    49     // Re-submit the form until all choices are filled in.
       
    50     if (count($choices) > 2) {
       
    51       while ($index < count($choices)) {
       
    52         $this->drupalPost(NULL, $edit, t('More choices'));
       
    53         $this->assertPollChoiceOrder($choices, $index);
       
    54         list($edit, $index) = $this->_pollGenerateEdit($title, $choices, $index);
       
    55       }
       
    56     }
       
    57 
       
    58     if ($preview) {
       
    59       $this->drupalPost(NULL, $edit, t('Preview'));
       
    60       $this->assertPollChoiceOrder($choices, $index, TRUE);
       
    61       list($edit, $index) = $this->_pollGenerateEdit($title, $choices, $index);
       
    62     }
       
    63 
       
    64     $this->drupalPost(NULL, $edit, t('Save'));
       
    65     $node = $this->drupalGetNodeByTitle($title);
       
    66     $this->assertText(t('@type @title has been created.', array('@type' => node_type_get_name('poll'), '@title' => $title)), 'Poll has been created.');
       
    67     $this->assertTrue($node->nid, 'Poll has been found in the database.');
       
    68 
       
    69     return isset($node->nid) ? $node->nid : FALSE;
       
    70   }
       
    71 
       
    72   /**
       
    73    * Generates POST values for the poll node form, specifically poll choices.
       
    74    *
       
    75    * @param $title
       
    76    *   The title for the poll node.
       
    77    * @param $choices
       
    78    *   An array containing poll choices, as generated by
       
    79    *   PollTestCase::_generateChoices().
       
    80    * @param $index
       
    81    *   (optional) The amount/number of already submitted poll choices. Defaults
       
    82    *   to 0.
       
    83    *
       
    84    * @return
       
    85    *   An indexed array containing:
       
    86    *   - The generated POST values, suitable for
       
    87    *     DrupalWebTestCase::drupalPost().
       
    88    *   - The number of poll choices contained in 'edit', for potential re-usage
       
    89    *     in subsequent invocations of this function.
       
    90    */
       
    91   function _pollGenerateEdit($title, array $choices, $index = 0) {
       
    92     $max_new_choices = ($index == 0 ? 2 : 5);
       
    93     $already_submitted_choices = array_slice($choices, 0, $index);
       
    94     $new_choices = array_values(array_slice($choices, $index, $max_new_choices));
       
    95 
       
    96     $edit = array(
       
    97       'title' => $title,
       
    98     );
       
    99     foreach ($already_submitted_choices as $k => $text) {
       
   100       $edit['choice[chid:' . $k . '][chtext]'] = $text;
       
   101     }
       
   102     foreach ($new_choices as $k => $text) {
       
   103       $edit['choice[new:' . $k . '][chtext]'] = $text;
       
   104     }
       
   105     return array($edit, count($already_submitted_choices) + count($new_choices));
       
   106   }
       
   107 
       
   108   function _generateChoices($count = 7) {
       
   109     $choices = array();
       
   110     for ($i = 1; $i <= $count; $i++) {
       
   111       $choices[] = $this->randomName();
       
   112     }
       
   113     return $choices;
       
   114   }
       
   115 
       
   116   /**
       
   117    * Assert correct poll choice order in the node form after submission.
       
   118    *
       
   119    * Verifies both the order in the DOM and in the 'weight' form elements.
       
   120    *
       
   121    * @param $choices
       
   122    *   An array containing poll choices, as generated by
       
   123    *   PollTestCase::_generateChoices().
       
   124    * @param $index
       
   125    *   (optional) The amount/number of already submitted poll choices. Defaults
       
   126    *   to 0.
       
   127    * @param $preview
       
   128    *   (optional) Whether to also check the poll preview.
       
   129    *
       
   130    * @see PollTestCase::_pollGenerateEdit()
       
   131    */
       
   132   function assertPollChoiceOrder(array $choices, $index = 0, $preview = FALSE) {
       
   133     $expected = array();
       
   134     $weight = 0;
       
   135     foreach ($choices as $id => $label) {
       
   136       if ($id < $index) {
       
   137         // The expected weight of each choice is higher than the previous one.
       
   138         $weight++;
       
   139         // Directly assert the weight form element value for this choice.
       
   140         $this->assertFieldByName('choice[chid:' . $id . '][weight]', $weight, format_string('Found choice @id with weight @weight.', array(
       
   141           '@id' => $id,
       
   142           '@weight' => $weight,
       
   143         )));
       
   144         // Append to our (to be reversed) stack of labels.
       
   145         $expected[$weight] = $label;
       
   146       }
       
   147     }
       
   148     ksort($expected);
       
   149 
       
   150     // Verify DOM order of poll choices (i.e., #weight of form elements).
       
   151     $elements = $this->xpath('//input[starts-with(@name, :prefix) and contains(@name, :suffix)]', array(
       
   152       ':prefix' => 'choice[chid:',
       
   153       ':suffix' => '][chtext]',
       
   154     ));
       
   155     $expected_order = $expected;
       
   156     foreach ($elements as $element) {
       
   157       $next_label = array_shift($expected_order);
       
   158       $this->assertEqual((string) $element['value'], $next_label);
       
   159     }
       
   160 
       
   161     // If requested, also verify DOM order in preview.
       
   162     if ($preview) {
       
   163       $elements = $this->xpath('//div[contains(@class, :teaser)]/descendant::div[@class=:text]', array(
       
   164         ':teaser' => 'node-teaser',
       
   165         ':text' => 'text',
       
   166       ));
       
   167       $expected_order = $expected;
       
   168       foreach ($elements as $element) {
       
   169         $next_label = array_shift($expected_order);
       
   170         $this->assertEqual((string) $element, $next_label, format_string('Found choice @label in preview.', array(
       
   171           '@label' => $next_label,
       
   172         )));
       
   173       }
       
   174     }
       
   175   }
       
   176 
       
   177   function pollUpdate($nid, $title, $edit) {
       
   178     // Edit the poll node.
       
   179     $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save'));
       
   180     $this->assertText(t('@type @title has been updated.', array('@type' => node_type_get_name('poll'), '@title' => $title)), 'Poll has been updated.');
       
   181   }
       
   182 }
       
   183 
       
   184 class PollCreateTestCase extends PollTestCase {
       
   185   public static function getInfo() {
       
   186     return array(
       
   187       'name' => 'Poll create',
       
   188       'description' => 'Adds "more choices", previews and creates a poll.',
       
   189       'group' => 'Poll'
       
   190     );
       
   191   }
       
   192 
       
   193   function setUp() {
       
   194     parent::setUp('poll');
       
   195   }
       
   196 
       
   197   function testPollCreate() {
       
   198     $title = $this->randomName();
       
   199     $choices = $this->_generateChoices(7);
       
   200     $poll_nid = $this->pollCreate($title, $choices, TRUE);
       
   201 
       
   202     // Verify poll appears on 'poll' page.
       
   203     $this->drupalGet('poll');
       
   204     $this->assertText($title, 'Poll appears in poll list.');
       
   205     $this->assertText('open', 'Poll is active.');
       
   206 
       
   207     // Click on the poll title to go to node page.
       
   208     $this->clickLink($title);
       
   209     $this->assertText('Total votes: 0', 'Link to poll correct.');
       
   210 
       
   211     // Now add a new option to make sure that when we update the node the
       
   212     // option is displayed.
       
   213     $node = node_load($poll_nid);
       
   214 
       
   215     $new_option = $this->randomName();
       
   216 
       
   217     $vote_count = '2000';
       
   218     $node->choice[] = array(
       
   219       'chid' => '',
       
   220       'chtext' => $new_option,
       
   221       'chvotes' => (int) $vote_count,
       
   222       'weight' => 1000,
       
   223     );
       
   224 
       
   225     node_save($node);
       
   226 
       
   227     $this->drupalGet('poll');
       
   228     $this->clickLink($title);
       
   229     $this->assertText($new_option, 'New option found.');
       
   230 
       
   231     $option = $this->xpath('//div[@id="node-1"]//div[@class="poll"]//div[@class="text"]');
       
   232     $this->assertEqual(end($option), $new_option, 'Last item is equal to new option.');
       
   233 
       
   234     $votes = $this->xpath('//div[@id="node-1"]//div[@class="poll"]//div[@class="percent"]');
       
   235     $this->assertTrue(strpos(end($votes), $vote_count) > 0, "Votes saved.");
       
   236   }
       
   237 
       
   238   function testPollClose() {
       
   239     $content_user = $this->drupalCreateUser(array('create poll content', 'edit any poll content', 'access content'));
       
   240     $vote_user = $this->drupalCreateUser(array('cancel own vote', 'inspect all votes', 'vote on polls', 'access content'));
       
   241 
       
   242     // Create poll.
       
   243     $title = $this->randomName();
       
   244     $choices = $this->_generateChoices(7);
       
   245     $poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   246 
       
   247     $this->drupalLogout();
       
   248     $this->drupalLogin($content_user);
       
   249 
       
   250     // Edit the poll node and close the poll.
       
   251     $close_edit = array('active' => 0);
       
   252     $this->pollUpdate($poll_nid, $title, $close_edit);
       
   253 
       
   254     // Verify 'Vote' button no longer appears.
       
   255     $this->drupalGet('node/' . $poll_nid);
       
   256     $elements = $this->xpath('//input[@id="edit-vote"]');
       
   257     $this->assertTrue(empty($elements), "Vote button doesn't appear.");
       
   258 
       
   259     // Verify status on 'poll' page is 'closed'.
       
   260     $this->drupalGet('poll');
       
   261     $this->assertText($title, 'Poll appears in poll list.');
       
   262     $this->assertText('closed', 'Poll is closed.');
       
   263 
       
   264     // Edit the poll node and re-activate.
       
   265     $open_edit = array('active' => 1);
       
   266     $this->pollUpdate($poll_nid, $title, $open_edit);
       
   267 
       
   268     // Vote on the poll.
       
   269     $this->drupalLogout();
       
   270     $this->drupalLogin($vote_user);
       
   271     $vote_edit = array('choice' => '1');
       
   272     $this->drupalPost('node/' . $poll_nid, $vote_edit, t('Vote'));
       
   273     $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
       
   274     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   275     $this->assertTrue(isset($elements[0]), "'Cancel your vote' button appears.");
       
   276 
       
   277     // Edit the poll node and close the poll.
       
   278     $this->drupalLogout();
       
   279     $this->drupalLogin($content_user);
       
   280     $close_edit = array('active' => 0);
       
   281     $this->pollUpdate($poll_nid, $title, $close_edit);
       
   282 
       
   283     // Verify 'Cancel your vote' button no longer appears.
       
   284     $this->drupalGet('node/' . $poll_nid);
       
   285     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   286     $this->assertTrue(empty($elements), "'Cancel your vote' button no longer appears.");
       
   287   }
       
   288 }
       
   289 
       
   290 class PollVoteTestCase extends PollTestCase {
       
   291   public static function getInfo() {
       
   292     return array(
       
   293       'name' => 'Poll vote',
       
   294       'description' => 'Vote on a poll',
       
   295       'group' => 'Poll'
       
   296     );
       
   297   }
       
   298 
       
   299   function setUp() {
       
   300     parent::setUp('poll');
       
   301   }
       
   302 
       
   303   function tearDown() {
       
   304     parent::tearDown();
       
   305   }
       
   306 
       
   307   function testPollVote() {
       
   308     $title = $this->randomName();
       
   309     $choices = $this->_generateChoices(7);
       
   310     $poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   311     $this->drupalLogout();
       
   312 
       
   313     $vote_user = $this->drupalCreateUser(array('cancel own vote', 'inspect all votes', 'vote on polls', 'access content'));
       
   314     $restricted_vote_user = $this->drupalCreateUser(array('vote on polls', 'access content'));
       
   315 
       
   316     $this->drupalLogin($vote_user);
       
   317 
       
   318     // Record a vote without selecting any choice.
       
   319     $edit = array();
       
   320     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   321     $this->assertText(t('Your vote could not be recorded because you did not select any of the choices.'), 'Found the empty poll submission error message.');
       
   322 
       
   323     // Record a vote for the first choice.
       
   324     $edit = array(
       
   325       'choice' => '1',
       
   326     );
       
   327     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   328     $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
       
   329     $this->assertText('Total votes: 1', 'Vote count updated correctly.');
       
   330     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   331     $this->assertTrue(isset($elements[0]), "'Cancel your vote' button appears.");
       
   332 
       
   333     $this->drupalGet("node/$poll_nid/votes");
       
   334     $this->assertText(t('This table lists all the recorded votes for this poll. If anonymous users are allowed to vote, they will be identified by the IP address of the computer they used when they voted.'), 'Vote table text.');
       
   335     $this->assertText($choices[0], 'Vote recorded');
       
   336 
       
   337     // Ensure poll listing page has correct number of votes.
       
   338     $this->drupalGet('poll');
       
   339     $this->assertText($title, 'Poll appears in poll list.');
       
   340     $this->assertText('1 vote', 'Poll has 1 vote.');
       
   341 
       
   342     // Cancel a vote.
       
   343     $this->drupalPost('node/' . $poll_nid, array(), t('Cancel your vote'));
       
   344     $this->assertText('Your vote was cancelled.', 'Your vote was cancelled.');
       
   345     $this->assertNoText('Cancel your vote', "Cancel vote button doesn't appear.");
       
   346 
       
   347     $this->drupalGet("node/$poll_nid/votes");
       
   348     $this->assertNoText($choices[0], 'Vote cancelled');
       
   349 
       
   350     // Ensure poll listing page has correct number of votes.
       
   351     $this->drupalGet('poll');
       
   352     $this->assertText($title, 'Poll appears in poll list.');
       
   353     $this->assertText('0 votes', 'Poll has 0 votes.');
       
   354 
       
   355     // Log in as a user who can only vote on polls.
       
   356     $this->drupalLogout();
       
   357     $this->drupalLogin($restricted_vote_user);
       
   358 
       
   359     // Vote on a poll.
       
   360     $edit = array(
       
   361       'choice' => '1',
       
   362     );
       
   363     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   364     $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
       
   365     $this->assertText('Total votes: 1', 'Vote count updated correctly.');
       
   366     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   367     $this->assertTrue(empty($elements), "'Cancel your vote' button does not appear.");
       
   368   }
       
   369 }
       
   370 
       
   371 class PollBlockTestCase extends PollTestCase {
       
   372   public static function getInfo() {
       
   373     return array(
       
   374       'name' => 'Block availability',
       
   375       'description' => 'Check if the most recent poll block is available.',
       
   376       'group' => 'Poll',
       
   377     );
       
   378   }
       
   379 
       
   380   function setUp() {
       
   381     parent::setUp('poll');
       
   382 
       
   383     // Create and login user
       
   384     $admin_user = $this->drupalCreateUser(array('administer blocks'));
       
   385     $this->drupalLogin($admin_user);
       
   386   }
       
   387 
       
   388   function testRecentBlock() {
       
   389     // Set block title to confirm that the interface is available.
       
   390     $this->drupalPost('admin/structure/block/manage/poll/recent/configure', array('title' => $this->randomName(8)), t('Save block'));
       
   391     $this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
       
   392 
       
   393     // Set the block to a region to confirm block is available.
       
   394     $edit = array();
       
   395     $edit['blocks[poll_recent][region]'] = 'footer';
       
   396     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   397     $this->assertText(t('The block settings have been updated.'), 'Block successfully move to footer region.');
       
   398 
       
   399     // Create a poll which should appear in recent polls block.
       
   400     $title = $this->randomName();
       
   401     $choices = $this->_generateChoices(7);
       
   402     $poll_nid = $this->pollCreate($title, $choices, TRUE);
       
   403 
       
   404     // Verify poll appears in a block.
       
   405     // View user page so we're not matching the poll node on front page.
       
   406     $this->drupalGet('user');
       
   407     // If a 'block' view not generated, this title would not appear even though
       
   408     // the choices might.
       
   409     $this->assertText($title, 'Poll appears in block.');
       
   410 
       
   411     // Logout and login back in as a user who can vote.
       
   412     $this->drupalLogout();
       
   413     $vote_user = $this->drupalCreateUser(array('cancel own vote', 'inspect all votes', 'vote on polls', 'access content'));
       
   414     $this->drupalLogin($vote_user);
       
   415 
       
   416     // Verify we can vote via the block.
       
   417     $edit = array(
       
   418       'choice' => '1',
       
   419     );
       
   420     $this->drupalPost('user/' . $vote_user->uid, $edit, t('Vote'));
       
   421     $this->assertText('Your vote was recorded.', 'Your vote was recorded.');
       
   422     $this->assertText('Total votes: 1', 'Vote count updated correctly.');
       
   423     $this->assertText('Older polls', 'Link to older polls appears.');
       
   424     $this->clickLink('Older polls');
       
   425     $this->assertText('1 vote - open', 'Link to poll listing correct.');
       
   426 
       
   427     // Close the poll and verify block doesn't appear.
       
   428     $content_user = $this->drupalCreateUser(array('create poll content', 'edit any poll content', 'access content'));
       
   429     $this->drupalLogout();
       
   430     $this->drupalLogin($content_user);
       
   431     $close_edit = array('active' => 0);
       
   432     $this->pollUpdate($poll_nid, $title, $close_edit);
       
   433     $this->drupalGet('user/' . $content_user->uid);
       
   434     $this->assertNoText($title, 'Poll no longer appears in block.');
       
   435   }
       
   436 }
       
   437 
       
   438 /**
       
   439  * Test adding new choices.
       
   440  */
       
   441 class PollJSAddChoice extends DrupalWebTestCase {
       
   442 
       
   443   public static function getInfo() {
       
   444     return array(
       
   445       'name' => 'Poll add choice',
       
   446       'description' => 'Submits a POST request for an additional poll choice.',
       
   447       'group' => 'Poll'
       
   448     );
       
   449   }
       
   450 
       
   451   function setUp() {
       
   452     parent::setUp('poll');
       
   453   }
       
   454 
       
   455   /**
       
   456    * Test adding a new choice.
       
   457    */
       
   458   function testAddChoice() {
       
   459     $web_user = $this->drupalCreateUser(array('create poll content', 'access content'));
       
   460     $this->drupalLogin($web_user);
       
   461     $this->drupalGet('node/add/poll');
       
   462     $edit = array(
       
   463       "title" => $this->randomName(),
       
   464       'choice[new:0][chtext]' => $this->randomName(),
       
   465       'choice[new:1][chtext]' => $this->randomName(),
       
   466     );
       
   467 
       
   468     // Press 'add choice' button through Ajax, and place the expected HTML result
       
   469     // as the tested content.
       
   470     $commands = $this->drupalPostAJAX(NULL, $edit, array('op' => t('More choices')));
       
   471     $this->content = $commands[1]['data'];
       
   472 
       
   473     $this->assertFieldByName('choice[chid:0][chtext]', $edit['choice[new:0][chtext]'], format_string('Field !i found', array('!i' => 0)));
       
   474     $this->assertFieldByName('choice[chid:1][chtext]', $edit['choice[new:1][chtext]'], format_string('Field !i found', array('!i' => 1)));
       
   475     $this->assertFieldByName('choice[new:0][chtext]', '', format_string('Field !i found', array('!i' => 2)));
       
   476   }
       
   477 }
       
   478 
       
   479 class PollVoteCheckHostname extends PollTestCase {
       
   480   public static function getInfo() {
       
   481     return array(
       
   482       'name' => 'User poll vote capability.',
       
   483       'description' => 'Check that users and anonymous users from specified ip-address can only vote once.',
       
   484       'group' => 'Poll'
       
   485     );
       
   486   }
       
   487 
       
   488   function setUp() {
       
   489     parent::setUp('poll');
       
   490 
       
   491     // Create and login user.
       
   492     $this->admin_user = $this->drupalCreateUser(array('administer permissions', 'create poll content'));
       
   493     $this->drupalLogin($this->admin_user);
       
   494 
       
   495     // Allow anonymous users to vote on polls.
       
   496     user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
       
   497       'access content' => TRUE,
       
   498       'vote on polls' => TRUE,
       
   499       'cancel own vote' => TRUE,
       
   500     ));
       
   501 
       
   502     // Enable page cache to verify that the result page is not saved in the
       
   503     // cache when anonymous voting is allowed.
       
   504     variable_set('cache', 1);
       
   505 
       
   506     // Create poll.
       
   507     $title = $this->randomName();
       
   508     $choices = $this->_generateChoices(3);
       
   509     $this->poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   510 
       
   511     $this->drupalLogout();
       
   512 
       
   513     // Create web users.
       
   514     $this->web_user1 = $this->drupalCreateUser(array('access content', 'vote on polls', 'cancel own vote'));
       
   515     $this->web_user2 = $this->drupalCreateUser(array('access content', 'vote on polls'));
       
   516   }
       
   517 
       
   518   /**
       
   519    * Check that anonymous users with same ip cannot vote on poll more than once
       
   520    * unless user is logged in.
       
   521    */
       
   522   function testHostnamePollVote() {
       
   523     // Login User1.
       
   524     $this->drupalLogin($this->web_user1);
       
   525 
       
   526     $edit = array(
       
   527       'choice' => '1',
       
   528     );
       
   529 
       
   530     // User1 vote on Poll.
       
   531     $this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
       
   532     $this->assertText(t('Your vote was recorded.'), format_string('%user vote was recorded.', array('%user' => $this->web_user1->name)));
       
   533     $this->assertText(t('Total votes: @votes', array('@votes' => 1)), 'Vote count updated correctly.');
       
   534 
       
   535     // Check to make sure User1 cannot vote again.
       
   536     $this->drupalGet('node/' . $this->poll_nid);
       
   537     $elements = $this->xpath('//input[@value="Vote"]');
       
   538     $this->assertTrue(empty($elements), format_string("%user is not able to vote again.", array('%user' => $this->web_user1->name)));
       
   539     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   540     $this->assertTrue(!empty($elements), "'Cancel your vote' button appears.");
       
   541 
       
   542     // Logout User1.
       
   543     $this->drupalLogout();
       
   544 
       
   545     // Fill the page cache by requesting the poll.
       
   546     $this->drupalGet('node/' . $this->poll_nid);
       
   547     $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', 'Page was cacheable but was not in the cache.');
       
   548     $this->drupalGet('node/' . $this->poll_nid);
       
   549     $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'HIT', 'Page was cached.');
       
   550 
       
   551     // Anonymous user vote on Poll.
       
   552     $this->drupalPost(NULL, $edit, t('Vote'));
       
   553     $this->assertText(t('Your vote was recorded.'), 'Anonymous vote was recorded.');
       
   554     $this->assertText(t('Total votes: @votes', array('@votes' => 2)), 'Vote count updated correctly.');
       
   555     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   556     $this->assertTrue(!empty($elements), "'Cancel your vote' button appears.");
       
   557 
       
   558     // Check to make sure Anonymous user cannot vote again.
       
   559     $this->drupalGet('node/' . $this->poll_nid);
       
   560     $this->assertFalse($this->drupalGetHeader('x-drupal-cache'), 'Page was not cacheable.');
       
   561     $elements = $this->xpath('//input[@value="Vote"]');
       
   562     $this->assertTrue(empty($elements), "Anonymous is not able to vote again.");
       
   563     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   564     $this->assertTrue(!empty($elements), "'Cancel your vote' button appears.");
       
   565 
       
   566     // Login User2.
       
   567     $this->drupalLogin($this->web_user2);
       
   568 
       
   569     // User2 vote on poll.
       
   570     $this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
       
   571     $this->assertText(t('Your vote was recorded.'), format_string('%user vote was recorded.', array('%user' => $this->web_user2->name)));
       
   572     $this->assertText(t('Total votes: @votes', array('@votes' => 3)), 'Vote count updated correctly.');
       
   573     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   574     $this->assertTrue(empty($elements), "'Cancel your vote' button does not appear.");
       
   575 
       
   576     // Logout User2.
       
   577     $this->drupalLogout();
       
   578 
       
   579     // Change host name for anonymous users.
       
   580     db_update('poll_vote')
       
   581       ->fields(array(
       
   582         'hostname' => '123.456.789.1',
       
   583       ))
       
   584       ->condition('hostname', '', '<>')
       
   585       ->execute();
       
   586 
       
   587     // Check to make sure Anonymous user can vote again with a new session after
       
   588     // a hostname change.
       
   589     $this->drupalGet('node/' . $this->poll_nid);
       
   590     $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', 'Page was cacheable but was not in the cache.');
       
   591     $this->drupalPost(NULL, $edit, t('Vote'));
       
   592     $this->assertText(t('Your vote was recorded.'), format_string('%user vote was recorded.', array('%user' => $this->web_user2->name)));
       
   593     $this->assertText(t('Total votes: @votes', array('@votes' => 4)), 'Vote count updated correctly.');
       
   594     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   595     $this->assertTrue(!empty($elements), "'Cancel your vote' button appears.");
       
   596 
       
   597     // Check to make sure Anonymous user cannot vote again with a new session,
       
   598     // and that the vote from the previous session cannot be cancelledd.
       
   599     $this->curlClose();
       
   600     $this->drupalGet('node/' . $this->poll_nid);
       
   601     $this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', 'Page was cacheable but was not in the cache.');
       
   602     $elements = $this->xpath('//input[@value="Vote"]');
       
   603     $this->assertTrue(empty($elements), 'Anonymous is not able to vote again.');
       
   604     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   605     $this->assertTrue(empty($elements), "'Cancel your vote' button does not appear.");
       
   606 
       
   607     // Login User1.
       
   608     $this->drupalLogin($this->web_user1);
       
   609 
       
   610     // Check to make sure User1 still cannot vote even after hostname changed.
       
   611     $this->drupalGet('node/' . $this->poll_nid);
       
   612     $elements = $this->xpath('//input[@value="Vote"]');
       
   613     $this->assertTrue(empty($elements), format_string("%user is not able to vote again.", array('%user' => $this->web_user1->name)));
       
   614     $elements = $this->xpath('//input[@value="Cancel your vote"]');
       
   615     $this->assertTrue(!empty($elements), "'Cancel your vote' button appears.");
       
   616   }
       
   617 }
       
   618 
       
   619 /**
       
   620  * Test poll token replacement in strings.
       
   621  */
       
   622 class PollTokenReplaceTestCase extends PollTestCase {
       
   623   public static function getInfo() {
       
   624     return array(
       
   625       'name' => 'Poll token replacement',
       
   626       'description' => 'Generates text using placeholders for dummy content to check poll token replacement.',
       
   627       'group' => 'Poll',
       
   628     );
       
   629   }
       
   630 
       
   631   function setUp() {
       
   632     parent::setUp('poll');
       
   633   }
       
   634 
       
   635   /**
       
   636    * Creates a poll, then tests the tokens generated from it.
       
   637    */
       
   638   function testPollTokenReplacement() {
       
   639     global $language;
       
   640 
       
   641     // Craete a poll with three choices.
       
   642     $title = $this->randomName();
       
   643     $choices = $this->_generateChoices(3);
       
   644     $poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   645     $this->drupalLogout();
       
   646 
       
   647     // Create four users and have each of them vote.
       
   648     $vote_user1 = $this->drupalCreateUser(array('vote on polls', 'access content'));
       
   649     $this->drupalLogin($vote_user1);
       
   650     $edit = array(
       
   651       'choice' => '1',
       
   652     );
       
   653     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   654     $this->drupalLogout();
       
   655 
       
   656     $vote_user2 = $this->drupalCreateUser(array('vote on polls', 'access content'));
       
   657     $this->drupalLogin($vote_user2);
       
   658     $edit = array(
       
   659       'choice' => '1',
       
   660     );
       
   661     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   662     $this->drupalLogout();
       
   663 
       
   664     $vote_user3 = $this->drupalCreateUser(array('vote on polls', 'access content'));
       
   665     $this->drupalLogin($vote_user3);
       
   666     $edit = array(
       
   667       'choice' => '2',
       
   668     );
       
   669     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   670     $this->drupalLogout();
       
   671 
       
   672     $vote_user4 = $this->drupalCreateUser(array('vote on polls', 'access content'));
       
   673     $this->drupalLogin($vote_user4);
       
   674     $edit = array(
       
   675       'choice' => '3',
       
   676     );
       
   677     $this->drupalPost('node/' . $poll_nid, $edit, t('Vote'));
       
   678     $this->drupalLogout();
       
   679 
       
   680     $poll = node_load($poll_nid, NULL, TRUE);
       
   681 
       
   682     // Generate and test sanitized tokens.
       
   683     $tests = array();
       
   684     $tests['[node:poll-votes]'] = 4;
       
   685     $tests['[node:poll-winner]'] = filter_xss($poll->choice[1]['chtext']);
       
   686     $tests['[node:poll-winner-votes]'] = 2;
       
   687     $tests['[node:poll-winner-percent]'] = 50;
       
   688     $tests['[node:poll-duration]'] = format_interval($poll->runtime, 1, $language->language);
       
   689 
       
   690     // Test to make sure that we generated something for each token.
       
   691     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
       
   692 
       
   693     foreach ($tests as $input => $expected) {
       
   694       $output = token_replace($input, array('node' => $poll), array('language' => $language));
       
   695       $this->assertEqual($output, $expected, format_string('Sanitized poll token %token replaced.', array('%token' => $input)));
       
   696     }
       
   697 
       
   698     // Generate and test unsanitized tokens.
       
   699     $tests['[node:poll-winner]'] = $poll->choice[1]['chtext'];
       
   700 
       
   701     foreach ($tests as $input => $expected) {
       
   702       $output = token_replace($input, array('node' => $poll), array('language' => $language, 'sanitize' => FALSE));
       
   703       $this->assertEqual($output, $expected, format_string('Unsanitized poll token %token replaced.', array('%token' => $input)));
       
   704     }
       
   705   }
       
   706 }
       
   707 
       
   708 class PollExpirationTestCase extends PollTestCase {
       
   709   public static function getInfo() {
       
   710     return array(
       
   711       'name' => 'Poll expiration',
       
   712       'description' => 'Test the poll auto-expiration logic.',
       
   713       'group' => 'Poll',
       
   714     );
       
   715   }
       
   716 
       
   717   function setUp() {
       
   718     parent::setUp('poll');
       
   719   }
       
   720 
       
   721   function testAutoExpire() {
       
   722     // Set up a poll.
       
   723     $title = $this->randomName();
       
   724     $choices = $this->_generateChoices(2);
       
   725     $poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   726     $this->assertTrue($poll_nid, 'Poll for auto-expire test created.');
       
   727 
       
   728     // Visit the poll edit page and verify that by default, expiration
       
   729     // is set to unlimited.
       
   730     $this->drupalGet("node/$poll_nid/edit");
       
   731     $this->assertField('runtime', 'Poll expiration setting found.');
       
   732     $elements = $this->xpath('//select[@id="edit-runtime"]/option[@selected="selected"]');
       
   733     $this->assertTrue(isset($elements[0]['value']) && $elements[0]['value'] == 0, 'Poll expiration set to unlimited.');
       
   734 
       
   735     // Set the expiration to one week.
       
   736     $edit = array();
       
   737     $poll_expiration = 604800; // One week.
       
   738     $edit['runtime'] = $poll_expiration;
       
   739     $this->drupalPost(NULL, $edit, t('Save'));
       
   740     $this->assertRaw(t('Poll %title has been updated.', array('%title' => $title)), 'Poll expiration settings saved.');
       
   741 
       
   742     // Make sure that the changed expiration settings is kept.
       
   743     $this->drupalGet("node/$poll_nid/edit");
       
   744     $elements = $this->xpath('//select[@id="edit-runtime"]/option[@selected="selected"]');
       
   745     $this->assertTrue(isset($elements[0]['value']) && $elements[0]['value'] == $poll_expiration, 'Poll expiration set to unlimited.');
       
   746 
       
   747     // Force a cron run. Since the expiration date has not yet been reached,
       
   748     // the poll should remain active.
       
   749     drupal_cron_run();
       
   750     $this->drupalGet("node/$poll_nid/edit");
       
   751     $elements = $this->xpath('//input[@id="edit-active-1"]');
       
   752     $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), 'Poll is still active.');
       
   753 
       
   754     // Test expiration. Since REQUEST_TIME is a constant and we don't
       
   755     // want to keep SimpleTest waiting until the moment of expiration arrives,
       
   756     // we forcibly change the expiration date in the database.
       
   757     $created = db_query('SELECT created FROM {node} WHERE nid = :nid', array(':nid' => $poll_nid))->fetchField();
       
   758     db_update('node')
       
   759       ->fields(array('created' => $created - ($poll_expiration * 1.01)))
       
   760       ->condition('nid', $poll_nid)
       
   761       ->execute();
       
   762 
       
   763     // Run cron and verify that the poll is now marked as "closed".
       
   764     drupal_cron_run();
       
   765     $this->drupalGet("node/$poll_nid/edit");
       
   766     $elements = $this->xpath('//input[@id="edit-active-0"]');
       
   767     $this->assertTrue(isset($elements[0]) && !empty($elements[0]['checked']), 'Poll has expired.');
       
   768   }
       
   769 }
       
   770 
       
   771 class PollDeleteChoiceTestCase extends PollTestCase {
       
   772   public static function getInfo() {
       
   773     return array(
       
   774       'name' => 'Poll choice deletion',
       
   775       'description' => 'Test the poll choice deletion logic.',
       
   776       'group' => 'Poll',
       
   777     );
       
   778   }
       
   779 
       
   780   function setUp() {
       
   781     parent::setUp('poll');
       
   782   }
       
   783 
       
   784   function testChoiceRemoval() {
       
   785     // Set up a poll with three choices.
       
   786     $title = $this->randomName();
       
   787     $choices = array('First choice', 'Second choice', 'Third choice');
       
   788     $poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   789     $this->assertTrue($poll_nid, 'Poll for choice deletion logic test created.');
       
   790 
       
   791     // Edit the poll, and try to delete first poll choice.
       
   792     $this->drupalGet("node/$poll_nid/edit");
       
   793     $edit['choice[chid:1][chtext]'] = '';
       
   794     $this->drupalPost(NULL, $edit, t('Save'));
       
   795 
       
   796     // Click on the poll title to go to node page.
       
   797     $this->drupalGet('poll');
       
   798     $this->clickLink($title);
       
   799 
       
   800     // Check the first poll choice is deleted, while the others remain.
       
   801     $this->assertNoText('First choice', 'First choice removed.');
       
   802     $this->assertText('Second choice', 'Second choice remains.');
       
   803     $this->assertText('Third choice', 'Third choice remains.');
       
   804   }
       
   805 }
       
   806 
       
   807 /**
       
   808  * Tests poll translation logic.
       
   809  */
       
   810 class PollTranslateTestCase extends PollTestCase {
       
   811   public static function getInfo() {
       
   812     return array(
       
   813       'name' => 'Poll translation',
       
   814       'description' => 'Test the poll translation logic.',
       
   815       'group' => 'Poll',
       
   816     );
       
   817   }
       
   818 
       
   819   function setUp() {
       
   820     parent::setUp('poll', 'translation');
       
   821   }
       
   822 
       
   823   /**
       
   824    * Tests poll creation and translation.
       
   825    *
       
   826    * Checks that the choice names get copied from the original poll and that
       
   827    * the vote count values are set to 0.
       
   828    */
       
   829   function testPollTranslate() {
       
   830     $admin_user = $this->drupalCreateUser(array('administer content types', 'administer languages', 'edit any poll content', 'create poll content', 'administer nodes', 'translate content'));
       
   831 
       
   832     // Set up a poll with two choices.
       
   833     $title = $this->randomName();
       
   834     $choices = array($this->randomName(), $this->randomName());
       
   835     $poll_nid = $this->pollCreate($title, $choices, FALSE);
       
   836     $this->assertTrue($poll_nid, 'Poll for translation logic test created.');
       
   837 
       
   838     $this->drupalLogout();
       
   839     $this->drupalLogin($admin_user);
       
   840 
       
   841     // Enable a second language.
       
   842     $this->drupalGet('admin/config/regional/language');
       
   843     $edit = array();
       
   844     $edit['langcode'] = 'nl';
       
   845     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
       
   846     $this->assertRaw(t('The language %language has been created and can now be used.', array('%language' => 'Dutch')), 'Language Dutch has been created.');
       
   847 
       
   848     // Set "Poll" content type to use multilingual support with translation.
       
   849     $this->drupalGet('admin/structure/types/manage/poll');
       
   850     $edit = array();
       
   851     $edit['language_content_type'] = 2;
       
   852     $this->drupalPost('admin/structure/types/manage/poll', $edit, t('Save content type'));
       
   853     $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Poll')), 'Poll content type has been updated.');
       
   854 
       
   855     // Edit poll.
       
   856     $this->drupalGet("node/$poll_nid/edit");
       
   857     $edit = array();
       
   858     // Set the poll's first choice count to 200.
       
   859     $edit['choice[chid:1][chvotes]'] = 200;
       
   860     // Set the language to Dutch.
       
   861     $edit['language'] = 'nl';
       
   862     $this->drupalPost(NULL, $edit, t('Save'));
       
   863 
       
   864     // Translate the Dutch poll.
       
   865     $this->drupalGet('node/add/poll', array('query' => array('translation' => $poll_nid, 'target' => 'en')));
       
   866 
       
   867     $dutch_poll = node_load($poll_nid);
       
   868 
       
   869     // Check that the vote count values didn't get copied from the Dutch poll
       
   870     // and are set to 0.
       
   871     $this->assertFieldByName('choice[chid:1][chvotes]', '0', ('Found choice with vote count 0'));
       
   872     $this->assertFieldByName('choice[chid:2][chvotes]', '0', ('Found choice with vote count 0'));
       
   873     // Check that the choice names got copied from the Dutch poll.
       
   874     $this->assertFieldByName('choice[chid:1][chtext]', $dutch_poll->choice[1]['chtext'], format_string('Found choice with text @text', array('@text' => $dutch_poll->choice[1]['chtext'])));
       
   875     $this->assertFieldByName('choice[chid:2][chtext]', $dutch_poll->choice[2]['chtext'], format_string('Found choice with text @text', array('@text' => $dutch_poll->choice[2]['chtext'])));
       
   876   }
       
   877 }