123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143 |
- <?php
- /**
- * @file
- * Tests for CAPTCHA module.
- */
- // TODO: write test for CAPTCHAs on admin pages
- // TODO: test for default challenge type
- // TODO: test about placement (comment form, node forms, log in form, etc)
- // TODO: test if captcha_cron does it work right
- // TODO: test custom CAPTCHA validation stuff
- // TODO: test if entry on status report (Already X blocked form submissions) works
- // TODO: test space ignoring validation of image CAPTCHA
- // TODO: refactor the 'comment_body[' . LANGUAGE_NONE . '][0][value]' stuff
- // Some constants for better reuse.
- define('CAPTCHA_WRONG_RESPONSE_ERROR_MESSAGE',
- 'The answer you entered for the CAPTCHA was not correct.');
- define('CAPTCHA_SESSION_REUSE_ATTACK_ERROR_MESSAGE',
- 'CAPTCHA session reuse attack detected.');
- define('CAPTCHA_UNKNOWN_CSID_ERROR_MESSAGE',
- 'CAPTCHA validation error: unknown CAPTCHA session ID. Contact the site administrator if this problem persists.');
- /**
- * Base class for CAPTCHA tests.
- *
- * Provides common setup stuff and various helper functions
- */
- abstract class CaptchaBaseWebTestCase extends DrupalWebTestCase {
- /**
- * User with various administrative permissions.
- * @var Drupal user
- */
- protected $admin_user;
- /**
- * Normal visitor with limited permissions
- * @var Drupal user;
- */
- protected $normal_user;
- /**
- * Form ID of comment form on standard (page) node
- * @var string
- */
- const COMMENT_FORM_ID = 'comment_node_page_form';
- /**
- * Drupal path of the (general) CAPTCHA admin page
- */
- const CAPTCHA_ADMIN_PATH = 'admin/config/people/captcha';
- function setUp() {
- // Load two modules: the captcha module itself and the comment module for testing anonymous comments.
- $modules = func_get_args();
- if (isset($modules[0]) && is_array($modules[0])) {
- $modules = $modules[0];
- }
- parent::setUp(array_merge(array('captcha', 'comment'), $modules));
- module_load_include('inc', 'captcha');
- // Create a normal user.
- $permissions = array(
- 'access comments', 'post comments', 'skip comment approval',
- 'access content', 'create page content', 'edit own page content',
- );
- $this->normal_user = $this->drupalCreateUser($permissions);
- // Create an admin user.
- $permissions[] = 'administer CAPTCHA settings';
- $permissions[] = 'skip CAPTCHA';
- $permissions[] = 'administer permissions';
- $permissions[] = 'administer content types';
- $this->admin_user = $this->drupalCreateUser($permissions);
- // Put comments on page nodes on a separate page (default in D7: below post).
- variable_set('comment_form_location_page', COMMENT_FORM_SEPARATE_PAGE);
- }
- /**
- * Assert that the response is accepted:
- * no "unknown CSID" message, no "CSID reuse attack detection" message,
- * no "wrong answer" message.
- */
- protected function assertCaptchaResponseAccepted() {
- // There should be no error message about unknown CAPTCHA session ID.
- $this->assertNoText(t(CAPTCHA_UNKNOWN_CSID_ERROR_MESSAGE),
- 'CAPTCHA response should be accepted (known CSID).',
- 'CAPTCHA');
- // There should be no error message about CSID reuse attack.
- $this->assertNoText(t(CAPTCHA_SESSION_REUSE_ATTACK_ERROR_MESSAGE),
- 'CAPTCHA response should be accepted (no CAPTCHA session reuse attack detection).',
- 'CAPTCHA');
- // There should be no error message about wrong response.
- $this->assertNoText(t(CAPTCHA_WRONG_RESPONSE_ERROR_MESSAGE),
- 'CAPTCHA response should be accepted (correct response).',
- 'CAPTCHA');
- }
- /**
- * Assert that there is a CAPTCHA on the form or not.
- * @param bool $presence whether there should be a CAPTCHA or not.
- */
- protected function assertCaptchaPresence($presence) {
- if ($presence) {
- $this->assertText(_captcha_get_description(),
- 'There should be a CAPTCHA on the form.', 'CAPTCHA');
- }
- else {
- $this->assertNoText(_captcha_get_description(),
- 'There should be no CAPTCHA on the form.', 'CAPTCHA');
- }
- }
- /**
- * Helper function to create a node with comments enabled.
- *
- * @return
- * Created node object.
- */
- protected function createNodeWithCommentsEnabled($type='page') {
- $node_settings = array(
- 'type' => $type,
- 'comment' => COMMENT_NODE_OPEN,
- );
- $node = $this->drupalCreateNode($node_settings);
- return $node;
- }
- /**
- * Helper function to generate a form values array for comment forms
- */
- protected function getCommentFormValues() {
- $edit = array(
- 'subject' => 'comment_subject ' . $this->randomName(32),
- 'comment_body[' . LANGUAGE_NONE . '][0][value]' => 'comment_body ' . $this->randomName(256),
- );
- return $edit;
- }
- /**
- * Helper function to generate a form values array for node forms
- */
- protected function getNodeFormValues() {
- $edit = array(
- 'title' => 'node_title ' . $this->randomName(32),
- 'body[' . LANGUAGE_NONE . '][0][value]' => 'node_body ' . $this->randomName(256),
- );
- return $edit;
- }
- /**
- * Get the CAPTCHA session id from the current form in the browser.
- */
- protected function getCaptchaSidFromForm() {
- $elements = $this->xpath('//input[@name="captcha_sid"]');
- $captcha_sid = (int) $elements[0]['value'];
- return $captcha_sid;
- }
- /**
- * Get the CAPTCHA token from the current form in the browser.
- */
- protected function getCaptchaTokenFromForm() {
- $elements = $this->xpath('//input[@name="captcha_token"]');
- $captcha_token = (int) $elements[0]['value'];
- return $captcha_token;
- }
- /**
- * Get the solution of the math CAPTCHA from the current form in the browser.
- */
- protected function getMathCaptchaSolutionFromForm() {
- // Get the math challenge.
- $elements = $this->xpath('//div[@class="form-item form-type-textfield form-item-captcha-response"]/span[@class="field-prefix"]');
- $challenge = (string) $elements[0];
- // Extract terms and operator from challenge.
- $matches = array();
- $ret = preg_match('/\\s*(\\d+)\\s*(-|\\+)\\s*(\\d+)\\s*=\\s*/', $challenge, $matches);
- // Solve the challenge
- $a = (int) $matches[1];
- $b = (int) $matches[3];
- $solution = $matches[2] == '-' ? $a - $b : $a + $b;
- return $solution;
- }
- /**
- * Helper function to allow comment posting for anonymous users.
- */
- protected function allowCommentPostingForAnonymousVisitors() {
- // Log in as admin.
- $this->drupalLogin($this->admin_user);
- // Post user permissions form
- $edit = array(
- '1[access comments]' => true,
- '1[post comments]' => true,
- '1[skip comment approval]' => true,
- );
- $this->drupalPost('admin/people/permissions', $edit, 'Save permissions');
- $this->assertText('The changes have been saved.');
- // Log admin out
- $this->drupalLogout();
- }
- }
- class CaptchaTestCase extends CaptchaBaseWebTestCase {
- public static function getInfo() {
- return array(
- 'name' => t('General CAPTCHA functionality'),
- 'description' => t('Testing of the basic CAPTCHA functionality.'),
- 'group' => t('CAPTCHA'),
- );
- }
- /**
- * Testing the protection of the user log in form.
- */
- function testCaptchaOnLoginForm() {
- // Create user and test log in without CAPTCHA.
- $user = $this->drupalCreateUser();
- $this->drupalLogin($user);
- // Log out again.
- $this->drupalLogout();
- // Set a CAPTCHA on login form
- captcha_set_form_id_setting('user_login', 'captcha/Math');
- // Check if there is a CAPTCHA on the login form (look for the title).
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- // Try to log in, which should fail.
- $edit = array(
- 'name' => $user->name,
- 'pass' => $user->pass_raw,
- 'captcha_response' => '?',
- );
- $this->drupalPost('user', $edit, t('Log in'));
- // Check for error message.
- $this->assertText(t(CAPTCHA_WRONG_RESPONSE_ERROR_MESSAGE),
- 'CAPTCHA should block user login form', 'CAPTCHA');
- // And make sure that user is not logged in: check for name and password fields on ?q=user
- $this->drupalGet('user');
- $this->assertField('name', t('Username field found.'), 'CAPTCHA');
- $this->assertField('pass', t('Password field found.'), 'CAPTCHA');
- }
- /**
- * Assert function for testing if comment posting works as it should.
- *
- * Creates node with comment writing enabled, tries to post comment
- * with given CAPTCHA response (caller should enable the desired
- * challenge on page node comment forms) and checks if the result is as expected.
- *
- * @param $captcha_response the response on the CAPTCHA
- * @param $should_pass boolean describing if the posting should pass or should be blocked
- * @param $message message to prefix to nested asserts
- */
- protected function assertCommentPosting($captcha_response, $should_pass, $message) {
- // Make sure comments on pages can be saved directely without preview.
- variable_set('comment_preview_page', DRUPAL_OPTIONAL);
- // Create a node with comments enabled.
- $node = $this->createNodeWithCommentsEnabled();
- // Post comment on node.
- $edit = $this->getCommentFormValues();
- $comment_subject = $edit['subject'];
- $comment_body = $edit['comment_body[' . LANGUAGE_NONE . '][0][value]'];
- $edit['captcha_response'] = $captcha_response;
- $this->drupalPost('comment/reply/' . $node->nid, $edit, t('Save'));
- if ($should_pass) {
- // There should be no error message.
- $this->assertCaptchaResponseAccepted();
- // Get node page and check that comment shows up.
- $this->drupalGet('node/' . $node->nid);
- $this->assertText($comment_subject, $message .' Comment should show up on node page.', 'CAPTCHA');
- $this->assertText($comment_body, $message . ' Comment should show up on node page.', 'CAPTCHA');
- }
- else {
- // Check for error message.
- $this->assertText(t(CAPTCHA_WRONG_RESPONSE_ERROR_MESSAGE), $message .' Comment submission should be blocked.', 'CAPTCHA');
- // Get node page and check that comment is not present.
- $this->drupalGet('node/' . $node->nid);
- $this->assertNoText($comment_subject, $message .' Comment should not show up on node page.', 'CAPTCHA');
- $this->assertNoText($comment_body, $message . ' Comment should not show up on node page.', 'CAPTCHA');
- }
- }
- /*
- * Testing the case sensistive/insensitive validation.
- */
- function testCaseInsensitiveValidation() {
- // Set Test CAPTCHA on comment form
- captcha_set_form_id_setting(self::COMMENT_FORM_ID, 'captcha/Test');
- // Log in as normal user.
- $this->drupalLogin($this->normal_user);
- // Test case sensitive posting.
- variable_set('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE);
- $this->assertCommentPosting('Test 123', TRUE, 'Case sensitive validation of right casing.');
- $this->assertCommentPosting('test 123', FALSE, 'Case sensitive validation of wrong casing.');
- $this->assertCommentPosting('TEST 123', FALSE, 'Case sensitive validation of wrong casing.');
- // Test case insensitive posting (the default)
- variable_set('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE);
- $this->assertCommentPosting('Test 123', TRUE, 'Case insensitive validation of right casing.');
- $this->assertCommentPosting('test 123', TRUE, 'Case insensitive validation of wrong casing.');
- $this->assertCommentPosting('TEST 123', TRUE, 'Case insensitive validation of wrong casing.');
- }
- /**
- * Test if the CAPTCHA description is only shown if there are challenge widgets to show.
- * For example, when a comment is previewed with correct CAPTCHA answer,
- * a challenge is generated and added to the form but removed in the pre_render phase.
- * The CAPTCHA description should not show up either.
- *
- * \see testCaptchaSessionReuseOnNodeForms()
- */
- function testCaptchaDescriptionAfterCommentPreview() {
- // Set Test CAPTCHA on comment form.
- captcha_set_form_id_setting(self::COMMENT_FORM_ID, 'captcha/Test');
- // Log in as normal user.
- $this->drupalLogin($this->normal_user);
- // Create a node with comments enabled.
- $node = $this->createNodeWithCommentsEnabled();
- // Preview comment with correct CAPTCHA answer.
- $edit = $this->getCommentFormValues();
- $edit['captcha_response'] = 'Test 123';
- $this->drupalPost('comment/reply/' . $node->nid, $edit, t('Preview'));
- // Check that there is no CAPTCHA after preview.
- $this->assertCaptchaPresence(FALSE);
- }
- /**
- * Test if the CAPTCHA session ID is reused when previewing nodes:
- * node preview after correct response should not show CAPTCHA anymore.
- * The preview functionality of comments and nodes works slightly different under the hood.
- * CAPTCHA module should be able to handle both.
- *
- * \see testCaptchaDescriptionAfterCommentPreview()
- */
- function testCaptchaSessionReuseOnNodeForms() {
- // Set Test CAPTCHA on page form.
- captcha_set_form_id_setting('page_node_form', 'captcha/Test');
- // Log in as normal user.
- $this->drupalLogin($this->normal_user);
- // Page settings to post, with correct CAPTCHA answer.
- $edit = $this->getNodeFormValues();
- $edit['captcha_response'] = 'Test 123';
- // Preview the node
- $this->drupalPost('node/add/page', $edit, t('Preview'));
- // Check that there is no CAPTCHA after preview.
- $this->assertCaptchaPresence(FALSE);
- }
- /**
- * CAPTCHA should also be put on admin pages even if visitor
- * has no access
- */
- function testCaptchaOnLoginBlockOnAdminPagesIssue893810() {
- // Set a CAPTCHA on login block form
- captcha_set_form_id_setting('user_login_block', 'captcha/Math');
- // Check if there is a CAPTCHA on home page.
- $this->drupalGet('node');
- $this->assertCaptchaPresence(TRUE);
- // Check there is a CAPTCHA on "forbidden" admin pages
- $this->drupalGet('admin');
- $this->assertCaptchaPresence(TRUE);
- }
- }
- class CaptchaAdminTestCase extends CaptchaBaseWebTestCase {
- public static function getInfo() {
- return array(
- 'name' => t('CAPTCHA administration functionality'),
- 'description' => t('Testing of the CAPTCHA administration interface and functionality.'),
- 'group' => t('CAPTCHA'),
- );
- }
- /**
- * Test access to the admin pages.
- */
- function testAdminAccess() {
- $this->drupalLogin($this->normal_user);
- $this->drupalGet(self::CAPTCHA_ADMIN_PATH);
- file_put_contents('tmp.simpletest.html', $this->drupalGetContent());
- $this->assertText(t('Access denied'), 'Normal users should not be able to access the CAPTCHA admin pages', 'CAPTCHA');
- $this->drupalLogin($this->admin_user);
- $this->drupalGet(self::CAPTCHA_ADMIN_PATH);
- $this->assertNoText(t('Access denied'), 'Admin users should be able to access the CAPTCHA admin pages', 'CAPTCHA');
- }
- /**
- * Test the CAPTCHA point setting getter/setter.
- */
- function testCaptchaPointSettingGetterAndSetter() {
- $comment_form_id = self::COMMENT_FORM_ID;
- // Set to 'none'.
- captcha_set_form_id_setting($comment_form_id, 'none');
- $result = captcha_get_form_id_setting($comment_form_id);
- $this->assertNotNull($result, 'Setting and getting CAPTCHA point: none', 'CAPTCHA');
- $this->assertNull($result->module, 'Setting and getting CAPTCHA point: none', 'CAPTCHA');
- $this->assertNull($result->captcha_type, 'Setting and getting CAPTCHA point: none', 'CAPTCHA');
- $result = captcha_get_form_id_setting($comment_form_id, TRUE);
- $this->assertEqual($result, 'none', 'Setting and symbolic getting CAPTCHA point: "none"', 'CAPTCHA');
- // Set to 'default'
- captcha_set_form_id_setting($comment_form_id, 'default');
- variable_set('captcha_default_challenge', 'foo/bar');
- $result = captcha_get_form_id_setting($comment_form_id);
- $this->assertNotNull($result, 'Setting and getting CAPTCHA point: default', 'CAPTCHA');
- $this->assertEqual($result->module, 'foo', 'Setting and getting CAPTCHA point: default', 'CAPTCHA');
- $this->assertEqual($result->captcha_type, 'bar', 'Setting and getting CAPTCHA point: default', 'CAPTCHA');
- $result = captcha_get_form_id_setting($comment_form_id, TRUE);
- $this->assertEqual($result, 'default', 'Setting and symbolic getting CAPTCHA point: "default"', 'CAPTCHA');
- // Set to 'baz/boo'.
- captcha_set_form_id_setting($comment_form_id, 'baz/boo');
- $result = captcha_get_form_id_setting($comment_form_id);
- $this->assertNotNull($result, 'Setting and getting CAPTCHA point: baz/boo', 'CAPTCHA');
- $this->assertEqual($result->module, 'baz', 'Setting and getting CAPTCHA point: baz/boo', 'CAPTCHA');
- $this->assertEqual($result->captcha_type, 'boo', 'Setting and getting CAPTCHA point: baz/boo', 'CAPTCHA');
- $result = captcha_get_form_id_setting($comment_form_id, TRUE);
- $this->assertEqual($result, 'baz/boo', 'Setting and symbolic getting CAPTCHA point: "baz/boo"', 'CAPTCHA');
- // Set to NULL (which should delete the CAPTCHA point setting entry).
- captcha_set_form_id_setting($comment_form_id, NULL);
- $result = captcha_get_form_id_setting($comment_form_id);
- $this->assertNull($result, 'Setting and getting CAPTCHA point: NULL', 'CAPTCHA');
- $result = captcha_get_form_id_setting($comment_form_id, TRUE);
- $this->assertNull($result, 'Setting and symbolic getting CAPTCHA point: NULL', 'CAPTCHA');
- // Set with object.
- $captcha_type = new stdClass;
- $captcha_type->module = 'baba';
- $captcha_type->captcha_type = 'fofo';
- captcha_set_form_id_setting($comment_form_id, $captcha_type);
- $result = captcha_get_form_id_setting($comment_form_id);
- $this->assertNotNull($result, 'Setting and getting CAPTCHA point: baba/fofo', 'CAPTCHA');
- $this->assertEqual($result->module, 'baba', 'Setting and getting CAPTCHA point: baba/fofo', 'CAPTCHA');
- $this->assertEqual($result->captcha_type, 'fofo', 'Setting and getting CAPTCHA point: baba/fofo', 'CAPTCHA');
- $result = captcha_get_form_id_setting($comment_form_id, TRUE);
- $this->assertEqual($result, 'baba/fofo', 'Setting and symbolic getting CAPTCHA point: "baba/fofo"', 'CAPTCHA');
- }
- /**
- * Helper function for checking CAPTCHA setting of a form.
- *
- * @param $form_id the form_id of the form to investigate.
- * @param $challenge_type what the challenge type should be:
- * NULL, 'none', 'default' or something like 'captcha/Math'
- */
- protected function assertCaptchaSetting($form_id, $challenge_type) {
- $result = captcha_get_form_id_setting(self::COMMENT_FORM_ID, TRUE);
- $this->assertEqual($result, $challenge_type,
- t('Check CAPTCHA setting for form: expected: @expected, received: @received.',
- array('@expected' => var_export($challenge_type, TRUE), '@received' => var_export($result, TRUE))),
- 'CAPTCHA');
- }
- /**
- * Testing of the CAPTCHA administration links.
- */
- function testCaptchAdminLinks() {
- // Log in as admin
- $this->drupalLogin($this->admin_user);
- // Enable CAPTCHA administration links.
- $edit = array(
- 'captcha_administration_mode' => TRUE,
- );
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH, $edit, 'Save configuration');
- // Create a node with comments enabled.
- $node = $this->createNodeWithCommentsEnabled();
- // Go to node page
- $this->drupalGet('node/' . $node->nid);
- // Click the add new comment link
- $this->clickLink(t('Add new comment'));
- $add_comment_url = $this->getUrl();
- // Remove fragment part from comment URL to avoid problems with later asserts
- $add_comment_url = strtok($add_comment_url, "#");
- ////////////////////////////////////////////////////////////
- // Click the CAPTCHA admin link to enable a challenge.
- $this->clickLink(t('Place a CAPTCHA here for untrusted users.'));
- // Enable Math CAPTCHA.
- $edit = array('captcha_type' => 'captcha/Math');
- $this->drupalPost($this->getUrl(), $edit, t('Save'));
- // Check if returned to original comment form.
- $this->assertUrl($add_comment_url, array(),
- 'After setting CAPTCHA with CAPTCHA admin links: should return to original form.', 'CAPTCHA');
- // Check if CAPTCHA was successfully enabled (on CAPTCHA admin links fieldset).
- $this->assertText(t('CAPTCHA: challenge "@type" enabled', array('@type' => 'Math')),
- 'Enable a challenge through the CAPTCHA admin links', 'CAPTCHA');
- // Check if CAPTCHA was successfully enabled (through API).
- $this->assertCaptchaSetting(self::COMMENT_FORM_ID, 'captcha/Math');
- //////////////////////////////////////////////////////
- // Edit challenge type through CAPTCHA admin links.
- $this->clickLink(t('change'));
- // Enable Math CAPTCHA.
- $edit = array('captcha_type' => 'default');
- $this->drupalPost($this->getUrl(), $edit, t('Save'));
- // Check if returned to original comment form.
- $this->assertEqual($add_comment_url, $this->getUrl(),
- 'After editing challenge type CAPTCHA admin links: should return to original form.', 'CAPTCHA');
- // Check if CAPTCHA was successfully changed (on CAPTCHA admin links fieldset).
- // This is actually the same as the previous setting because the captcha/Math is the
- // default for the default challenge. TODO Make sure the edit is a real change.
- $this->assertText(t('CAPTCHA: challenge "@type" enabled', array('@type' => 'Math')),
- 'Enable a challenge through the CAPTCHA admin links', 'CAPTCHA');
- // Check if CAPTCHA was successfully edited (through API).
- $this->assertCaptchaSetting(self::COMMENT_FORM_ID, 'default');
- //////////////////////////////////////////////////////
- // Disable challenge through CAPTCHA admin links.
- $this->clickLink(t('disable'));
- // And confirm.
- $this->drupalPost($this->getUrl(), array(), 'Disable');
- // Check if returned to original comment form.
- $this->assertEqual($add_comment_url, $this->getUrl(),
- 'After disablin challenge with CAPTCHA admin links: should return to original form.', 'CAPTCHA');
- // Check if CAPTCHA was successfully disabled (on CAPTCHA admin links fieldset).
- $this->assertText(t('CAPTCHA: no challenge enabled'),
- 'Disable challenge through the CAPTCHA admin links', 'CAPTCHA');
- // Check if CAPTCHA was successfully disabled (through API).
- $this->assertCaptchaSetting(self::COMMENT_FORM_ID, 'none');
- }
- function testUntrustedUserPosting() {
- // Set CAPTCHA on comment form.
- captcha_set_form_id_setting(self::COMMENT_FORM_ID, 'captcha/Math');
- // Create a node with comments enabled.
- $node = $this->createNodeWithCommentsEnabled();
- // Log in as normal (untrusted) user.
- $this->drupalLogin($this->normal_user);
- // Go to node page and click the "add comment" link.
- $this->drupalGet('node/' . $node->nid);
- $this->clickLink(t('Add new comment'));
- $add_comment_url = $this->getUrl();
- // Check if CAPTCHA is visible on form.
- $this->assertCaptchaPresence(TRUE);
- // Try to post a comment with wrong answer.
- $edit = $this->getCommentFormValues();
- $edit['captcha_response'] = 'xx';
- $this->drupalPost($add_comment_url, $edit, t('Preview'));
- $this->assertText(t(CAPTCHA_WRONG_RESPONSE_ERROR_MESSAGE),
- 'wrong CAPTCHA should block form submission.', 'CAPTCHA');
- //TODO: more testing for untrusted posts.
- }
- /**
- * Test XSS vulnerability on CAPTCHA description.
- */
- function testXssOnCaptchaDescription() {
- // Set CAPTCHA on user register form.
- captcha_set_form_id_setting('user_register', 'captcha/Math');
- // Put JavaScript snippet in CAPTCHA description.
- $this->drupalLogin($this->admin_user);
- $xss = '<script type="text/javascript">alert("xss")</script>';
- $edit = array('captcha_description' => $xss);
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH, $edit, 'Save configuration');
- // Visit user register form and check if JavaScript snippet is there.
- $this->drupalLogout();
- $this->drupalGet('user/register');
- $this->assertNoRaw($xss, 'JavaScript should not be allowed in CAPTCHA description.', 'CAPTCHA');
- }
- /**
- * Test the CAPTCHA placement clearing.
- */
- function testCaptchaPlacementCacheClearing() {
- // Set CAPTCHA on user register form.
- captcha_set_form_id_setting('user_register_form', 'captcha/Math');
- // Visit user register form to fill the CAPTCHA placement cache.
- $this->drupalGet('user/register');
- // Check if there is CAPTCHA placement cache.
- $placement_map = variable_get('captcha_placement_map_cache', NULL);
- $this->assertNotNull($placement_map, 'CAPTCHA placement cache should be set.');
- // Clear the cache
- $this->drupalLogin($this->admin_user);
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH, array(), t('Clear the CAPTCHA placement cache'));
- // Check that the placement cache is unset
- $placement_map = variable_get('captcha_placement_map_cache', NULL);
- $this->assertNull($placement_map, 'CAPTCHA placement cache should be unset after cache clear.');
- }
- /**
- * Helper function to get the CAPTCHA point setting straight from the database.
- * @param string $form_id
- * @return stdClass object
- */
- private function getCaptchaPointSettingFromDatabase($form_id) {
- $result = db_query(
- "SELECT * FROM {captcha_points} WHERE form_id = :form_id",
- array(':form_id' => $form_id)
- )->fetchObject();
- return $result;
- }
- /**
- * Method for testing the CAPTCHA point administration
- */
- function testCaptchaPointAdministration() {
- // Generate CAPTCHA point data:
- // Drupal form ID should consist of lowercase alphanumerics and underscore)
- $captcha_point_form_id = 'form_' . strtolower($this->randomName(32));
- // the Math CAPTCHA by the CAPTCHA module is always available, so let's use it
- $captcha_point_module = 'captcha';
- $captcha_point_type = 'Math';
- // Log in as admin
- $this->drupalLogin($this->admin_user);
- // Set CAPTCHA point through admin/user/captcha/captcha/captcha_point
- $form_values = array(
- 'captcha_point_form_id' => $captcha_point_form_id,
- 'captcha_type' => $captcha_point_module .'/'. $captcha_point_type,
- );
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point', $form_values, t('Save'));
- $this->assertText(t('Saved CAPTCHA point settings.'),
- 'Saving of CAPTCHA point settings');
- // Check in database
- $result = $this->getCaptchaPointSettingFromDatabase($captcha_point_form_id);
- $this->assertEqual($result->module, $captcha_point_module,
- 'Enabled CAPTCHA point should have module set');
- $this->assertEqual($result->captcha_type, $captcha_point_type,
- 'Enabled CAPTCHA point should have type set');
- // Disable CAPTCHA point again
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/'. $captcha_point_form_id .'/disable', array(), t('Disable'));
- $this->assertRaw(t('Disabled CAPTCHA for form %form_id.', array('%form_id' => $captcha_point_form_id)), 'Disabling of CAPTCHA point');
- // Check in database
- $result = $this->getCaptchaPointSettingFromDatabase($captcha_point_form_id);
- $this->assertNull($result->module,
- 'Disabled CAPTCHA point should have NULL as module');
- $this->assertNull($result->captcha_type,
- 'Disabled CAPTCHA point should have NULL as type');
- // Set CAPTCHA point through admin/user/captcha/captcha/captcha_point/$form_id
- $form_values = array(
- 'captcha_type' => $captcha_point_module .'/'. $captcha_point_type,
- );
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/'. $captcha_point_form_id, $form_values, t('Save'));
- $this->assertText(t('Saved CAPTCHA point settings.'),
- 'Saving of CAPTCHA point settings');
- // Check in database
- $result = $this->getCaptchaPointSettingFromDatabase($captcha_point_form_id);
- $this->assertEqual($result->module, $captcha_point_module,
- 'Enabled CAPTCHA point should have module set');
- $this->assertEqual($result->captcha_type, $captcha_point_type,
- 'Enabled CAPTCHA point should have type set');
- // Delete CAPTCHA point
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/'. $captcha_point_form_id .'/delete', array(), t('Delete'));
- $this->assertRaw(t('Deleted CAPTCHA for form %form_id.', array('%form_id' => $captcha_point_form_id)),
- 'Deleting of CAPTCHA point');
- // Check in database
- $result = $this->getCaptchaPointSettingFromDatabase($captcha_point_form_id);
- $this->assertFalse($result, 'Deleted CAPTCHA point should be in database');
- }
- /**
- * Method for testing the CAPTCHA point administration
- */
- function testCaptchaPointAdministrationByNonAdmin() {
- // First add a CAPTCHA point (as admin)
- $this->drupalLogin($this->admin_user);
- $captcha_point_form_id = 'form_' . strtolower($this->randomName(32));
- $captcha_point_module = 'captcha';
- $captcha_point_type = 'Math';
- $form_values = array(
- 'captcha_point_form_id' => $captcha_point_form_id,
- 'captcha_type' => $captcha_point_module .'/'. $captcha_point_type,
- );
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/', $form_values, t('Save'));
- $this->assertText(t('Saved CAPTCHA point settings.'),
- 'Saving of CAPTCHA point settings');
- // Switch from admin to nonadmin
- $this->drupalGet(url('logout', array('absolute' => TRUE)));
- $this->drupalLogin($this->normal_user);
- // Try to set CAPTCHA point through admin/user/captcha/captcha/captcha_point
- $this->drupalGet(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point');
- $this->assertText(t('You are not authorized to access this page.'),
- 'Non admin should not be able to set a CAPTCHA point');
- // Try to set CAPTCHA point through admin/user/captcha/captcha/captcha_point/$form_id
- $this->drupalGet(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/' . 'form_' . strtolower($this->randomName(32)));
- $this->assertText(t('You are not authorized to access this page.'),
- 'Non admin should not be able to set a CAPTCHA point');
- // Try to disable the CAPTCHA point
- $this->drupalGet(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/'. $captcha_point_form_id .'/disable');
- $this->assertText(t('You are not authorized to access this page.'),
- 'Non admin should not be able to disable a CAPTCHA point');
- // Try to delete the CAPTCHA point
- $this->drupalGet(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/'. $captcha_point_form_id .'/delete');
- $this->assertText(t('You are not authorized to access this page.'),
- 'Non admin should not be able to delete a CAPTCHA point');
- // Switch from nonadmin to admin again
- $this->drupalGet(url('logout', array('absolute' => TRUE)));
- $this->drupalLogin($this->admin_user);
- // Check if original CAPTCHA point still exists in database
- $result = $this->getCaptchaPointSettingFromDatabase($captcha_point_form_id);
- $this->assertEqual($result->module, $captcha_point_module,
- 'Enabled CAPTCHA point should still have module set');
- $this->assertEqual($result->captcha_type, $captcha_point_type,
- 'Enabled CAPTCHA point should still have type set');
- // Delete CAPTCHA point
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH . '/captcha/captcha_point/'. $captcha_point_form_id .'/delete', array(), t('Delete'));
- $this->assertRaw(t('Deleted CAPTCHA for form %form_id.', array('%form_id' => $captcha_point_form_id)),
- 'Deleting of CAPTCHA point');
- }
- }
- class CaptchaPersistenceTestCase extends CaptchaBaseWebTestCase {
- public static function getInfo() {
- return array(
- 'name' => t('CAPTCHA persistence functionality'),
- 'description' => t('Testing of the CAPTCHA persistence functionality.'),
- 'group' => t('CAPTCHA'),
- );
- }
- /**
- * Set up the persistence and CAPTCHA settings.
- * @param int $persistence the persistence value.
- */
- private function setUpPersistence($persistence) {
- // Log in as admin
- $this->drupalLogin($this->admin_user);
- // Set persistence.
- $edit = array('captcha_persistence' => $persistence);
- $this->drupalPost(self::CAPTCHA_ADMIN_PATH, $edit, 'Save configuration');
- // Log admin out.
- $this->drupalLogout();
- // Set the Test123 CAPTCHA on user register and comment form.
- // We have to do this with the function captcha_set_form_id_setting()
- // (because the CATCHA admin form does not show the Test123 option).
- // We also have to do this after all usage of the CAPTCHA admin form
- // (because posting the CAPTCHA admin form would set the CAPTCHA to 'none').
- captcha_set_form_id_setting('user_login', 'captcha/Test');
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- captcha_set_form_id_setting('user_register_form', 'captcha/Test');
- $this->drupalGet('user/register');
- $this->assertCaptchaPresence(TRUE);
- }
- protected function assertPreservedCsid($captcha_sid_initial) {
- $captcha_sid = $this->getCaptchaSidFromForm();
- $this->assertEqual($captcha_sid_initial, $captcha_sid,
- "CAPTCHA session ID should be preserved (expected: $captcha_sid_initial, found: $captcha_sid).");
- }
- protected function assertDifferentCsid($captcha_sid_initial) {
- $captcha_sid = $this->getCaptchaSidFromForm();
- $this->assertNotEqual($captcha_sid_initial, $captcha_sid,
- "CAPTCHA session ID should be different.");
- }
- function testPersistenceAlways(){
- // Set up of persistence and CAPTCHAs.
- $this->setUpPersistence(CAPTCHA_PERSISTENCE_SHOW_ALWAYS);
- // Go to login form and check if there is a CAPTCHA on the login form (look for the title).
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- $captcha_sid_initial = $this->getCaptchaSidFromForm();
- // Try to with wrong user name and password, but correct CAPTCHA.
- $edit = array(
- 'name' => 'foobar',
- 'pass' => 'bazlaz',
- 'captcha_response' => 'Test 123',
- );
- $this->drupalPost(NULL, $edit, t('Log in'));
- // Check that there was no error message for the CAPTCHA.
- $this->assertCaptchaResponseAccepted();
- // Name and password were wrong, we should get an updated form with a fresh CAPTCHA.
- $this->assertCaptchaPresence(TRUE);
- $this->assertPreservedCsid($captcha_sid_initial);
- // Post from again.
- $this->drupalPost(NULL, $edit, t('Log in'));
- // Check that there was no error message for the CAPTCHA.
- $this->assertCaptchaResponseAccepted();
- $this->assertPreservedCsid($captcha_sid_initial);
- }
- function testPersistencePerFormInstance(){
- // Set up of persistence and CAPTCHAs.
- $this->setUpPersistence(CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_INSTANCE);
- // Go to login form and check if there is a CAPTCHA on the login form.
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- $captcha_sid_initial = $this->getCaptchaSidFromForm();
- // Try to with wrong user name and password, but correct CAPTCHA.
- $edit = array(
- 'name' => 'foobar',
- 'pass' => 'bazlaz',
- 'captcha_response' => 'Test 123',
- );
- $this->drupalPost(NULL, $edit, t('Log in'));
- // Check that there was no error message for the CAPTCHA.
- $this->assertCaptchaResponseAccepted();
- // There shouldn't be a CAPTCHA on the new form.
- $this->assertCaptchaPresence(FALSE);
- $this->assertPreservedCsid($captcha_sid_initial);
- // Start a new form instance/session
- $this->drupalGet('node');
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- $this->assertDifferentCsid($captcha_sid_initial);
- // Check another form
- $this->drupalGet('user/register');
- $this->assertCaptchaPresence(TRUE);
- $this->assertDifferentCsid($captcha_sid_initial);
- }
- function testPersistencePerFormType(){
- // Set up of persistence and CAPTCHAs.
- $this->setUpPersistence(CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_TYPE);
- // Go to login form and check if there is a CAPTCHA on the login form.
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- $captcha_sid_initial = $this->getCaptchaSidFromForm();
- // Try to with wrong user name and password, but correct CAPTCHA.
- $edit = array(
- 'name' => 'foobar',
- 'pass' => 'bazlaz',
- 'captcha_response' => 'Test 123',
- );
- $this->drupalPost(NULL, $edit, t('Log in'));
- // Check that there was no error message for the CAPTCHA.
- $this->assertCaptchaResponseAccepted();
- // There shouldn't be a CAPTCHA on the new form.
- $this->assertCaptchaPresence(FALSE);
- $this->assertPreservedCsid($captcha_sid_initial);
- // Start a new form instance/session
- $this->drupalGet('node');
- $this->drupalGet('user');
- $this->assertCaptchaPresence(FALSE);
- $this->assertDifferentCsid($captcha_sid_initial);
- // Check another form
- $this->drupalGet('user/register');
- $this->assertCaptchaPresence(TRUE);
- $this->assertDifferentCsid($captcha_sid_initial);
- }
- function testPersistenceOnlyOnce(){
- // Set up of persistence and CAPTCHAs.
- $this->setUpPersistence(CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL);
- // Go to login form and check if there is a CAPTCHA on the login form.
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- $captcha_sid_initial = $this->getCaptchaSidFromForm();
- // Try to with wrong user name and password, but correct CAPTCHA.
- $edit = array(
- 'name' => 'foobar',
- 'pass' => 'bazlaz',
- 'captcha_response' => 'Test 123',
- );
- $this->drupalPost(NULL, $edit, t('Log in'));
- // Check that there was no error message for the CAPTCHA.
- $this->assertCaptchaResponseAccepted();
- // There shouldn't be a CAPTCHA on the new form.
- $this->assertCaptchaPresence(FALSE);
- $this->assertPreservedCsid($captcha_sid_initial);
- // Start a new form instance/session
- $this->drupalGet('node');
- $this->drupalGet('user');
- $this->assertCaptchaPresence(FALSE);
- $this->assertDifferentCsid($captcha_sid_initial);
- // Check another form
- $this->drupalGet('user/register');
- $this->assertCaptchaPresence(FALSE);
- $this->assertDifferentCsid($captcha_sid_initial);
- }
- }
- class CaptchaSessionReuseAttackTestCase extends CaptchaBaseWebTestCase {
- public static function getInfo() {
- return array(
- 'name' => t('CAPTCHA session reuse attack tests'),
- 'description' => t('Testing of the protection against CAPTCHA session reuse attacks.'),
- 'group' => t('CAPTCHA'),
- );
- }
- /**
- * Assert that the CAPTCHA session ID reuse attack was detected.
- */
- protected function assertCaptchaSessionIdReuseAttackDetection() {
- $this->assertText(t(CAPTCHA_SESSION_REUSE_ATTACK_ERROR_MESSAGE),
- 'CAPTCHA session ID reuse attack should be detected.',
- 'CAPTCHA');
- // There should be an error message about wrong response.
- $this->assertText(t(CAPTCHA_WRONG_RESPONSE_ERROR_MESSAGE),
- 'CAPTCHA response should flagged as wrong.',
- 'CAPTCHA');
- }
- function testCaptchaSessionReuseAttackDetectionOnCommentPreview() {
- // Create commentable node
- $node = $this->createNodeWithCommentsEnabled();
- // Set Test CAPTCHA on comment form.
- captcha_set_form_id_setting(self::COMMENT_FORM_ID, 'captcha/Math');
- variable_set('captcha_persistence', CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_INSTANCE);
- // Log in as normal user.
- $this->drupalLogin($this->normal_user);
- // Go to comment form of commentable node.
- $this->drupalGet('comment/reply/' . $node->nid);
- $this->assertCaptchaPresence(TRUE);
- // Get CAPTCHA session ID and solution of the challenge.
- $captcha_sid = $this->getCaptchaSidFromForm();
- $captcha_token = $this->getCaptchaTokenFromForm();
- $solution = $this->getMathCaptchaSolutionFromForm();
- // Post the form with the solution.
- $edit = $this->getCommentFormValues();
- $edit['captcha_response'] = $solution;
- $this->drupalPost(NULL, $edit, t('Preview'));
- // Answer should be accepted and further CAPTCHA ommitted.
- $this->assertCaptchaResponseAccepted();
- $this->assertCaptchaPresence(FALSE);
- // Post a new comment, reusing the previous CAPTCHA session.
- $edit = $this->getCommentFormValues();
- $edit['captcha_sid'] = $captcha_sid;
- $edit['captcha_token'] = $captcha_token;
- $edit['captcha_response'] = $solution;
- $this->drupalPost('comment/reply/' . $node->nid, $edit, t('Preview'));
- // CAPTCHA session reuse attack should be detected.
- $this->assertCaptchaSessionIdReuseAttackDetection();
- // There should be a CAPTCHA.
- $this->assertCaptchaPresence(TRUE);
- }
- function testCaptchaSessionReuseAttackDetectionOnNodeForm() {
- // Set CAPTCHA on page form.
- captcha_set_form_id_setting('page_node_form', 'captcha/Math');
- variable_set('captcha_persistence', CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_INSTANCE);
- // Log in as normal user.
- $this->drupalLogin($this->normal_user);
- // Go to node add form.
- $this->drupalGet('node/add/page');
- $this->assertCaptchaPresence(TRUE);
- // Get CAPTCHA session ID and solution of the challenge.
- $captcha_sid = $this->getCaptchaSidFromForm();
- $captcha_token = $this->getCaptchaTokenFromForm();
- $solution = $this->getMathCaptchaSolutionFromForm();
- // Page settings to post, with correct CAPTCHA answer.
- $edit = $this->getNodeFormValues();
- $edit['captcha_response'] = $solution;
- // Preview the node
- $this->drupalPost(NULL, $edit, t('Preview'));
- // Answer should be accepted.
- $this->assertCaptchaResponseAccepted();
- // Check that there is no CAPTCHA after preview.
- $this->assertCaptchaPresence(FALSE);
- // Post a new comment, reusing the previous CAPTCHA session.
- $edit = $this->getNodeFormValues();
- $edit['captcha_sid'] = $captcha_sid;
- $edit['captcha_token'] = $captcha_token;
- $edit['captcha_response'] = $solution;
- $this->drupalPost('node/add/page', $edit, t('Preview'));
- // CAPTCHA session reuse attack should be detected.
- $this->assertCaptchaSessionIdReuseAttackDetection();
- // There should be a CAPTCHA.
- $this->assertCaptchaPresence(TRUE);
- }
- function testCaptchaSessionReuseAttackDetectionOnLoginForm() {
- // Set CAPTCHA on login form.
- captcha_set_form_id_setting('user_login', 'captcha/Math');
- variable_set('captcha_persistence', CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_INSTANCE);
- // Go to log in form.
- $this->drupalGet('user');
- $this->assertCaptchaPresence(TRUE);
- // Get CAPTCHA session ID and solution of the challenge.
- $captcha_sid = $this->getCaptchaSidFromForm();
- $captcha_token = $this->getCaptchaTokenFromForm();
- $solution = $this->getMathCaptchaSolutionFromForm();
- // Log in through form.
- $edit = array(
- 'name' => $this->normal_user->name,
- 'pass' => $this->normal_user->pass_raw,
- 'captcha_response' => $solution,
- );
- $this->drupalPost(NULL, $edit, t('Log in'));
- $this->assertCaptchaResponseAccepted();
- $this->assertCaptchaPresence(FALSE);
- // If a "log out" link appears on the page, it is almost certainly because
- // the login was successful.
- $pass = $this->assertLink(t('Log out'), 0, t('User %name successfully logged in.', array('%name' => $this->normal_user->name)), t('User login'));
- // Log out again.
- $this->drupalLogout();
- // Try to log in again, reusing the previous CAPTCHA session.
- $edit += array(
- 'captcha_sid' => $captcha_sid,
- 'captcha_token' => $captcha_token,
- );
- $this->drupalPost('user', $edit, t('Log in'));
- // CAPTCHA session reuse attack should be detected.
- $this->assertCaptchaSessionIdReuseAttackDetection();
- // There should be a CAPTCHA.
- $this->assertCaptchaPresence(TRUE);
- }
- public function testMultipleCaptchaProtectedFormsOnOnePage()
- {
- // Set Test CAPTCHA on comment form and login block
- captcha_set_form_id_setting(self::COMMENT_FORM_ID, 'captcha/Test');
- captcha_set_form_id_setting('user_login_block', 'captcha/Math');
- $this->allowCommentPostingForAnonymousVisitors();
- // Create a node with comments enabled.
- $node = $this->createNodeWithCommentsEnabled();
- // Preview comment with correct CAPTCHA answer.
- $edit = $this->getCommentFormValues();
- $comment_subject = $edit['subject'];
- $edit['captcha_response'] = 'Test 123';
- $this->drupalPost('comment/reply/' . $node->nid, $edit, t('Preview'));
- // Post should be accepted: no warnings,
- // no CAPTCHA reuse detection (which could be used by user log in block).
- $this->assertCaptchaResponseAccepted();
- $this->assertText($comment_subject);
- }
- }
- // Some tricks to debug:
- // drupal_debug($data) // from devel module
- // file_put_contents('tmp.simpletest.html', $this->drupalGetContent());
|