Projet

Général

Profil

Paste
Télécharger (27,5 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / cas / cas.test @ a2baadd1

1
<?php
2

    
3
/**
4
 * @file
5
 * Tests for cas.module.
6
 */
7

    
8
class CasTestHelper extends DrupalWebTestCase {
9
  protected $admin_user;
10

    
11
  /**
12
   * Helper class for CAS tests.
13
   *
14
   * Creates an administrative user and downloads phpCAS.
15
   */
16
  function setUp() {
17
    // Install modules needed for this test. This could have been passed in as
18
    // either a single array argument or a variable number of string arguments.
19
    // @todo Remove this compatibility layer in Drupal 8, and only accept
20
    // $modules as a single array argument.
21
    $modules = func_get_args();
22
    if (isset($modules[0]) && is_array($modules[0])) {
23
      $modules = $modules[0];
24
    }
25

    
26
    // cas_test requires the CAS Server module.
27
    $modules = array_merge(array('cas', 'cas_test', 'cas_server'), $modules);
28
    parent::setUp($modules);
29

    
30
    // Tests will fail unless clean URLs are enabled, due to an incompatibility
31
    // in phpCAS.
32
    variable_set('clean_url', TRUE);
33

    
34
    // Create admin user.
35
    $this->admin_user = $this->drupalCreateUser(array('administer users', 'administer cas'));
36

    
37
    // Download and extract in PHPCAS.
38
    $this->downloadExtractPhpCas('1.3.1');
39
  }
40

    
41
  /**
42
   * Download and extract phpCAS.
43
   *
44
   * Sets the 'cas_library_dir' variable to the directory where phpCAS
45
   * is downloaded.
46
   *
47
   * @param $version
48
   *   The phpCAS version number to download and extract.
49
   */
50
  function downloadExtractPhpCas($version) {
51
    // Find the most URL of the most recent phpCAS version.
52
    $directory = 'CAS-' . $version;
53
    $filename = 'CAS-' . $version . '.tgz';
54
    $url = 'http://downloads.jasig.org/cas-clients/php/' . $version . '/' . $filename;
55

    
56
    // Avoid downloading the file dozens of times
57
    $simpletest_cache = $this->originalFileDirectory . '/simpletest/cas';
58
    if (!file_exists($simpletest_cache)) {
59
      mkdir($simpletest_cache);
60
    }
61

    
62
    // Local archive name.
63
    $local_archive = $simpletest_cache . '/' . $filename;
64
    $cas_library_dir = $simpletest_cache . '/' . $directory;
65

    
66
    // Begin single threaded code.
67
    if (function_exists('sem_get')) {
68
      $semaphore = sem_get(ftok(__FILE__, 1));
69
      sem_acquire($semaphore);
70
    }
71

    
72
    // Download and extact the archive, but only in one thread.
73
    if (!file_exists($local_archive)) {
74
      $local_archive = system_retrieve_file($url, $local_archive, FALSE, FILE_EXISTS_REPLACE);
75
    }
76
    if (!file_exists($cas_library_dir)) {
77
      // Extract the files.
78
      $archiver = archiver_get_archiver($local_archive);
79
      $archiver->extract($simpletest_cache);
80
    }
81
    if (function_exists('sem_get')) {
82
      sem_release($semaphore);
83
    }
84
    // End single threaded code.
85

    
86
    // Verify that files were successfully extracted.
87
    $this->assertTrue(file_exists($cas_library_dir . '/CAS.php'), t('CAS.php found in @cas_library_dir.', array('@cas_library_dir' => $cas_library_dir)));
88

    
89
    // Set the CAS library directory.
90
    variable_set('cas_library_dir', $cas_library_dir);
91
  }
92

    
93
  /**
94
   * Create a CAS user with the specified username.
95
   *
96
   * @param $cas_name
97
   *   The CAS username. If omitted, a CAS username will be automatically
98
   *   generated.
99
   * @param $permissions
100
   *   An array of permissions to assign to the created user.
101
   *
102
   * @return
103
   *   A user account object. The CAS username is present in the cas_name
104
   *   field.
105
   */
106
  function casCreateUser($cas_name = NULL, $permissions = array('access comments', 'access content', 'post comments', 'skip comment approval')) {
107
    // Create user.
108
    $account = $this->drupalCreateUser($permissions);
109
    $pass_raw = $account->pass_raw;
110

    
111
    // Add CAS username.
112
    if (empty($cas_name)) {
113
      $cas_name = $this->randomName();
114
    }
115
    $edit['cas_name'] = $cas_name;
116
    $account = user_save($account, $edit);
117

    
118
    // Restore password.
119
    $account->pass_raw = $pass_raw;
120
    return $account;
121
  }
122

    
123
  /**
124
   * Log in a CAS user with the internal browser.
125
   *
126
   * @param $account
127
   *   A user object with a valid CAS username field, or the CAS username as a
128
   *   string.
129
   * @param $attributes
130
   *   Additional attributes for the CAS user.
131
   */
132
  function casLogin($account, $attributes = array()) {
133
    if ($this->loggedInUser) {
134
      $this->drupalLogout();
135
    }
136

    
137
    // Log in the user.
138
    $cas_name = $this->setCasUser($account, $attributes);
139
    $this->drupalGet('cas');
140

    
141
    $pass = $this->assertLink(t('Log out'), 0, t('CAS user %cas_name successfully logged in.', array('%cas_name' => $cas_name)), t('User login'));
142
    if ($pass) {
143
      $this->loggedInUser = cas_user_load_by_name($cas_name, TRUE, TRUE);
144
    }
145
  }
146

    
147
  /**
148
   * Set the CAS username and attributes for the next CAS login request.
149
   *
150
   * @param $account
151
   *   A user object with a valid CAS username field, or the CAS username as a
152
   *   string.
153
   * @param $attributes
154
   *   Additional attributes for the CAS user.
155
   *
156
   * @return
157
   *   The CAS username.
158
   */
159
  function setCasUser($account, $attributes = array()) {
160
    $cas_name = is_object($account) ? $account->cas_name : $account;
161
    $cas_user = array('name' => $cas_name, 'attributes' => $attributes);
162
    variable_set('cas_test_cas_user', $cas_user);
163
    return $cas_name;
164
  }
165

    
166
  /**
167
   * Clear the CAS username and attributes for the next CAS login request.
168
   */
169
  function clearCasUser() {
170
    variable_del('cas_test_cas_user');
171
  }
172

    
173
  /**
174
   * Assert that the user has logged in.
175
   *
176
   * @return
177
   *  TRUE if the assertion succeeded, FALSE otherwise.
178
   */
179
  function assertLoggedIn($account) {
180
    $pass = $this->assertLink(t('Log out'), 0, t('CAS user %cas_name successfully logged in.', array('%cas_name' => $account->cas_name)), t('User login'));
181
    if ($pass) {
182
      $this->loggedInUser = $account;
183
    }
184
    return $pass;
185
  }
186

    
187
  /**
188
   * Assert that the user has been logged out.
189
   *
190
   * @return
191
   *  TRUE if the assertion succeeded, FALSE otherwise.
192
   */
193
  function assertLoggedOut() {
194
    $this->drupalGet('user');
195
    $pass = $this->assertField('name', t('Username field found.'), t('Logout'));
196
    $pass = $pass && $this->assertField('pass', t('Password field found.'), t('Logout'));
197
    if ($pass) {
198
      $this->loggedInUser = FALSE;
199
    }
200
    return $pass;
201
  }
202

    
203
  /**
204
   * Assert the value of the token.
205
   *
206
   * @param $token
207
   *   A token to evaluate for the current CAS user.
208
   * @param $value
209
   *   The expected value after the token is evaluated.
210
   * @param $message
211
   *   The message to display along with the assertion.
212
   *
213
   * @return
214
   *  TRUE if the assertion succeeded, FALSE otherwise.
215
   */
216
  function assertToken($token, $value, $message = '') {
217
    $options = array(
218
      'query' => array(
219
        'token' => $token,
220
        'name' => $this->loggedInUser->cas_name,
221
      ),
222
    );
223
    $path = 'cas_test/token';
224
    $out = $this->drupalGet($path, $options);
225
    return $this->assertEqual($out, $value, $message, 'Token');
226
  }
227

    
228
}
229

    
230
class CasUserAdminTestCase extends CasTestHelper {
231

    
232
  public static function getInfo() {
233
    return array(
234
      'name' => 'User administration',
235
      'description' => 'Test CAS user administration.',
236
      'group' => 'Central Authentication Service'
237
    );
238
  }
239

    
240
  /**
241
   * Registers, modifies, and deletes a CAS user using User API hooks.
242
   */
243
  function testCASUserHooks() {
244
    // Create a test account.
245
    $account = $this->drupalCreateUser();
246
    $uid = $account->uid;
247

    
248
    // Add a CAS username.
249
    $cas_name = $this->randomName();
250
    $edit = array('cas_name' => $cas_name);
251
    $account = user_save($account, $edit);
252
    $this->assertEqual($cas_name, $account->cas_name, t('CAS username %cas_name successfully created.', array('%cas_name' => $cas_name)));
253

    
254
    // Reload the account and ensure the CAS name is still present.
255
    $account = user_load($uid);
256
    $this->assertEqual($cas_name, $account->cas_name, t('CAS username %cas_name successfully saved.', array('%cas_name' => $cas_name)));
257

    
258
    // Load the account by the CAS username.
259
    $account = cas_user_load_by_name($cas_name);
260
    $this->assertEqual($uid, $account->uid, t('Loaded the correct account with CAS username %cas_name.', array('%cas_name' => $cas_name)));
261

    
262
    // Change the CAS username.
263
    $cas_new_name = $this->randomName();
264
    $account = user_load($uid);
265
    $edit = array('cas_name' => $cas_new_name);
266
    user_save($account, $edit);
267
    $account = user_load($uid);
268
    $this->assertEqual($cas_new_name, $account->cas_name, t('CAS username %cas_name successfully updated.', array('%cas_name' => $cas_new_name)));
269
    $this->assertEqual(count($account->cas_names), 1, t('Only one CAS username is present.'));
270
    $account = cas_user_load_by_name($cas_name);
271
    $this->assertFalse($account, t('Could not load account using old CAS username.'));
272

    
273
    // Remove the CAS username.
274
    $account = user_load($uid);
275
    $edit = array('cas_name' => NULL);
276
    user_save($account, $edit);
277
    $account = user_load($uid);
278
    $this->assertFalse($account->cas_name, t('CAS username successfully deleted.'));
279
    $this->assertEqual(count($account->cas_names), 0, t('No CAS usernames are present.'));
280

    
281
    // Attempt to load by a non-existant CAS username.
282
    $account = cas_user_load_by_name($cas_new_name);
283
    $this->assertFalse($account, t('Could not load account with non-existent CAS username.'));
284

    
285
    // Verify that all CAS usernames have been removed from {cas_user}.
286
    $cas_uid_count = db_select('cas_user')
287
      ->condition('cas_name', array($cas_name, $cas_new_name), 'IN')
288
      ->countQuery()
289
      ->execute()
290
      ->fetchField();
291
    $this->assertEqual($cas_uid_count, 0, t('CAS usernames successfully removed from {cas_user}.'));
292
  }
293
  /**
294
   * Tests adding a user with a CAS username in the administrative interface.
295
   */
296
  function testUserAdd() {
297
    $this->drupalLogin($this->admin_user);
298

    
299
    // Register a user with a CAS username.
300
    $cas_name = $this->randomName();
301
    $edit = array(
302
      'name' => $this->randomName(),
303
      'mail' => $this->randomName() . '@example.com',
304
      'cas_name' => $cas_name,
305
      'pass[pass1]' => $pass = $this->randomString(),
306
      'pass[pass2]' => $pass,
307
      'notify' => FALSE,
308
    );
309
    $this->drupalPost('admin/people/create', $edit, t('Create new account'));
310
    $this->assertText(t('Created a new user account for @name. No e-mail has been sent.', array('@name' => $edit['name'])), 'User created');
311

    
312
    $this->drupalGet('admin/people');
313
    $this->assertText($edit['name'], 'User found in list of users');
314
    $this->assertText($edit['cas_name'], 'CAS username found in list of users');
315

    
316
    // Verify that duplicate CAS usernames are not allowed.
317
    $edit = array(
318
      'name' => $this->randomName(),
319
      'mail' => $this->randomName() . '@example.com',
320
      'cas_name' => $cas_name,
321
      'pass[pass1]' => $pass = $this->randomString(),
322
      'pass[pass2]' => $pass,
323
      'notify' => FALSE,
324
    );
325
    $this->drupalPost('admin/people/create', $edit, t('Create new account'));
326
    $this->assertText(t('The CAS username is already in use on this site.'), 'CAS username already in use.');
327
  }
328

    
329
  /**
330
   * Tests adding a CAS user in the administrative interface.
331
   */
332
  function testCasUserAdd() {
333
    $this->drupalLogin($this->admin_user);
334

    
335
    // Add a CAS user.
336
    $edit = array(
337
      'cas_name' => $this->randomName(),
338
    );
339
    $this->drupalPost('admin/people/cas/create', $edit, t('Create new account'));
340
    $this->assertText(t('Created a new user account for @name. No e-mail has been sent.', array('@name' => $edit['cas_name'])), 'User created');
341

    
342
    // Verify the user shows up in the list of all users.
343
    $this->drupalGet('admin/people');
344
    $this->assertNoUniqueText($edit['cas_name'], 'User and CAS username found in list of users');
345

    
346
    // Attempt to add the user again and see that it fails.
347
    $this->drupalPost('admin/people/cas/create', $edit, t('Create new account'));
348
    $this->assertText(t('The CAS username is already in use on this site.'), 'CAS username already in use.');
349
  }
350
}
351

    
352
/**
353
 * Test case to test user editing behavior.
354
 */
355
class CasUserTestCase extends CasTestHelper {
356

    
357
  public static function getInfo() {
358
    return array(
359
      'name' => 'User behavior',
360
      'description' => 'Test CAS user behavior, including auto-registration and user editing.',
361
      'group' => 'Central Authentication Service',
362
    );
363
  }
364

    
365
  /**
366
   * Tests automatically registering a user on login.
367
   */
368
  function testCasAutoRegister() {
369
    $cas_name = $this->randomName();
370
    $this->setCasUser($cas_name);
371

    
372
    // Test that the user is not automatically registered.
373
    variable_set('cas_user_register', FALSE);
374
    $this->drupalGet('cas');
375
    $this->assertRaw(t('No account found for %cas_name.', array('%cas_name' => $cas_name)));
376

    
377
    // Test that the user is automatically registered.
378
    variable_set('cas_user_register', TRUE);
379
    $this->drupalGet('cas');
380
    $this->loggedInUser = cas_user_load_by_name($cas_name, TRUE);
381
    $this->assertRaw(t('Logged in via CAS as %cas_username.', array('%cas_username' => $cas_name)));
382
    $this->drupalLogout();
383

    
384
    // Create a new user.
385
    $user2 = $this->drupalCreateUser();
386
    $cas_name = $user2->name;
387
    $this->setCasUser($cas_name);
388

    
389
    // Test that CAS does not hijack an existing username.
390
    $this->drupalGet('cas');
391
    $this->assertRaw(t('A new account could not be created for %cas_name. The username is already in use on this site.', array('%cas_name' => $cas_name)));
392
  }
393

    
394
  function testUserEdit() {
395
    $cas_name = $this->randomName();
396
    $account = $this->casCreateUser($cas_name, array('change own username'));
397

    
398
    $this->casLogin($cas_name);
399

    
400
    // Standard user page.
401
    variable_set('cas_hide_email', FALSE);
402
    variable_set('cas_hide_password', FALSE);
403
    $this->drupalGet("user/$account->uid/edit");
404
    $this->assertField('mail', 'E-mail field is present.');
405
    $this->assertField('current_pass', 'Current password field is present.');
406
    $this->assertField('pass[pass1]', 'Existing password field 1 is present.');
407
    $this->assertField('pass[pass2]', 'Existing password field 2 is present.');
408
    $edit = array(
409
      'mail' => $mail = $this->randomName() . '@example.com',
410
      'current_pass' => $account->pass_raw,
411
    );
412
    $this->drupalPost("user/$account->uid/edit", $edit, t('Save'));
413
    $this->assertFieldByName('mail', $mail);
414

    
415
    // Hide the password, ensure edits can be made without providing
416
    // the current password.
417
    variable_set('cas_hide_password', TRUE);
418
    $this->drupalGet("user/$account->uid/edit");
419
    $this->assertNoField('current_pass', 'Current password field is not present.');
420
    $this->assertNoField('pass[pass1]', 'Existing password field 1 is not present.');
421
    $this->assertNoField('pass[pass2]', 'Existing password field 2 is not present.');
422
    $edit = array(
423
      'mail' => $mail = $this->randomName() . '@example.com',
424
    );
425
    $this->drupalPost("user/$account->uid/edit", $edit, t('Save'));
426
    $this->assertFieldByName('mail', $mail);
427

    
428
    // Hide the e-mail field as well, ensure that it is not visible.
429
    variable_set('cas_hide_email', TRUE);
430
    $this->drupalGet("user/$account->uid/edit");
431
    $this->assertNoField('mail', 'E-mail field is not present.');
432
  }
433

    
434
  function testNameToken() {
435
    $account = $this->casCreateUser();
436
    $this->casLogin($account);
437

    
438
    $this->assertToken('[cas:name]', $account->cas_name);
439
  }
440

    
441
  function testCaseInsensitiveLogin() {
442
    $account = $this->casCreateUser();
443
    $this->casLogin(strtoupper($account->cas_name));
444
    $this->assertLoggedIn($account);
445
  }
446

    
447
}
448

    
449
/**
450
 * Test case to test user logout behavior.
451
 */
452
class CasLogoutRedirectionTestCase extends CasTestHelper {
453

    
454
  public static function getInfo() {
455
    return array(
456
      'name' => 'Logout redirection',
457
      'description' => 'Test CAS user logout redirection.',
458
      'group' => 'Central Authentication Service',
459
    );
460
  }
461

    
462
  /**
463
   * Test redirection on user logout.
464
   */
465
  function testLogoutRedirection() {
466
    $account = $this->casCreateUser();
467

    
468
    $this->casLogin($account);
469
    $this->drupalGet('caslogout');
470
    $this->assertText('Logged out. No redirection provided.');
471
    $this->assertLoggedOut();
472

    
473
    // Verify the destination parameter may be passed on logout, i.e.,
474
    // caslogout?destination=node
475
    $destination = 'node';
476
    $this->casLogin($account);
477
    $this->drupalGet('caslogout', array('query' => array('destination' => $destination)));
478
    $this->assertText(t('Logged out. Continue to @url.', array('@url' => url($destination, array('absolute' => TRUE)))));
479
    $this->assertLoggedOut();
480

    
481
    // Verify that remote destination parameters are not allowed.
482
    $destination = 'http://example.com/?query=yes#fragment';
483
    $this->casLogin($account);
484
    $this->drupalGet('caslogout', array('query' => array('destination' => $destination)));
485
    $this->assertText(t('Logged out. No redirection provided.'));
486
    $this->assertLoggedOut();
487

    
488
    // Verify 'cas_logout_destination' works for a variety of destinations,
489
    // including remote destinations.
490
    $destinations = array('<front>', 'http://example.com/?query=yes#fragment', 'node/1');
491
    foreach ($destinations as $destination) {
492
      variable_set('cas_logout_destination', $destination);
493
      $this->casLogin($account);
494
      $this->drupalGet('caslogout');
495
      $this->assertText(t('Logged out. Continue to @url.', array('@url' => url($destination, array('absolute' => TRUE)))));
496
      $this->assertLoggedOut();
497
    }
498

    
499
    // Verify 'cas_logout_destination' can be overwritten by passing the
500
    // destination query string.
501
    variable_set('cas_logout_destination', 'http://example.com/');
502
    $destination = 'node/1';
503
    $this->casLogin($account);
504
    $this->drupalGet('caslogout', array('query' => array('destination' => $destination)));
505
    $this->assertText(t('Logged out. Continue to @url.', array('@url' => url($destination, array('absolute' => TRUE)))));
506
    $this->assertLoggedOut();
507
  }
508
}
509

    
510
/**
511
 * Test case to test user login behavior.
512
 */
513
class CasLoginRedirectionTestCase extends CasTestHelper {
514

    
515
  public static function getInfo() {
516
    return array(
517
      'name' => 'Login redirection',
518
      'description' => 'Test CAS user login redirection.',
519
      'group' => 'Central Authentication Service',
520
    );
521
  }
522

    
523
  /**
524
   * Verify login redirection for an existing user.
525
   */
526
  function testExistingUserLoginRedirection() {
527
    $node1 = $this->drupalCreateNode();
528
    $node2 = $this->drupalCreateNode();
529
    $node3 = $this->drupalCreateNode();
530

    
531
    // Create a CAS user.
532
    $account = $this->casCreateUser();
533
    $cas_name = $account->cas_name;
534
    $this->setCasUser($cas_name);
535

    
536
    // Test going to 'cas'
537
    $this->drupalGet('cas');
538
    $this->assertLoggedIn($account);
539
    $this->assertUrl('');
540
    $this->drupalLogout();
541

    
542
    // Test going to 'cas?destination=node/$node1->nid'
543
    $destination = "node/$node1->nid";
544
    $this->drupalGet('cas', array('query' => array('destination' => $destination)));
545
    $this->assertLoggedIn($account);
546
    $this->assertUrl($destination);
547
    $this->drupalLogout();
548

    
549
    // Use the login block on $node2.
550
    $destination = "node/$node2->nid";
551
    variable_set('cas_login_form', CAS_ADD_LINK);
552
    $edit = array('cas_identifier' => TRUE);
553
    $this->drupalPost($destination, $edit, t('Log in'));
554
    $this->assertLoggedIn($account);
555
    $this->assertUrl($destination);
556
    $this->drupalLogout();
557

    
558
    // Use the regular login page, without a destination.
559
    $edit = array('cas_identifier' => TRUE);
560
    $this->drupalPost('user/login', $edit, t('Log in'));
561
    $this->assertLoggedIn($account);
562
    $this->assertUrl('user');
563
    $this->drupalLogout();
564

    
565
    // Use the regular login page, with a destination.
566
    $destination = "node/$node3->nid";
567
    $edit = array('cas_identifier' => TRUE);
568
    $this->drupalPost('user/login', $edit, t('Log in'), array('query' => array('destination' => $destination)));
569
    $this->assertLoggedIn($account);
570
    $this->assertUrl($destination);
571
    $this->drupalLogout();
572

    
573
    // External destinations are not allowed.
574
    $destination = '';
575
    $this->drupalGet('cas', array('query' => array('destination' => 'http://example.com/node/3')));
576
    $this->assertLoggedIn($account);
577
    $this->assertUrl($destination);
578
    $this->drupalLogout();
579
  }
580

    
581
  /**
582
   * Verify login redirection for a new user.
583
   */
584
  function testNewUserLoginRedirection() {
585
    // Initial login without a destination goes to front page.
586
    $cas_name = $this->randomName();
587
    $this->casLogin($cas_name);
588
    $this->assertUrl('');
589
    $this->drupalLogout();
590

    
591
    // Initial login with redirection goes to specified destination.
592
    $node = $this->drupalCreateNode();
593
    variable_set('cas_first_login_destination', "node/$node->nid");
594
    $cas_name = $this->randomName();
595
    $account = $this->casLogin($cas_name);
596
    $this->assertUrl("node/$node->nid", array('query' => array('destination' => '')));
597
    $this->drupalLogout();
598

    
599
    // The second login should not be redirected.
600
    $this->casLogin($cas_name);
601
    $this->assertUrl('');
602
    $this->drupalLogout();
603

    
604
    // Initial login with a admin-created account goes to the specified
605
    // destination.
606
    $account = $this->casCreateUser();
607
    $this->casLogin($account);
608
    $this->assertUrl("node/$node->nid", array('query' => array('destination' => '')));
609
    $this->drupalLogout();
610

    
611
    // The second login should not be redirected.
612
    $this->casLogin($account);
613
    $this->assertUrl('');
614
    $this->drupalLogout();
615
  }
616
}
617

    
618
/**
619
 * Test CAS Single Sign-Out.
620
 */
621
class CasSingleSignOutTestCase extends CasTestHelper {
622

    
623
  public static function getInfo() {
624
    return array(
625
      'name' => 'Single Sign-Out',
626
      'description' => 'Test CAS Single Sign-Out.',
627
      'group' => 'Central Authentication Service',
628
    );
629
  }
630

    
631
  function testSingleSignOut() {
632
    // Create a user, and log in.
633
    $cas_name = $this->randomName();
634
    $account = $this->casCreateUser($cas_name);
635
    $this->casLogin($account);
636

    
637
    cas_test_single_sign_out($cas_name);
638
    $this->assertLoggedOut();
639

    
640
    // @todo: Add additional tests for other methods of logging in (especially
641
    //   methods coming from cas_pages).
642
  }
643

    
644
  function testSingleSignOutDoubleEncode() {
645
    // Create a user, and log in.
646
    $cas_name = $this->randomName();
647
    $account = $this->casCreateUser($cas_name);
648
    $this->casLogin($account);
649

    
650
    cas_test_single_sign_out($cas_name, TRUE);
651
    $this->assertLoggedOut();
652

    
653
    // @todo: Add additional tests for other methods of logging in (especially
654
    //   methods coming from cas_pages).
655
  }
656
}
657

    
658
/**
659
 * Test case for CAS gateway feature.
660
 */
661
class CasGatewayTestCase extends CasTestHelper {
662

    
663
  public static function getInfo() {
664
    return array(
665
      'name' => 'CAS Gateway',
666
      'description' => 'Test CAS Gateway ("Check to see if user is already logged in") feature.',
667
      'group' => 'Central Authentication Service',
668
    );
669
  }
670

    
671
  function setUp() {
672
    parent::setUp();
673
    variable_set('cas_check_first', TRUE);
674
  }
675

    
676
  /**
677
   * Test the CAS Gateway functionality of the user is not logged in.
678
   */
679
  function testCasGatewayLoggedOut() {
680
    $this->drupalGet('');
681
    $this->assertTrue($this->redirect_count > 1, 'Polled CAS server on first request.');
682
    $this->drupalGet('');
683
    $this->assertEqual($this->redirect_count, 0, 'Did not poll CAS server on second request.');
684
    $this->drupalGet('node');
685
    $this->assertEqual($this->redirect_count, 0, 'Did not poll CAS server on third request.');
686
  }
687

    
688
  /**
689
   * Test the CAS Gateway functionality of the user is logged in.
690
   */
691
  function testCasGatewayLoggedIn() {
692
    // Create a user.
693
    $cas_name = $this->randomName();
694
    $account = $this->casCreateUser($cas_name);
695
    $this->setCasUser($cas_name);
696

    
697
    $this->drupalGet('node');
698
    $this->assertLoggedIn($account);
699
  }
700
}
701

    
702
/**
703
 * Test case for CAS force login feature.
704
 */
705
class CasRequiredLoginTestCase extends CasTestHelper {
706

    
707
  public static function getInfo() {
708
    return array(
709
      'name' => 'Required Login',
710
      'description' => 'Test CAS required login redirection.',
711
      'group' => 'Central Authentication Service',
712
    );
713
  }
714

    
715
  /**
716
   * Test redirection forced by cas_access and cas_pages variables.
717
   */
718
  function testCasPages() {
719
    $node1 = $this->drupalCreateNode();
720
    $node2 = $this->drupalCreateNode();
721
    $account = $this->casCreateUser();
722
    $this->setCasUser($account);
723

    
724
    $this->drupalGet("node/$node2->nid");
725

    
726
    // Enable required login for $node.
727
    variable_set('cas_access', 0);
728
    variable_set('cas_pages', "node/$node1->nid\nnode/$node2->nid");
729

    
730
    // Visit the node and verify we are logged in.
731
    $this->drupalGet("node/$node2->nid");
732
    $this->assertLoggedIn($account);
733
    $this->assertUrl("node/$node2->nid");
734
    $this->drupalLogout();
735

    
736
    // Invert the access restrictions. Verify we can get the access the node
737
    // without restriction.
738
    variable_set('cas_access', 1);
739
    $this->drupalGet("node/$node1->nid");
740
    $this->assertField('name', t('Username field found.'), t('Logout'));
741
    $this->assertField('pass', t('Password field found.'), t('Logout'));
742

    
743
    // Verify that accessing any other page redirects to the login page.
744
    $this->clearCasUser();
745
    $this->drupalGet('node');
746
    $this->assertText('No CAS name provided.');
747
  }
748

    
749
  /**
750
   * Test redirection prevented by cas_exclude.
751
   */
752
  function testCasExclude() {
753
    $node = $this->drupalCreateNode();
754
    $account = $this->casCreateUser();
755
    $this->setCasUser($account);
756

    
757
    variable_set('cas_check_first', TRUE);
758
    variable_set('cas_exclude', "node/$node->nid");
759

    
760
    // Visit an excluded page and ensure we did not try to log in.
761
    $this->drupalGet("node/$node->nid");
762
    $this->assertField('name', t('Username field found.'), t('Logout'));
763
    $this->assertField('pass', t('Password field found.'), t('Logout'));
764

    
765
    // Visit another page and ensure we logged in.
766
    $this->drupalGet('node');
767
    $this->assertLoggedIn($account);
768
    $this->assertUrl('node');
769
  }
770
}
771

    
772
/**
773
 * Tests the visibility and functionality of the CAS login block.
774
 */
775
class CasLoginBlockTestCase extends CasTestHelper {
776
  public static function getInfo() {
777
    return array(
778
      'name' => 'CAS login block',
779
      'description' => 'Tests the CAS login block.',
780
      'group' => 'Central Authentication Service',
781
    );
782
  }
783

    
784
  function setUp() {
785
    parent::setUp();
786

    
787
    // Enable the CAS login block.
788
    $admin_user = $this->drupalCreateUser(array('administer blocks'));
789
    $this->drupalLogin($admin_user);
790
    $edit = array(
791
      'blocks[user_login][region]' => '-1',
792
      'blocks[cas_login][region]' => 'sidebar_first',
793
    );
794
    $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
795
    $this->drupalLogout();
796
  }
797

    
798
  /**
799
   * Asserts that the CAS login block is shown or not shown.
800
   *
801
   * @param $visible
802
   *   Whether or not the CAS login block is expected to be shown.
803
   *
804
   * @return
805
   *  TRUE if the assertion succeeded, FALSE otherwise.
806
   */
807
  function assertCasLoginBlock($visible) {
808
    $xpath = '//div[@id=block-cas-0]/*';
809
    $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-cas-login'));
810
    if ($visible) {
811
      return $this->assertFieldByXPath($xpath, NULL, t('CAS login block found.'));
812
    }
813
    else {
814
      return $this->assertNoFieldByXPath($xpath, NULL, t('CAS login block not found.'));
815
    }
816
  }
817

    
818
  /**
819
   * Tests the visibility and functionality of the CAS login block.
820
   */
821
  function testCasLoginBlock() {
822
    $account = $this->casCreateUser();
823
    $this->setCasUser($account);
824

    
825
    // Verify that the block is shown on some pages, but not on others.
826
    $this->drupalGet('');
827
    $this->assertCasLoginBlock(TRUE);
828

    
829
    $this->drupalGet('user');
830
    $this->assertCasLoginBlock(FALSE);
831

    
832
    $this->drupalGet('user/1');
833
    $this->assertCasLoginBlock(TRUE);
834

    
835
    // Log in using the login block, and verify redirection works.
836
    $edit = array();
837
    $submit = t(variable_get('cas_login_invite', CAS_LOGIN_INVITE_DEFAULT));
838

    
839
    $this->drupalPost('', $edit, $submit);
840
    $this->assertLoggedIn($account);
841
    $this->assertUrl('node');
842

    
843
    // Block should not be shown to logged in users.
844
    $this->assertCasLoginBlock(FALSE);
845
  }
846
}