Project

General

Profile

Paste
Download (16.1 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / honeypot / honeypot.test @ 4019484b

1
<?php
2

    
3
/**
4
 * @file
5
 * Testing for Honeypot module.
6
 */
7

    
8
/**
9
 * Test the functionality of the Honeypot module for forms.
10
 */
11
class HoneypotFormTestCase extends DrupalWebTestCase {
12
  protected $adminUser;
13
  protected $webUser;
14
  protected $node;
15

    
16
  public static function getInfo() {
17
    return array(
18
      'name' => 'Honeypot form protections',
19
      'description' => 'Ensure that Honeypot protects site forms properly.',
20
      'group' => 'Form API',
21
    );
22
  }
23

    
24
  public function setUp() {
25
    // Enable modules required for this test.
26
    parent::setUp(array('honeypot', 'comment', 'honeypot_test'));
27

    
28
    // Set up required Honeypot variables.
29
    variable_set('honeypot_element_name', 'url');
30
    // Disable time_limit protection.
31
    variable_set('honeypot_time_limit', 0);
32
    // Test protecting all forms.
33
    variable_set('honeypot_protect_all_forms', TRUE);
34
    variable_set('honeypot_log', FALSE);
35

    
36
    // Set up other required variables.
37
    variable_set('user_email_verification', TRUE);
38
    variable_set('user_register', USER_REGISTER_VISITORS);
39

    
40
    // Set up admin user.
41
    $this->adminUser = $this->drupalCreateUser(array(
42
      'administer honeypot',
43
      'bypass honeypot protection',
44
      'administer content types',
45
      'administer users',
46
      'access comments',
47
      'post comments',
48
      'skip comment approval',
49
      'administer comments',
50
    ));
51

    
52
    // Set up web user.
53
    $this->webUser = $this->drupalCreateUser(array(
54
      'access comments',
55
      'post comments',
56
      'create article content',
57
    ));
58

    
59
    // Set up example node.
60
    $this->node = $this->drupalCreateNode(array(
61
      'type' => 'article',
62
      'promote' => 1,
63
      'uid' => $this->webUser->uid,
64
    ));
65
  }
66

    
67
  /**
68
   * Test user registration (anonymous users).
69
   */
70
  public function testProtectRegisterUserNormal() {
71
    // Set up form and submit it.
72
    $edit['name'] = $this->randomName();
73
    $edit['mail'] = $edit['name'] . '@example.com';
74
    $this->drupalPost('user/register', $edit, t('Create new account'));
75

    
76
    // Form should have been submitted successfully.
77
    $this->assertText(t('A welcome message with further instructions has been sent to your e-mail address.'), 'User registered successfully.');
78
  }
79

    
80
  public function testProtectUserRegisterHoneypotFilled() {
81
    // Set up form and submit it.
82
    $edit['name'] = $this->randomName();
83
    $edit['mail'] = $edit['name'] . '@example.com';
84
    $edit['url'] = 'http://www.example.com/';
85
    $this->drupalPost('user/register', $edit, t('Create new account'));
86

    
87
    // Form should have error message.
88
    $this->assertText(t('There was a problem with your form submission. Please refresh the page and try again.'), 'Registration form protected by honeypot.');
89
  }
90

    
91
  public function testProtectRegisterUserTooFast() {
92
    // Enable time limit for honeypot.
93
    variable_set('honeypot_time_limit', 5);
94

    
95
    // Set up form and submit it.
96
    $edit['name'] = $this->randomName();
97
    $edit['mail'] = $edit['name'] . '@example.com';
98
    $this->drupalPost('user/register', $edit, t('Create new account'));
99

    
100
    // Form should have error message.
101
    $this->assertText(t('There was a problem with your form submission. Please wait 6 seconds and try again.'), 'Registration form protected by time limit.');
102
  }
103

    
104
  /**
105
   * Test comment form protection.
106
   */
107
  public function testProtectCommentFormNormal() {
108
    $comment = 'Test comment.';
109

    
110
    // Disable time limit for honeypot.
111
    variable_set('honeypot_time_limit', 0);
112

    
113
    // Log in the web user.
114
    $this->drupalLogin($this->webUser);
115

    
116
    // Set up form and submit it.
117
    $edit['comment_body[' . LANGUAGE_NONE . '][0][value]'] = $comment;
118
    $this->drupalPost('comment/reply/' . $this->node->nid, $edit, t('Save'));
119
    $this->assertText(t('Your comment has been posted.'), 'Comment posted successfully.');
120
  }
121

    
122
  public function testProtectCommentFormHoneypotFilled() {
123
    $comment = 'Test comment.';
124

    
125
    // Log in the web user.
126
    $this->drupalLogin($this->webUser);
127

    
128
    // Set up form and submit it.
129
    $edit['comment_body[' . LANGUAGE_NONE . '][0][value]'] = $comment;
130
    $edit['url'] = 'http://www.example.com/';
131
    $this->drupalPost('comment/reply/' . $this->node->nid, $edit, t('Save'));
132
    $this->assertText(t('There was a problem with your form submission. Please refresh the page and try again.'), 'Comment posted successfully.');
133
  }
134

    
135
  public function testProtectCommentFormHoneypotBypass() {
136
    // Log in the admin user.
137
    $this->drupalLogin($this->adminUser);
138

    
139
    // Get the comment reply form and ensure there's no 'url' field.
140
    $this->drupalGet('comment/reply/' . $this->node->nid);
141
    $this->assertNoText('id="edit-url" name="url"', 'Honeypot home page field not shown.');
142
  }
143

    
144
  /**
145
   * Test node form protection.
146
   */
147
  public function testProtectNodeFormTooFast() {
148
    // Log in the admin user.
149
    $this->drupalLogin($this->webUser);
150

    
151
    // Reset the time limit to 5 seconds.
152
    variable_set('honeypot_time_limit', 5);
153

    
154
    // Set up the form and submit it.
155
    $edit["title"] = 'Test Page';
156
    $this->drupalPost('node/add/article', $edit, t('Save'));
157
    $this->assertText(t('There was a problem with your form submission.'), 'Honeypot node form timestamp protection works.');
158
  }
159

    
160
  /**
161
   * Test node form protection.
162
   */
163
  public function testProtectNodeFormPreviewPassthru() {
164
    // Log in the admin user.
165
    $this->drupalLogin($this->webUser);
166

    
167
    // Post a node form using the 'Preview' button and make sure it's allowed.
168
    $edit["title"] = 'Test Page';
169
    $this->drupalPost('node/add/article', $edit, t('Preview'));
170
    $this->assertNoText(t('There was a problem with your form submission.'), 'Honeypot not blocking node form previews.');
171
  }
172

    
173
  /**
174
   * Test programmatic submission.
175
   */
176
  public function testProgrammaticSubmission() {
177
    // Enable time limit protection.
178
    variable_set('honeypot_time_limit', 5);
179

    
180
    // Create a user for which we are going to trigger the password reset.
181
    $edit = array();
182
    $edit['name']   = 'robo-user';
183
    $edit['mail']   = $edit['name'] . '@example.com';
184
    $edit['status'] = 1;
185
    user_save(drupal_anonymous_user(), $edit);
186

    
187
    // Trigger the password reset through a programmatic submission.
188
    $this->drupalGet('honeypot_test/submit_form');
189

    
190
    // Verify that the submission did not return any validation errors.
191
    $form_errors = drupal_json_decode($this->content);
192
    $this->assertNoRaw('There was a problem with your form submission. Please wait 6 seconds and try again.');
193
    $this->assertFalse($form_errors, 'The were no validation errors when submitting the form.');
194
  }
195

    
196
  /**
197
   * Test that any (not-strict-empty) value triggers protection.
198
   */
199
  public function testStrictEmptinessOnHoneypotField() {
200
    // Initialise the form values.
201
    $edit['name'] = $this->randomName();
202
    $edit['mail'] = $edit['name'] . '@example.com';
203

    
204
    // Any value that is not strictly empty should trigger Honeypot.
205
    foreach (['0', ' '] as $value) {
206
      $edit['url'] = $value;
207
      $this->drupalPost('user/register', $edit, t('Create new account'));
208
      $this->assertText(t('There was a problem with your form submission. Please refresh the page and try again.'), "Honeypot protection is triggered when the honeypot field contains '{$value}'.");
209
    }
210
  }
211
}
212

    
213
/**
214
 * Test the functionality of the Honeypot module for an admin user.
215
 */
216
class HoneypotAdminFormTestCase extends DrupalWebTestCase {
217
  protected $adminUser;
218

    
219
  public static function getInfo() {
220
    return array(
221
      'name' => 'Honeypot admin form',
222
      'description' => 'Ensure the Honeypot admin form functions properly.',
223
      'group' => 'Form API',
224
    );
225
  }
226

    
227
  public function setUp() {
228
    // Enable modules required for this test.
229
    parent::setUp(array('honeypot'));
230

    
231
    // Set up admin user.
232
    $this->adminUser = $this->drupalCreateUser(array(
233
      'administer honeypot',
234
      'bypass honeypot protection',
235
    ));
236
  }
237

    
238
  /**
239
   * Test a valid element name.
240
   */
241
  public function testElementNameUpdateSuccess() {
242
    // Log in the web user.
243
    $this->drupalLogin($this->adminUser);
244

    
245
    // Set up form and submit it.
246
    $edit['honeypot_element_name'] = "test";
247
    $this->drupalPost('admin/config/content/honeypot', $edit, t('Save configuration'));
248

    
249
    // Form should have been submitted successfully.
250
    $this->assertText(t('The configuration options have been saved.'), 'Honeypot element name assertion works for valid names.');
251

    
252
    // Set up form and submit it.
253
    $edit['honeypot_element_name'] = "test-1";
254
    $this->drupalPost('admin/config/content/honeypot', $edit, t('Save configuration'));
255

    
256
    // Form should have been submitted successfully.
257
    $this->assertText(t('The configuration options have been saved.'), 'Honeypot element name assertion works for valid names with dashes and numbers.');
258
  }
259

    
260
  /**
261
   * Test an invalid element name (invalid first character).
262
   */
263
  public function testElementNameUpdateFirstCharacterFail() {
264
    // Log in the admin user.
265
    $this->drupalLogin($this->adminUser);
266

    
267
    // Set up form and submit it.
268
    $edit['honeypot_element_name'] = "1test";
269
    $this->drupalPost('admin/config/content/honeypot', $edit, t('Save configuration'));
270

    
271
    // Form submission should fail.
272
    $this->assertText(t('The element name must start with a letter.'), 'Honeypot element name assertion works for invalid names.');
273
  }
274

    
275
  /**
276
   * Test an invalid element name (invalid character in name).
277
   */
278
  public function testElementNameUpdateInvalidCharacterFail() {
279
    // Log in the admin user.
280
    $this->drupalLogin($this->adminUser);
281

    
282
    // Set up form and submit it.
283
    $edit['honeypot_element_name'] = "special-character-&";
284
    $this->drupalPost('admin/config/content/honeypot', $edit, t('Save configuration'));
285

    
286
    // Form submission should fail.
287
    $this->assertText(t('The element name cannot contain spaces or other special characters.'), 'Honeypot element name assertion works for invalid names with special characters.');
288

    
289
    // Set up form and submit it.
290
    $edit['honeypot_element_name'] = "space in name";
291
    $this->drupalPost('admin/config/content/honeypot', $edit, t('Save configuration'));
292

    
293
    // Form submission should fail.
294
    $this->assertText(t('The element name cannot contain spaces or other special characters.'), 'Honeypot element name assertion works for invalid names with spaces.');
295
  }
296
}
297

    
298
/**
299
 * Test Honeypot's CSS generation routines.
300
 */
301
class HoneypotCssTestCase extends DrupalWebTestCase {
302
  public static function getInfo() {
303
    return array(
304
      'name' => 'Honeypot CSS tests',
305
      'description' => 'Ensure that Honeypot rebuilds its CSS file correctly.',
306
      'group' => 'Form API',
307
    );
308
  }
309

    
310
  public function setUp() {
311
    // Enable modules required for this test.
312
    parent::setUp(array('honeypot'));
313

    
314
    // Set up required Honeypot variables.
315
    variable_set('honeypot_element_name', 'url');
316
  }
317

    
318
  /**
319
   * Test CSS file regeneration.
320
   */
321
  public function testHoneypotCssRegeneration() {
322
    $honeypot_css = honeypot_get_css_file_path();
323

    
324
    // Delete the Honeypot CSS file (if it exists).
325
    file_unmanaged_delete($honeypot_css);
326

    
327
    // Make sure the Honeypot CSS file doesn't exist.
328
    $this->assertFalse(file_exists($honeypot_css));
329

    
330
    // Create the CSS file.
331
    honeypot_create_css(variable_get('honeypot_element_name', 'url'));
332

    
333
    // Make sure the Honeypot CSS file exists.
334
    $this->assertTrue(file_exists($honeypot_css));
335
  }
336

    
337
  /**
338
   * Test cron-based CSS file regeneration.
339
   */
340
  public function testHoneypotCssRegenerationOnCron() {
341
    $honeypot_css = honeypot_get_css_file_path();
342

    
343
    // Delete the Honeypot CSS file (if it exists).
344
    file_unmanaged_delete($honeypot_css);
345

    
346
    // Make sure the Honeypot CSS file doesn't exist.
347
    $this->assertFalse(file_exists($honeypot_css));
348

    
349
    // Run cron.
350
    honeypot_cron();
351

    
352
    // Make sure the Honeypot CSS file exists.
353
    $this->assertTrue(file_exists($honeypot_css));
354
  }
355

    
356
  /**
357
   * Test cron-based CSS file update.
358
   */
359
  public function testHoneypotCssUpdateOnCron() {
360
    $honeypot_css = honeypot_get_css_file_path();
361
    $original_element_name = variable_get('honeypot_element_name', 'url');
362

    
363
    // Update the honeypot element name.
364
    variable_set('honeypot_element_name', 'test');
365

    
366
    // Make sure the Honeypot CSS file still exists.
367
    $this->assertTrue(file_exists($honeypot_css));
368

    
369
    // Run cron.
370
    honeypot_cron();
371

    
372
    // Make sure the Honeypot CSS file was updated with the new element name.
373
    $handle = fopen($honeypot_css, 'r');
374
    $contents = fread($handle, filesize($honeypot_css));
375
    fclose($handle);
376
    $updated_element_name_in_css = (strpos($contents, 'test') === 1);
377
    $this->assertTrue($updated_element_name_in_css);
378

    
379
    // For debug.
380
    $this->verbose($contents);
381

    
382
    // Revert the honeypot element name back to the original.
383
    variable_set('honeypot_element_name', $original_element_name);
384
  }
385

    
386
  /**
387
   * Test CSS works when default file scheme is not public://
388
   */
389
  public function testHoneypotCssNonpublicFileSystem() {
390
    variable_set('file_default_scheme', 'private');
391

    
392
    $honeypot_css = honeypot_get_css_file_path();
393

    
394
    // Delete the Honeypot CSS file (if it exists).
395
    file_unmanaged_delete($honeypot_css);
396

    
397
    // Make sure the Honeypot CSS file doesn't exist.
398
    $this->assertFalse(file_exists($honeypot_css));
399

    
400
    // Run cron.
401
    honeypot_cron();
402

    
403
    // Make sure the Honeypot CSS file exists.
404
    $this->assertTrue(file_exists($honeypot_css));
405
  }
406

    
407
  /**
408
   * Test CSS file availability.
409
   */
410
  public function testHoneypotCssAvailability() {
411
    // Public CSS file can be consumed.
412
    variable_set('file_default_scheme', 'public');
413
    if ($wrapper = file_stream_wrapper_get_instance_by_uri(honeypot_get_css_file_path())) {
414
      $url = $wrapper->getExternalUrl();
415
    }
416
    $this->drupalGet($url);
417
    $this->assertResponse(200);
418

    
419

    
420
    // Private CSS file can not be consumed.
421
    variable_set('file_default_scheme', 'private');
422
    honeypot_cron();
423
    if ($wrapper = file_stream_wrapper_get_instance_by_uri(honeypot_get_css_file_path())) {
424
      $url = $wrapper->getExternalUrl();
425
    }
426
    $this->drupalGet($url);
427
    $this->assertNoResponse(200);
428

    
429
    // Site default is private, but override honeypot's to public to consume.
430
    variable_set('honeypot_file_default_scheme', 'public');
431
    honeypot_cron();
432
    if ($wrapper = file_stream_wrapper_get_instance_by_uri(honeypot_get_css_file_path())) {
433
      $url = $wrapper->getExternalUrl();
434
    }
435
    $this->drupalGet($url);
436
    $this->assertResponse(200);
437
  }
438

    
439
}
440

    
441
/**
442
 * Test the functionality of the Honeypot module's integration with Trigger.
443
 */
444
class HoneypotTriggerTestCase extends DrupalWebTestCase {
445
  public static function getInfo() {
446
    return array(
447
      'name' => 'Honeypot Trigger integration',
448
      'description' => 'Ensure that Honeypot triggers events correctly.',
449
      'group' => 'Form API',
450
    );
451
  }
452

    
453
  public function setUp() {
454
    // Enable modules required for this test.
455
    parent::setUp(array('honeypot', 'trigger'));
456

    
457
    // Set up required Honeypot variables.
458
    variable_set('honeypot_element_name', 'url');
459
    // Disable time_limit protection.
460
    variable_set('honeypot_time_limit', 0);
461
    // Test protecting all forms.
462
    variable_set('honeypot_protect_all_forms', TRUE);
463
    variable_set('honeypot_log', FALSE);
464

    
465
    // Set up other required variables.
466
    variable_set('user_email_verification', TRUE);
467
    variable_set('user_register', USER_REGISTER_VISITORS);
468

    
469
    // Assign new action to Honeypot form rejection Trigger.
470
    db_insert('trigger_assignments')
471
      ->fields(array(
472
        'hook' => 'honeypot_reject',
473
        'aid' => 'system_block_ip_action',
474
        'weight' => 1,
475
      ))
476
      ->execute();
477
  }
478

    
479
  /**
480
   * Test trigger integration.
481
   */
482
  public function testHoneypotTriggerIntegration() {
483
    // Set up form and submit it.
484
    $edit['name'] = $this->randomName();
485
    $edit['mail'] = $edit['name'] . '@example.com';
486
    $edit['url'] = 'http://www.example.com/';
487
    $this->drupalPost('user/register', $edit, t('Create new account'));
488

    
489
    // Make sure Honeypot is working.
490
    $this->assertText(t('There was a problem with your form submission.'), 'Honeypot working correctly.');
491

    
492
    // Visit the home page and make sure the user is banned.
493
    $this->drupalGet('node');
494
    $this->assertText(t('has been banned'), 'User banned successfully.');
495
  }
496

    
497
}