/[drupal]/contributions/modules/captcha/captcha.test
ViewVC logotype

Contents of /contributions/modules/captcha/captcha.test

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.13 - (show annotations) (download) (as text)
Thu Jul 2 23:45:05 2009 UTC (4 months, 3 weeks ago) by soxofaan
Branch: MAIN
CVS Tags: DRUPAL-6--2-0-RC3, DRUPAL-6--2-0-RC2, DRUPAL-6--2-0, HEAD
Changes since 1.12: +5 -4 lines
File MIME type: text/x-php
#473002: CAPTCHA API now provides a way to define a custom CAPTCHA validation function
1 <?php
2 // $Id: captcha.test,v 1.12 2009/05/26 21:55:25 soxofaan Exp $
3
4 /**
5 * @file
6 * Tests for CAPTCHA module.
7 */
8
9 // TODO: write test to check persistence
10 // TODO: write test for CAPTCHAs on admin pages
11 // TODO: test for default challenge type
12 // TODO: test about placement (comment form, node forms, log in form, etc)
13 // TODO: test if captcha_cron does it work right
14 // TODO: test custom CAPTCHA validation stuff
15
16 class CapchaTestCase extends DrupalWebTestCase {
17
18 public static function getInfo() {
19 return array(
20 'name' => t('CAPTCHA functionality'),
21 'description' => t('Testing of the basic CAPTCHA functionality.'),
22 'group' => t('CAPTCHA'),
23 );
24 }
25
26 function setUp() {
27 // Load two modules: the captcha module itself and the comment module for testing anonymous comments.
28 parent::setUp('captcha', 'comment');
29 module_load_include('inc', 'captcha');
30
31 // Create a normal user that can post comments and pages,
32 // but can not skip CAPTCHA.
33 $permissions = array(
34 'access comments', 'post comments', 'post comments without approval',
35 'access content', 'create page content', 'edit own page content',
36 );
37 $this->normal_user = $this->drupalCreateUser($permissions);
38
39 }
40
41 /**
42 * Testing the protection of the user log in form.
43 */
44 function testCaptchaOnLoginForm() {
45 // Create user and test log in without CAPTCHA.
46 $user = $this->drupalCreateUser();
47 $this->drupalLogin($user);
48 // Log out again.
49 $this->drupalLogout();
50
51 // Set a CAPTCHA on login form
52 captcha_set_form_id_setting('user_login', 'captcha/Math');
53
54 // Check if there is a CAPTCHA on the login form (look for the title).
55 $this->drupalGet('user');
56 $captcha = captcha_captcha('generate', 'Math');
57 $this->assertText($captcha['form']['captcha_response']['#title'], 'CAPTCHA should be added to form (user_login).', 'CAPTCHA');
58
59
60 // Try to log in, which should fail.
61 $edit = array(
62 'name' => $user->name,
63 'pass' => $user->pass_raw,
64 'captcha_response' => '?',
65 );
66 $this->drupalPost('user', $edit, t('Log in'));
67 // Check for error message.
68 $this->assertText(t('The answer you entered for the CAPTCHA was not correct.'),
69 'CAPTCHA should block user login form', 'CAPTCHA');
70
71 // And make sure that user is not logged in: check for name and password fields on ?q=user
72 $this->drupalGet('user');
73 $this->assertField('name', t('Username field found.'), 'CAPTCHA');
74 $this->assertField('pass', t('Password field found.'), 'CAPTCHA');
75
76 }
77
78
79 /**
80 * Assert function for testing if comment posting works as it should.
81 *
82 * Creates node with comment writing enabled, tries to post comment
83 * with given CAPTCHA response (caller should enable the desired
84 * challenge on comment_form) and checks if the result is as expected.
85 *
86 * @param $captcha_response the response on the CAPTCHA
87 * @param $should_pass boolean describing if the posting should pass or should be blocked
88 * @param $message message to prefix to nested asserts
89 */
90 function assertCommentPosting($captcha_response, $should_pass, $message) {
91 // Make sure comments on pages can be saved directely without preview.
92 variable_set('comment_preview_page', COMMENT_PREVIEW_OPTIONAL);
93
94 // Create a node with comments enabled.
95 $node_settings = array(
96 'type' => 'page',
97 'comment' => COMMENT_NODE_READ_WRITE,
98 );
99 $node = $this->drupalCreateNode($node_settings);
100
101 // Post comment on node.
102 $edit = array(
103 'subject' => $this->randomName(32, 'subject_'),
104 'comment' => $this->randomName(256, 'comment_body'),
105 'captcha_response' => $captcha_response,
106 );
107 $this->drupalPost('comment/reply/' . $node->nid, $edit, t('Save'));
108
109 if ($should_pass) {
110 // There should be no error message.
111 $this->assertNoText(t('The answer you entered for the CAPTCHA was not correct.'),
112 $message .' Comment submission should pass.', 'CAPTCHA');
113 // Get node page and check that comment shows up.
114 $this->drupalGet('node/' . $node->nid);
115 $this->assertText($edit['comment'],
116 $message .' Comment should show up on node page.', 'CAPTCHA');
117 }
118 else {
119 // Check for error message.
120 $this->assertText(t('The answer you entered for the CAPTCHA was not correct.'),
121 $message .' Comment submission should be blocked.', 'CAPTCHA');
122 // Get node page and check that comment is not present.
123 $this->drupalGet('node/' . $node->nid);
124 $this->assertNoText($edit['comment'],
125 $message .' Comment should not show up on node page.', 'CAPTCHA');
126 }
127 }
128
129 /*
130 * Testing the case sensistive/insensitive validation.
131 */
132 function testCaseInsensitiveValidation() {
133 // Set Test CAPTCHA on comment form
134 captcha_set_form_id_setting('comment_form', 'captcha/Test');
135
136 // Log in as normal user.
137 $this->drupalLogin($this->normal_user);
138
139 // Test case sensitive posting.
140 variable_set('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE);
141 $this->assertCommentPosting('Test 123', TRUE, 'Case sensitive validation of right casing.');
142 $this->assertCommentPosting('test 123', FALSE, 'Case sensitive validation of wrong casing.');
143 $this->assertCommentPosting('TEST 123', FALSE, 'Case sensitive validation of wrong casing.');
144
145 // Test case insensitive posting (the default)
146 variable_set('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE);
147 $this->assertCommentPosting('Test 123', TRUE, 'Case insensitive validation of right casing.');
148 $this->assertCommentPosting('test 123', TRUE, 'Case insensitive validation of wrong casing.');
149 $this->assertCommentPosting('TEST 123', TRUE, 'Case insensitive validation of wrong casing.');
150
151 }
152
153 /**
154 * Test if the CAPTCHA description is only shown if there are challenge widgets to show.
155 * For example, when a comment is previewed with correct CAPTCHA answer,
156 * a challenge is generated and added to the form but removed in the pre_render phase.
157 * The CAPTCHA description should not show up either.
158 *
159 * \see testCaptchaSessionReuseOnNodeForms()
160 */
161 function testCaptchaDescriptionAfterCommentPreview() {
162 // Set Test CAPTCHA on comment form.
163 captcha_set_form_id_setting('comment_form', 'captcha/Test');
164
165 // Log in as normal user.
166 $this->drupalLogin($this->normal_user);
167
168 // Create a node with comments enabled.
169 $node = $this->drupalCreateNode(array('comment' => COMMENT_NODE_READ_WRITE));
170
171 // Preview comment with correct CAPTCHA answer.
172 $edit = array(
173 'subject' => $this->randomName(32, 'subject_'),
174 'comment' => $this->randomName(256, 'comment_body'),
175 'captcha_response' => 'Test 123',
176 );
177 $this->drupalPost('comment/reply/' . $node->nid, $edit, t('Preview'));
178
179 // Check that there is no CAPTCHA after preview.
180 $this->assertNoText(_captcha_get_description(),
181 'CAPTCHA description should not show up after comment preview with correct response.', 'CAPTCHA');
182 }
183
184 /**
185 * Test if the CAPTCHA session ID is reused when previewing nodes:
186 * node preview after correct response should not show CAPTCHA anymore.
187 * The preview functionality of comments and nodes works slightly different under the hood.
188 * CAPTCHA module should be able to handle both.
189 *
190 * \see testCaptchaDescriptionAfterCommentPreview()
191 */
192 function testCaptchaSessionReuseOnNodeForms() {
193 // Set Test CAPTCHA on page form.
194 captcha_set_form_id_setting('page_node_form', 'captcha/Test');
195
196 // Log in as normal user.
197 $this->drupalLogin($this->normal_user);
198
199 // Page settings to post, with correct CAPTCHA answer.
200 $edit = array(
201 'title' => $this->randomName(8),
202 'body' => $this->randomName(32),
203 'captcha_response' => 'Test 123',
204 );
205 // Preview the node
206 $this->drupalPost('node/add/page', $edit, t('Preview'));
207
208 // Check that there is no CAPTCHA after preview.
209 $this->assertNoText(_captcha_get_description(),
210 'CAPTCHA description should not show up after node preview with correct response.', 'CAPTCHA');
211 }
212
213 }
214
215
216 class CapchaAdminTestCase extends DrupalWebTestCase {
217
218 public static function getInfo() {
219 return array(
220 'name' => t('CAPTCHA administration functionality'),
221 'description' => t('Testing of the CAPTCHA administration interface and functionality.'),
222 'group' => t('CAPTCHA'),
223 );
224 }
225
226 function setUp() {
227 // Load two modules: the captcha module itself and the comment module for testing anonymous comments.
228 parent::setUp('captcha', 'comment');
229 module_load_include('inc', 'captcha');
230
231 // Create a normal user.
232 $permissions = array(
233 'access comments', 'post comments', 'post comments without approval',
234 );
235 $this->normal_user = $this->drupalCreateUser($permissions);
236 // Create an admin user.
237 $permissions[] = 'administer CAPTCHA settings';
238 $permissions[] = 'skip CAPTCHA';
239 $this->admin_user = $this->drupalCreateUser($permissions);
240
241 }
242
243 /**
244 * Test access to the admin pages.
245 */
246 function testAdminAccess() {
247 $this->drupalLogin($this->normal_user);
248 $this->drupalGet('admin/user/captcha');
249 file_put_contents('tmp.simpletest.html', $this->drupalGetContent());
250 $this->assertText(t('Access denied'), 'Normal users should not be able to access the CAPTCHA admin pages', 'CAPTCHA');
251
252 $this->drupalLogin($this->admin_user);
253 $this->drupalGet('admin/user/captcha');
254 $this->assertNoText(t('Access denied'), 'Admin users should be able to access the CAPTCHA admin pages', 'CAPTCHA');
255 }
256
257 /**
258 * Test the CAPTCHA point setting getter/setter.
259 */
260 function testCaptchaPointSettingGetterAndSetter() {
261 // Set to 'none'.
262 captcha_set_form_id_setting('comment_form', 'none');
263 $result = captcha_get_form_id_setting('comment_form');
264 $this->assertNotNull($result, 'Setting and getting CAPTCHA point: none', 'CAPTCHA');
265 $this->assertNull($result->module, 'Setting and getting CAPTCHA point: none', 'CAPTCHA');
266 $this->assertNull($result->type, 'Setting and getting CAPTCHA point: none', 'CAPTCHA');
267 $result = captcha_get_form_id_setting('comment_form', TRUE);
268 $this->assertEqual($result, 'none', 'Setting and symbolic getting CAPTCHA point: "none"', 'CAPTCHA');
269 // Set to 'default'
270 captcha_set_form_id_setting('comment_form', 'default');
271 variable_set('captcha_default_challenge', 'foo/bar');
272 $result = captcha_get_form_id_setting('comment_form');
273 $this->assertNotNull($result, 'Setting and getting CAPTCHA point: default', 'CAPTCHA');
274 $this->assertEqual($result->module, 'foo', 'Setting and getting CAPTCHA point: default', 'CAPTCHA');
275 $this->assertEqual($result->type, 'bar', 'Setting and getting CAPTCHA point: default', 'CAPTCHA');
276 $result = captcha_get_form_id_setting('comment_form', TRUE);
277 $this->assertEqual($result, 'default', 'Setting and symbolic getting CAPTCHA point: "default"', 'CAPTCHA');
278 // Set to 'baz/boo'.
279 captcha_set_form_id_setting('comment_form', 'baz/boo');
280 $result = captcha_get_form_id_setting('comment_form');
281 $this->assertNotNull($result, 'Setting and getting CAPTCHA point: baz/boo', 'CAPTCHA');
282 $this->assertEqual($result->module, 'baz', 'Setting and getting CAPTCHA point: baz/boo', 'CAPTCHA');
283 $this->assertEqual($result->type, 'boo', 'Setting and getting CAPTCHA point: baz/boo', 'CAPTCHA');
284 $result = captcha_get_form_id_setting('comment_form', TRUE);
285 $this->assertEqual($result, 'baz/boo', 'Setting and symbolic getting CAPTCHA point: "baz/boo"', 'CAPTCHA');
286 // Set to NULL (which should delete the CAPTCHA point setting entry).
287 captcha_set_form_id_setting('comment_form', NULL);
288 $result = captcha_get_form_id_setting('comment_form');
289 $this->assertNull($result, 'Setting and getting CAPTCHA point: NULL', 'CAPTCHA');
290 $result = captcha_get_form_id_setting('comment_form', TRUE);
291 $this->assertNull($result, 'Setting and symbolic getting CAPTCHA point: NULL', 'CAPTCHA');
292 // Set with object.
293 $captcha_type = new stdClass;
294 $captcha_type->module = 'baba';
295 $captcha_type->type = 'fofo';
296 captcha_set_form_id_setting('comment_form', $captcha_type);
297 $result = captcha_get_form_id_setting('comment_form');
298 $this->assertNotNull($result, 'Setting and getting CAPTCHA point: baba/fofo', 'CAPTCHA');
299 $this->assertEqual($result->module, 'baba', 'Setting and getting CAPTCHA point: baba/fofo', 'CAPTCHA');
300 $this->assertEqual($result->type, 'fofo', 'Setting and getting CAPTCHA point: baba/fofo', 'CAPTCHA');
301 $result = captcha_get_form_id_setting('comment_form', TRUE);
302 $this->assertEqual($result, 'baba/fofo', 'Setting and symbolic getting CAPTCHA point: "baba/fofo"', 'CAPTCHA');
303
304 }
305
306
307 /**
308 * Helper function for checking CAPTCHA setting of a form.
309 *
310 * @param $form_id the form_id of the form to investigate.
311 * @param $challenge_type what the challenge type shoul be:
312 * NULL, 'none', 'default' or something like 'captcha/Math'
313 */
314 protected function assertCaptchaSetting($form_id, $challenge_type) {
315 $result = captcha_get_form_id_setting('comment_form', TRUE);
316 $this->assertEqual($result, $challenge_type, 'Check CAPTCHA setting for form.', 'CAPTCHA');
317 }
318
319 /**
320 * Testing of the CAPTCHA administration links.
321 */
322 function testCaptchAdminLinks() {
323 // Log in as admin
324 $this->drupalLogin($this->admin_user);
325
326 // Enable CAPTCHA administration links.
327 $edit = array(
328 'captcha_administration_mode' => TRUE,
329 );
330 $this->drupalPost('admin/user/captcha', $edit, 'Save configuration');
331
332 // Create a node with comments enabled.
333 $node_settings = array(
334 'type' => 'page',
335 'comment' => COMMENT_NODE_READ_WRITE,
336 );
337 $node = $this->drupalCreateNode($node_settings);
338
339 // Go to node page
340 $this->drupalGet('node/' . $node->nid);
341
342 // Click the add new comment link
343 $this->clickLink(t('Add new comment'));
344 $add_comment_url = $this->getUrl();
345
346 ////////////////////////////////////////////////////////////
347 // Click the CAPTCHA admin link to enable a challenge.
348 $this->clickLink(t('Place a CAPTCHA here for untrusted users.'));
349 // Enable Math CAPTCHA.
350 $edit = array('captcha_type' => 'captcha/Math');
351 $this->drupalPost($this->getUrl(), $edit, t('Save'));
352
353 // Check if returned to original comment form.
354 $this->assertEqual($add_comment_url, $this->getUrl(),
355 'After setting CAPTCHA with CAPTCHA admin links: should return to original form.', 'CAPTCHA');
356 // Check if CAPTCHA was successfully enabled (on CAPTCHA admin links fieldset).
357 $this->assertText(t('CAPTCHA: challenge "@type" enabled', array('@type' => 'Math')),
358 'Enable a challenge through the CAPTCHA admin links', 'CAPTCHA');
359 // Check if CAPTCHA was successfully enabled (through API).
360 $this->assertCaptchaSetting('comment_form', 'captcha/Math');
361
362 //////////////////////////////////////////////////////
363 // Edit challenge type through CAPTCHA admin links.
364 $this->clickLink(t('change'));
365 // Enable Math CAPTCHA.
366 $edit = array('captcha_type' => 'default');
367 $this->drupalPost($this->getUrl(), $edit, t('Save'));
368
369 // Check if returned to original comment form.
370 $this->assertEqual($add_comment_url, $this->getUrl(),
371 'After editing challenge type CAPTCHA admin links: should return to original form.', 'CAPTCHA');
372 // Check if CAPTCHA was successfully changed (on CAPTCHA admin links fieldset).
373 // This is actually the same as the previous setting because the captcha/Math is the
374 // default for the default challenge. TODO Make sure the edit is a real change.
375 $this->assertText(t('CAPTCHA: challenge "@type" enabled', array('@type' => 'Math')),
376 'Enable a challenge through the CAPTCHA admin links', 'CAPTCHA');
377 // Check if CAPTCHA was successfully edited (through API).
378 $this->assertCaptchaSetting('comment_form', 'default');
379
380
381
382 //////////////////////////////////////////////////////
383 // Disable challenge through CAPTCHA admin links.
384 $this->clickLink(t('disable'));
385 // And confirm.
386 $this->drupalPost($this->getUrl(), array(), 'Disable');
387
388 // Check if returned to original comment form.
389 $this->assertEqual($add_comment_url, $this->getUrl(),
390 'After disablin challenge with CAPTCHA admin links: should return to original form.', 'CAPTCHA');
391 // Check if CAPTCHA was successfully disabled (on CAPTCHA admin links fieldset).
392 $this->assertText(t('CAPTCHA: no challenge enabled'),
393 'Disable challenge through the CAPTCHA admin links', 'CAPTCHA');
394 // Check if CAPTCHA was successfully disabled (through API).
395 $this->assertCaptchaSetting('comment_form', 'none');
396
397 }
398
399
400 function testUntrustedUserPosting() {
401 // Set CAPTCHA on comment form.
402 captcha_set_form_id_setting('comment_form', 'captcha/Math');
403
404 // Create a node with comments enabled.
405 $node_settings = array(
406 'type' => 'page',
407 'comment' => COMMENT_NODE_READ_WRITE,
408 );
409 $node = $this->drupalCreateNode($node_settings);
410
411 // Log in as normal (untrusted) user.
412 $this->drupalLogin($this->normal_user);
413
414 // Go to node page and click the "add comment" link.
415 $this->drupalGet('node/' . $node->nid);
416 $this->clickLink(t('Add new comment'));
417 $add_comment_url = $this->getUrl();
418
419 // Check if CAPTCHA is visible on form.
420 $this->assertText(t('Math question'),
421 'CAPTCHA should be on form for untrusted user.', 'CAPTCHA');
422 // Try to post a comment with wrong answer.
423 $edit = array(
424 'subject' => 'check thiz out!',
425 'comment' => 'cool site u have',
426 'captcha_response' => 'xx',
427 );
428 $this->drupalPost($add_comment_url, $edit, t('Preview'));
429 $this->assertText(t('The answer you entered for the CAPTCHA was not correct.'),
430 'wrong CAPTCHA should block form submission.', 'CAPTCHA');
431
432 //TODO: more testing for untrusted posts.
433 }
434 }
435
436
437
438 // Some tricks to debug:
439 // drupal_debug($data) // from devel module
440 // file_put_contents('tmp.simpletest.html', $this->drupalGetContent());

  ViewVC Help
Powered by ViewVC 1.1.2