commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / cas / cas.test
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.3');
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-existent 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 3 CAS users.
336 $edit = array();
337 for ($i = 0; $i < 3; $i++) {
338 $cas_names[] = $this->randomName();
339 }
340 $edit['cas_name'] = implode("\n", $cas_names);
341 $this->drupalPost('admin/people/cas/create', $edit, t('Create new account(s)'));
342 $this->assertText(t('The following 3 CAS usernames were created: @cas_names', array('@cas_names' => implode(', ', $cas_names))), 'Users created');
343
344 // Verify the users show up in the list of all users.
345 $this->drupalGet('admin/people');
346 foreach ($cas_names as $cas_name) {
347 $this->assertNoUniqueText($cas_name, 'User and CAS username found in list of users');
348 }
349
350 // Attempt to add one of the users again and see that it fails.
351 $edit['cas_name'] = $cas_names[0];
352 $this->drupalPost('admin/people/cas/create', $edit, t('Create new account(s)'));
353 $this->assertText(t('The CAS username is already in use on this site.'), 'CAS username already in use.');
354 }
355 }
356
357 /**
358 * Test case to test user editing behavior.
359 */
360 class CasUserTestCase extends CasTestHelper {
361
362 public static function getInfo() {
363 return array(
364 'name' => 'User behavior',
365 'description' => 'Test CAS user behavior, including auto-registration and user editing.',
366 'group' => 'Central Authentication Service',
367 );
368 }
369
370 /**
371 * Tests automatically registering a user on login.
372 */
373 function testCasAutoRegister() {
374 $cas_name = $this->randomName();
375 $this->setCasUser($cas_name);
376
377 // Test that the user is not automatically registered.
378 variable_set('cas_user_register', FALSE);
379 $this->drupalGet('cas');
380 $this->assertRaw(t('No account found for %cas_name.', array('%cas_name' => $cas_name)));
381
382 // Ensure that the login result is not cached.
383 $cas_name = $this->randomName();
384 $this->setCasUser($cas_name);
385 $this->drupalGet('cas');
386 $this->assertRaw(t('No account found for %cas_name.', array('%cas_name' => $cas_name)));
387
388 // Test that the user is automatically registered.
389 variable_set('cas_user_register', TRUE);
390 $this->drupalGet('cas');
391 $this->loggedInUser = cas_user_load_by_name($cas_name, TRUE);
392 $this->assertRaw(t('Logged in via CAS as %cas_username.', array('%cas_username' => $cas_name)));
393 $this->drupalLogout();
394
395 // Create a new user.
396 $user2 = $this->drupalCreateUser();
397 $cas_name = $user2->name;
398 $this->setCasUser($cas_name);
399
400 // Test that CAS does not hijack an existing username.
401 $this->drupalGet('cas');
402 $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)));
403 }
404
405 function testUserEdit() {
406 $cas_name = $this->randomName();
407 $account = $this->casCreateUser($cas_name, array('change own username'));
408
409 $this->casLogin($cas_name);
410
411 // Standard user page.
412 variable_set('cas_hide_email', FALSE);
413 variable_set('cas_hide_password', FALSE);
414 $this->drupalGet("user/$account->uid/edit");
415 $this->assertField('mail', 'E-mail field is present.');
416 $this->assertField('current_pass', 'Current password field is present.');
417 $this->assertField('pass[pass1]', 'Existing password field 1 is present.');
418 $this->assertField('pass[pass2]', 'Existing password field 2 is present.');
419 $edit = array(
420 'mail' => $mail = $this->randomName() . '@example.com',
421 'current_pass' => $account->pass_raw,
422 );
423 $this->drupalPost("user/$account->uid/edit", $edit, t('Save'));
424 $this->assertFieldByName('mail', $mail);
425
426 // Hide the password, ensure edits can be made without providing
427 // the current password.
428 variable_set('cas_hide_password', TRUE);
429 $this->drupalGet("user/$account->uid/edit");
430 $this->assertNoField('current_pass', 'Current password field is not present.');
431 $this->assertNoField('pass[pass1]', 'Existing password field 1 is not present.');
432 $this->assertNoField('pass[pass2]', 'Existing password field 2 is not present.');
433 $edit = array(
434 'mail' => $mail = $this->randomName() . '@example.com',
435 );
436 $this->drupalPost("user/$account->uid/edit", $edit, t('Save'));
437 $this->assertFieldByName('mail', $mail);
438
439 // Hide the e-mail field as well, ensure that it is not visible.
440 variable_set('cas_hide_email', TRUE);
441 $this->drupalGet("user/$account->uid/edit");
442 $this->assertNoField('mail', 'E-mail field is not present.');
443 }
444
445 function testNameToken() {
446 $account = $this->casCreateUser();
447 $this->casLogin($account);
448
449 $this->assertToken('[cas:name]', $account->cas_name);
450 }
451
452 function testCaseInsensitiveLogin() {
453 $account = $this->casCreateUser();
454 $this->casLogin(strtoupper($account->cas_name));
455 $this->assertLoggedIn($account);
456 }
457
458 }
459
460 /**
461 * Test case to test user logout behavior.
462 */
463 class CasLogoutRedirectionTestCase extends CasTestHelper {
464
465 public static function getInfo() {
466 return array(
467 'name' => 'Logout redirection',
468 'description' => 'Test CAS user logout redirection.',
469 'group' => 'Central Authentication Service',
470 );
471 }
472
473 /**
474 * Test redirection on user logout.
475 */
476 function testLogoutRedirection() {
477 $account = $this->casCreateUser();
478
479 $this->casLogin($account);
480 $this->drupalGet('caslogout');
481 $this->assertText('Logged out. No redirection provided.');
482 $this->assertLoggedOut();
483
484 // Verify the destination parameter may be passed on logout, i.e.,
485 // caslogout?destination=node
486 $destination = 'node';
487 $this->casLogin($account);
488 $this->drupalGet('caslogout', array('query' => array('destination' => $destination)));
489 $this->assertText(t('Logged out. Continue to @url.', array('@url' => url($destination, array('absolute' => TRUE)))));
490 $this->assertLoggedOut();
491
492 // Verify that remote destination parameters are not allowed.
493 $destination = 'http://example.com/?query=yes#fragment';
494 $this->casLogin($account);
495 $this->drupalGet('caslogout', array('query' => array('destination' => $destination)));
496 $this->assertText(t('Logged out. No redirection provided.'));
497 $this->assertLoggedOut();
498
499 // Verify 'cas_logout_destination' works for a variety of destinations,
500 // including remote destinations.
501 $destinations = array('<front>', 'http://example.com/?query=yes#fragment', 'node/1');
502 foreach ($destinations as $destination) {
503 variable_set('cas_logout_destination', $destination);
504 $this->casLogin($account);
505 $this->drupalGet('caslogout');
506 $this->assertText(t('Logged out. Continue to @url.', array('@url' => url($destination, array('absolute' => TRUE)))));
507 $this->assertLoggedOut();
508 }
509
510 // Verify 'cas_logout_destination' can be overwritten by passing the
511 // destination query string.
512 variable_set('cas_logout_destination', 'http://example.com/');
513 $destination = 'node/1';
514 $this->casLogin($account);
515 $this->drupalGet('caslogout', array('query' => array('destination' => $destination)));
516 $this->assertText(t('Logged out. Continue to @url.', array('@url' => url($destination, array('absolute' => TRUE)))));
517 $this->assertLoggedOut();
518 }
519 }
520
521 /**
522 * Test case to test user login behavior.
523 */
524 class CasLoginRedirectionTestCase extends CasTestHelper {
525
526 public static function getInfo() {
527 return array(
528 'name' => 'Login redirection',
529 'description' => 'Test CAS user login redirection.',
530 'group' => 'Central Authentication Service',
531 );
532 }
533
534 /**
535 * Verify login redirection for an existing user.
536 */
537 function testExistingUserLoginRedirection() {
538 $node1 = $this->drupalCreateNode();
539 $node2 = $this->drupalCreateNode();
540 $node3 = $this->drupalCreateNode();
541
542 // Create a CAS user.
543 $account = $this->casCreateUser();
544 $cas_name = $account->cas_name;
545 $this->setCasUser($cas_name);
546
547 // Test going to 'cas'
548 $this->drupalGet('cas');
549 $this->assertLoggedIn($account);
550 $this->assertUrl('');
551 $this->drupalLogout();
552
553 // Test going to 'cas?destination=node/$node1->nid'
554 $destination = "node/$node1->nid";
555 $this->drupalGet('cas', array('query' => array('destination' => $destination)));
556 $this->assertLoggedIn($account);
557 $this->assertUrl($destination);
558 $this->drupalLogout();
559
560 // Use the login block on $node2.
561 $destination = "node/$node2->nid";
562 variable_set('cas_login_form', CAS_ADD_LINK);
563 $edit = array('cas_identifier' => TRUE);
564 $this->drupalPost($destination, $edit, t('Log in'));
565 $this->assertLoggedIn($account);
566 $this->assertUrl($destination);
567 $this->drupalLogout();
568
569 // Use the regular login page, without a destination.
570 $edit = array('cas_identifier' => TRUE);
571 $this->drupalPost('user/login', $edit, t('Log in'));
572 $this->assertLoggedIn($account);
573 $this->assertUrl('user');
574 $this->drupalLogout();
575
576 // Use the regular login page, with a destination.
577 $destination = "node/$node3->nid";
578 $edit = array('cas_identifier' => TRUE);
579 $this->drupalPost('user/login', $edit, t('Log in'), array('query' => array('destination' => $destination)));
580 $this->assertLoggedIn($account);
581 $this->assertUrl($destination);
582 $this->drupalLogout();
583
584 // External destinations are not allowed.
585 $destination = '';
586 $this->drupalGet('cas', array('query' => array('destination' => 'http://example.com/node/3')));
587 $this->assertLoggedIn($account);
588 $this->assertUrl($destination);
589 $this->drupalLogout();
590 }
591
592 /**
593 * Verify login redirection for a new user.
594 */
595 function testNewUserLoginRedirection() {
596 // Initial login without a destination goes to front page.
597 $cas_name = $this->randomName();
598 $this->casLogin($cas_name);
599 $this->assertUrl('');
600 $this->drupalLogout();
601
602 // Initial login with redirection goes to specified destination.
603 $node = $this->drupalCreateNode();
604 variable_set('cas_first_login_destination', "node/$node->nid");
605 $cas_name = $this->randomName();
606 $account = $this->casLogin($cas_name);
607 $this->assertUrl("node/$node->nid");
608 $this->drupalLogout();
609
610 // The second login should not be redirected.
611 $this->casLogin($cas_name);
612 $this->assertUrl('');
613 $this->drupalLogout();
614
615 // Initial login with a admin-created account goes to the specified
616 // destination.
617 $account = $this->casCreateUser();
618 $this->casLogin($account);
619 $this->assertUrl("node/$node->nid");
620 $this->drupalLogout();
621
622 // The second login should not be redirected.
623 $this->casLogin($account);
624 $this->assertUrl('');
625 $this->drupalLogout();
626 }
627 }
628
629 /**
630 * Test CAS Single Sign-Out.
631 */
632 class CasSingleSignOutTestCase extends CasTestHelper {
633
634 public static function getInfo() {
635 return array(
636 'name' => 'Single Sign-Out',
637 'description' => 'Test CAS Single Sign-Out.',
638 'group' => 'Central Authentication Service',
639 );
640 }
641
642 function testSingleSignOut() {
643 // Create a user, and log in.
644 $cas_name = $this->randomName();
645 $account = $this->casCreateUser($cas_name);
646 $this->casLogin($account);
647
648 cas_test_single_sign_out($cas_name);
649 $this->assertLoggedOut();
650
651 // @todo: Add additional tests for other methods of logging in (especially
652 // methods coming from cas_pages).
653 }
654
655 function testSingleSignOutDoubleEncode() {
656 // Create a user, and log in.
657 $cas_name = $this->randomName();
658 $account = $this->casCreateUser($cas_name);
659 $this->casLogin($account);
660
661 cas_test_single_sign_out($cas_name, TRUE);
662 $this->assertLoggedOut();
663
664 // @todo: Add additional tests for other methods of logging in (especially
665 // methods coming from cas_pages).
666 }
667 }
668
669 /**
670 * Test case for CAS gateway feature.
671 */
672 class CasGatewayTestCase extends CasTestHelper {
673
674 public static function getInfo() {
675 return array(
676 'name' => 'CAS Gateway',
677 'description' => 'Test CAS Gateway ("Check to see if user is already logged in") feature.',
678 'group' => 'Central Authentication Service',
679 );
680 }
681
682 function setUp() {
683 parent::setUp();
684 }
685
686 /**
687 * Test the CAS Gateway functionality of the user is not logged in.
688 */
689 function testCasGatewayLoggedOut() {
690 $node1 = $this->drupalCreateNode();
691
692 variable_set('cas_check_frequency', CAS_CHECK_ONCE);
693 $this->drupalGet('');
694 $this->assertTrue($this->redirect_count == 2, 'Polled CAS server on first request.');
695 $this->drupalGet('');
696 $this->assertEqual($this->redirect_count, 0, 'Did not poll CAS server on second request.');
697 $this->drupalGet('node/' . $node1->nid);
698 $this->assertEqual($this->redirect_count, 0, 'Did not poll CAS server on third request.');
699 $this->assertFalse($this->loggedInUser);
700
701 variable_set('cas_check_frequency', CAS_CHECK_ALWAYS);
702 $this->drupalGet('');
703 $this->assertTrue($this->redirect_count == 2, 'Polled CAS server on first request');
704 $this->drupalGet('');
705 $this->assertTrue($this->redirect_count == 2, 'Polled CAS server on second request');
706 $this->drupalGet('node/' . $node1->nid);
707 $this->assertEqual($this->redirect_count == 2, 'Polled CAS server on third request');
708 $this->assertFalse($this->loggedInUser);
709 }
710
711 /**
712 * Test the CAS Gateway functionality of the user is logged in.
713 */
714 function testCasGatewayLoggedIn() {
715 // Create a user.
716 $cas_name = $this->randomName();
717 $account = $this->casCreateUser($cas_name);
718 $this->setCasUser($cas_name);
719
720 variable_set('cas_check_frequency', CAS_CHECK_ONCE);
721 $this->drupalGet('');
722 $this->assertLoggedIn($account);
723 // Logging out should immediately log a user back in
724 $this->drupalGet('user/logout');
725 $this->assertLoggedIn($account);
726
727 variable_set('cas_check_frequency', CAS_CHECK_ALWAYS);
728 $this->drupalGet('');
729 $this->assertLoggedIn($account);
730 // Logging out should immediately log a user back in
731 $this->drupalGet('user/logout');
732 $this->assertLoggedIn($account);
733 }
734 }
735
736 /**
737 * Test case for CAS force login feature.
738 */
739 class CasRequiredLoginTestCase extends CasTestHelper {
740
741 public static function getInfo() {
742 return array(
743 'name' => 'Required Login',
744 'description' => 'Test CAS required login redirection.',
745 'group' => 'Central Authentication Service',
746 );
747 }
748
749 /**
750 * Test redirection forced by cas_access and cas_pages variables.
751 */
752 function testCasPages() {
753 $node1 = $this->drupalCreateNode();
754 $node2 = $this->drupalCreateNode();
755 $account = $this->casCreateUser();
756 $this->setCasUser($account);
757
758 $this->drupalGet("node/$node2->nid");
759
760 // Enable required login for $node.
761 variable_set('cas_access', 0);
762 variable_set('cas_pages', "node/$node1->nid\nnode/$node2->nid");
763
764 // Visit the node and verify we are logged in.
765 $this->drupalGet("node/$node2->nid");
766 $this->assertLoggedIn($account);
767 $this->assertUrl("node/$node2->nid");
768 $this->drupalLogout();
769
770 // Invert the access restrictions. Verify we can get the access the node
771 // without restriction.
772 variable_set('cas_access', 1);
773 $this->drupalGet("node/$node1->nid");
774 $this->assertField('name', t('Username field found.'), t('Logout'));
775 $this->assertField('pass', t('Password field found.'), t('Logout'));
776
777 // Verify that accessing any other page redirects to the login page.
778 $this->clearCasUser();
779 $this->drupalGet('node');
780 $this->assertText('No CAS name provided.');
781 }
782
783 /**
784 * Test redirection prevented by cas_exclude.
785 */
786 function testCasExclude() {
787 $node = $this->drupalCreateNode();
788 $account = $this->casCreateUser();
789 $this->setCasUser($account);
790
791 variable_set('cas_check_frequency', CAS_CHECK_ONCE);
792 variable_set('cas_exclude', "node/$node->nid");
793
794 // Visit an excluded page and ensure we did not try to log in.
795 $this->drupalGet("node/$node->nid");
796 $this->assertField('name', t('Username field found.'), t('Logout'));
797 $this->assertField('pass', t('Password field found.'), t('Logout'));
798
799 // Visit another page and ensure we logged in.
800 $this->drupalGet('node');
801 $this->assertLoggedIn($account);
802 $this->assertUrl('node');
803 }
804 }
805
806 /**
807 * Tests the visibility and functionality of the CAS login block.
808 */
809 class CasLoginBlockTestCase extends CasTestHelper {
810 public static function getInfo() {
811 return array(
812 'name' => 'CAS login block',
813 'description' => 'Tests the CAS login block.',
814 'group' => 'Central Authentication Service',
815 );
816 }
817
818 function setUp() {
819 parent::setUp();
820
821 // Enable the CAS login block.
822 $admin_user = $this->drupalCreateUser(array('administer blocks'));
823 $this->drupalLogin($admin_user);
824 $edit = array(
825 'blocks[user_login][region]' => '-1',
826 'blocks[cas_login][region]' => 'sidebar_first',
827 );
828 $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
829 $this->drupalLogout();
830 }
831
832 /**
833 * Asserts that the CAS login block is shown or not shown.
834 *
835 * @param $visible
836 * Whether or not the CAS login block is expected to be shown.
837 *
838 * @return
839 * TRUE if the assertion succeeded, FALSE otherwise.
840 */
841 function assertCasLoginBlock($visible) {
842 $xpath = '//div[@id=block-cas-0]/*';
843 $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-cas-login'));
844 if ($visible) {
845 return $this->assertFieldByXPath($xpath, NULL, t('CAS login block found.'));
846 }
847 else {
848 return $this->assertNoFieldByXPath($xpath, NULL, t('CAS login block not found.'));
849 }
850 }
851
852 /**
853 * Tests the visibility and functionality of the CAS login block.
854 */
855 function testCasLoginBlock() {
856 $account = $this->casCreateUser();
857 $this->setCasUser($account);
858
859 // Verify that the block is shown on some pages, but not on others.
860 $this->drupalGet('');
861 $this->assertCasLoginBlock(TRUE);
862
863 $this->drupalGet('user');
864 $this->assertCasLoginBlock(FALSE);
865
866 $this->drupalGet('user/1');
867 $this->assertCasLoginBlock(TRUE);
868
869 // Log in using the login block, and verify redirection works.
870 $edit = array();
871 $submit = t(variable_get('cas_login_invite', CAS_LOGIN_INVITE_DEFAULT));
872
873 $this->drupalPost('', $edit, $submit);
874 $this->assertLoggedIn($account);
875 $this->assertUrl('node');
876
877 // Block should not be shown to logged in users.
878 $this->assertCasLoginBlock(FALSE);
879 }
880 }