/**
  * @runInSeparateProcess
  * @covers ::validate
  */
 function test_validate()
 {
     /**
      * No service.
      */
     $args = array('service' => '', 'ticket' => 'ticket');
     $this->assertEquals($this->controller->handleRequest($args), "no\n\n", "Error on empty service.");
     /**
      * No ticket.
      */
     $args = array('service' => 'http://test.local/', 'ticket' => '');
     $this->assertEquals($this->controller->handleRequest($args), "no\n\n", "Error on empty ticket.");
     /**
      * Invalid ticket.
      */
     $args = array('service' => 'http://test.local/', 'ticket' => 'bad-ticket');
     $this->assertEquals($this->controller->handleRequest($args), "no\n\n", "Error on invalid ticket.");
     /**
      * Valid ticket.
      */
     $service = 'http://test/';
     $user_id = $this->factory->user->create();
     wp_set_current_user($user_id);
     try {
         $login = new CAS\Controller\LoginController($this->server);
         $login->handleRequest(array('service' => $service));
     } catch (WPDieException $message) {
         parse_str(parse_url($this->redirect_location, PHP_URL_QUERY), $query);
     }
     $args = array('service' => $service, 'ticket' => $query['ticket']);
     $user = get_user_by('id', $user_id);
     $this->assertEquals("yes\n" . $user->user_login . "\n", $this->controller->handleRequest($args), "Valid ticket.");
     Cassava\Options::set('allow_ticket_reuse', 1);
     $this->assertEquals("yes\n" . $user->user_login . "\n", $this->controller->handleRequest($args), "Tickets may reused.");
     Cassava\Options::set('allow_ticket_reuse', 0);
     $this->assertEquals("no\n\n", $this->controller->handleRequest($args), "Tickets may not be reused.");
     $this->markTestIncomplete("Test support for the optional 'pgtUrl' and 'renew' parameters.");
 }
 /**
  * @runInSeparateProcess
  * @covers ::proxy
  */
 function test_proxy()
 {
     $targetService = 'http://test/';
     /**
      * No proxy-granting ticket.
      */
     $args = array('targetService' => $targetService, 'pgt' => '');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxyFailure)', $error, 'Error if proxy-granting ticket not provided.');
     $this->assertXPathMatch(RequestException::ERROR_INVALID_REQUEST, 'string(//cas:proxyFailure[1]/@code)', $error, 'INVALID_REQUEST error code if proxy-granting ticket not provided.');
     /**
      * No target service.
      */
     $args = array('targetService' => '', 'pgt' => 'pgt');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxyFailure)', $error, 'Error if target service not provided.');
     $this->assertXPathMatch(RequestException::ERROR_INVALID_REQUEST, 'string(//cas:proxyFailure[1]/@code)', $error, 'INVALID_REQUEST error code if target service not provided.');
     /**
      * Invalid proxy-granting ticket.
      */
     $args = array('targetService' => $targetService, 'pgt' => 'bad-ticket');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxyFailure)', $error, 'Error on bad proxy-granting ticket.');
     $this->assertXPathMatch(TicketException::ERROR_BAD_PGT, 'string(//cas:proxyFailure[1]/@code)', $error, 'BAD_PGT error code on bad proxy-granting ticket.');
     /**
      * /proxy should not validate service tickets.
      */
     $user_id = $this->factory->user->create();
     wp_set_current_user($user_id);
     try {
         $login = new CAS\Controller\LoginController($this->server);
         $login->handleRequest(array('service' => $targetService));
     } catch (WPDieException $message) {
         parse_str(parse_url($this->redirect_location, PHP_URL_QUERY), $query);
     }
     $args = array('targetService' => $targetService, 'pgt' => $query['ticket']);
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxyFailure)', $xml, "'proxy' should not validate service tickets.");
     $this->assertXPathMatch(TicketException::ERROR_BAD_PGT, 'string(//cas:proxyFailure[1]/@code)', $xml, 'BAD_PGT error code on proxy ticket.');
     /**
      * /proxy should not validate proxy tickets.
      */
     $args = array('targetService' => $targetService, 'pgt' => preg_replace('@^' . CAS\Ticket::TYPE_ST . '@', CAS\Ticket::TYPE_PT, $query['ticket']));
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxyFailure)', $xml, "'proxy' should not validate proxy tickets.");
     $this->assertXPathMatch(TicketException::ERROR_BAD_PGT, 'string(//cas:proxyFailure[1]/@code)', $xml, 'BAD_PGT error code on service ticket.');
     /**
      * /proxy validates a Proxy-Granting Ticket successfully.
      */
     Cassava\Options::set('allow_ticket_reuse', 1);
     $args = array('targetService' => $targetService, 'pgt' => preg_replace('@^' . CAS\Ticket::TYPE_ST . '@', CAS\Ticket::TYPE_PGT, $query['ticket']));
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxySuccess)', $xml, 'Successful validation on proxy-granting ticket.');
     $this->assertXPathMatch(1, 'count(//cas:proxySuccess/cas:proxyTicket)', $xml, "'/proxy' response returns a proxy ticket.");
     $proxyTicket = $this->xpathEvaluate('string(//cas:proxySuccess[1]/cas:proxyTicket[1])', $xml);
     $args = array('service' => $targetService, 'ticket' => $proxyTicket);
     $proxyValidate = new CAS\Controller\ProxyValidateController($this->server);
     $xml = $proxyValidate->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess)', $xml, "'/proxy' response returns a valid proxy ticket.");
     /**
      * Do not enforce single-use tickets.
      */
     $args = array('targetService' => $targetService, 'pgt' => preg_replace('@^' . CAS\Ticket::TYPE_ST . '@', CAS\Ticket::TYPE_PGT, $query['ticket']));
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxySuccess)', $xml, 'Settings allow ticket reuse.');
     /**
      * Enforce single-use tickets.
      */
     Cassava\Options::set('allow_ticket_reuse', 0);
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:proxyFailure)', $error, "Settings do not allow ticket reuse.");
     $this->assertXPathMatch(TicketException::ERROR_BAD_PGT, 'string(//cas:proxyFailure[1]/@code)', $error, 'BAD_PGT error code on ticket reuse.');
 }
 /**
  * @runInSeparateProcess
  * @covers ::proxyValidate
  *
  * @todo Test support for the optional 'pgtUrl' parameter.
  * @todo Test support for the optional 'renew' parameter.
  */
 function test_proxyValidate()
 {
     $service = 'http://test/';
     /**
      * No service.
      */
     $args = array('service' => '', 'ticket' => 'ticket');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, 'Error if service not provided.');
     $this->assertXPathMatch(RequestException::ERROR_INVALID_REQUEST, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_REQUEST error code if service not provided.');
     /**
      * No ticket.
      */
     $args = array('service' => $service, 'ticket' => '');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, 'Error if ticket not provided.');
     $this->assertXPathMatch(RequestException::ERROR_INVALID_REQUEST, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_REQUEST error code if ticket not provided.');
     /**
      * Invalid ticket.
      */
     $args = array('service' => $service, 'ticket' => 'bad-ticket');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, 'Error on bad ticket.');
     $this->assertXPathMatch(TicketException::ERROR_INVALID_TICKET, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_TICKET error code on bad ticket.');
     /**
      * Valid ticket.
      */
     $user_id = $this->factory->user->create();
     wp_set_current_user($user_id);
     try {
         $login = new CAS\Controller\LoginController($this->server);
         $login->handleRequest(array('service' => $service));
     } catch (WPDieException $message) {
         parse_str(parse_url($this->redirect_location, PHP_URL_QUERY), $query);
     }
     $args = array('service' => $service, 'ticket' => $query['ticket']);
     $user = get_user_by('id', $user_id);
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess)', $xml, 'Successful validation.');
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess/cas:user)', $xml, "Ticket validation response returns a user.");
     $this->assertXPathMatch($user->user_login, 'string(//cas:authenticationSuccess[1]/cas:user[1])', $xml, "Ticket validation returns user login.");
     /**
      * Do not enforce single-use tickets.
      */
     Cassava\Options::set('allow_ticket_reuse', 1);
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess)', $xml, 'Settings allow ticket reuse.');
     /**
      * /proxyValidate may validate Proxy Tickets.
      */
     $args = array('service' => $service, 'ticket' => preg_replace('@^' . CAS\Ticket::TYPE_ST . '@', CAS\Ticket::TYPE_PT, $query['ticket']));
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess)', $xml, "'proxyValidate' may validate proxy tickets.");
     /**
      * Enforce single-use tickets.
      */
     Cassava\Options::set('allow_ticket_reuse', 0);
     $args = array('service' => $service, 'ticket' => $query['ticket']);
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, "Settings do not allow ticket reuse.");
     $this->assertXPathMatch(TicketException::ERROR_INVALID_TICKET, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_TICKET error code on ticket reuse.');
 }
 /**
  * @runInSeparateProcess
  * @covers ::serviceValidate
  *
  * @todo Test support for the optional 'pgtUrl' parameter.
  * @todo Test support for the optional 'renew' parameter.
  */
 function test_serviceValidate()
 {
     $service = 'http://test/';
     /**
      * No service.
      */
     $args = array('service' => '', 'ticket' => 'ticket');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, 'Error if service not provided.');
     $this->assertXPathMatch(RequestException::ERROR_INVALID_REQUEST, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_REQUEST error code if service not provided.');
     /**
      * No ticket.
      */
     $args = array('service' => $service, 'ticket' => '');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, 'Error if ticket not provided.');
     $this->assertXPathMatch(RequestException::ERROR_INVALID_REQUEST, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_REQUEST error code if ticket not provided.');
     /**
      * Invalid ticket.
      */
     $args = array('service' => $service, 'ticket' => 'bad-ticket');
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, 'Error on bad ticket.');
     $this->assertXPathMatch(TicketException::ERROR_INVALID_TICKET, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_TICKET error code on bad ticket.');
     /**
      * Valid ticket.
      */
     $user_id = $this->factory->user->create();
     wp_set_current_user($user_id);
     try {
         $login = new CAS\Controller\LoginController($this->server);
         $login->handleRequest(array('service' => $service));
     } catch (WPDieException $message) {
         parse_str(parse_url($this->redirect_location, PHP_URL_QUERY), $query);
     }
     $args = array('service' => $service, 'ticket' => $query['ticket']);
     $user = get_user_by('id', $user_id);
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess)', $xml, 'Successful validation.');
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess/cas:user)', $xml, "Ticket validation response returns a user.");
     $this->assertXPathMatch($user->user_login, 'string(//cas:authenticationSuccess/cas:user)', $xml, "Ticket validation returns user login.");
     /**
      * Do not enforce single-use tickets.
      */
     Cassava\Options::set('allow_ticket_reuse', 1);
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationSuccess)', $xml, 'Settings allow ticket reuse.');
     /**
      * Validate does not return any user attributes.
      */
     $this->assertXPathMatch(0, 'count(//cas:authenticationSuccess/cas:attributes)', $xml, "Ticket validation returns no user attributes.");
     /**
      * Validate returns selected user attributes.
      */
     Cassava\Options::set('attributes', array('display_name', 'user_email'));
     $xml = $this->controller->handleRequest($args);
     $this->assertXPathMatch($user->get('display_name'), 'string(//cas:authenticationSuccess/cas:attributes/cas:display_name)', $xml, 'Ticket validation returns the user display name.');
     $this->assertXPathMatch($user->get('user_email'), 'string(//cas:authenticationSuccess/cas:attributes/cas:user_email)', $xml, 'Ticket validation returns the user email.');
     /**
      * /serviceValidate should not validate Proxy Tickets.
      */
     $args = array('service' => $service, 'ticket' => preg_replace('@^' . CAS\Ticket::TYPE_ST . '@', CAS\Ticket::TYPE_PT, $query['ticket']));
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, "'serviceValidate' may not validate proxy tickets.");
     $this->assertXPathMatch(TicketException::ERROR_INVALID_TICKET, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_TICKET error code on proxy ticket.');
     /**
      * Enforce single-use tickets.
      */
     Cassava\Options::set('allow_ticket_reuse', 0);
     $args = array('service' => $service, 'ticket' => $query['ticket']);
     $error = $this->controller->handleRequest($args);
     $this->assertXPathMatch(1, 'count(//cas:authenticationFailure)', $error, "Settings do not allow ticket reuse.");
     $this->assertXPathMatch(TicketException::ERROR_INVALID_TICKET, 'string(//cas:authenticationFailure[1]/@code)', $error, 'INVALID_TICKET error code on ticket reuse.');
     $this->markTestIncomplete("Test support for the optional 'pgtUrl' and 'renew' parameters.");
 }