Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
RpcNetidClientSoapTest.php 23.24 KiB
<?php

use edu\wisc\doit\RpcNetidClientSoap;
use edu\wisc\doit\RpcNetidClientSoapConfig;
use edu\wisc\doit\RpcNetidStructGetQuestionsRequest;
use edu\wisc\doit\RpcNetidStructQuestion;
use edu\wisc\doit\RpcNetidStructNetidResponse;
use edu\wisc\doit\RpcNetidStructValidationResponse;

/**
 * Unit tests for the {@link edu\wisc\doit\RpcNetidClientSoap} class.
 * 
 * These tests make use of PHPUnit's mocking ability. A mock PHP SoapClient is built off
 * the test NetID web service WSDL. This mocked SoapClient can then be used to initialize
 * RpcNetidClientSoap. 
 * 
 * @see https://phpunit.de/manual/current/en/test-doubles.html#test-doubles.stubbing-and-mocking-web-services PHPUnit: Stubbing and Mocking Web Services
 */

class RpcNetidClientSoapTest extends PHPUnit\Framework\TestCase {

	private $config;
	private $cert;
	private $key;
	private $wsdl;
	private $mockSoapClient;

	/**
	 * The mock SOAP client is created before each unit test
	 * @see PHPUnit_Framework_TestCase::setUp()
	 */
	function setUp() {
		parent::setUp();
		$this->wsdl = realpath( __DIR__ . '/resources/rpctest-netid.wsdl' );
		$this->mockSoapClient = $this->getMockFromWsdl( $this->wsdl, 'SoapClientNetid'  );
	}
	
	/** 
	 * @test
	 * @expectedException DomainException 
	 */
	function getQuestions_UidIsNotString() {
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getQuestions(123);
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function getQuestions_UnexpectedResponeCodeFromWebService() {
		$result = new stdClass();
		$result->result = 500;
		$this->mockSoapClient->expects($this->any())->method('getQuestions')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getQuestions('nobody');
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 101
	 */
	function getQuestions_UnexpectedDataStructureFromWebService() {
		$result = new stdClass();
		$result->result = 200;
		$this->mockSoapClient->expects($this->any())->method('getQuestions')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getQuestions( 'nobody' );
	}
	
	/** @test valid call to getQuestions() */
	function getQuestions_validCall() {
		
		// Set up return data for mocked function
		$result = new stdClass();
		$result->result = 200;
		$result->Questions = new stdClass();
		$result->Questions->QuestionPair = array();
		
		$q1 = new stdClass();
		$q1->Number = 1;
		$q1->Question = "test";
		$result->Questions->QuestionPair[] = $q1;
		
		$q2 = new StdClass();
		$q2->Number = 2;
		$q2->Question = "test2";
		$result->Questions->QuestionPair[] = $q2;
		
		$this->mockSoapClient->expects($this->any())->method('getQuestions')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->getQuestions( 'nobody' );
		$this->assertInternalType( 'array', $returnValue );
		$this->assertCount( 2, $returnValue );
		$this->assertInstanceOf( 'edu\wisc\doit\RpcNetidStructQuestion', $returnValue[0] );
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function lockStatus_UidIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->lockStatus(123);
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function lockStatus_UnexpectedStatusCodeFromWebService(){
		$result = new stdClass();
		$result->result = 401;
		$this->mockSoapClient->expects($this->any())->method('lockStatus')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->lockStatus( 'nobody' );
	}
	
	/**
	 * @test Valid call to lockStatus that returns false
	 */
	function lockStatus_validCall_ReturnsFalse(){
		$result = new stdClass();
		$result->result = 200;

		$this->mockSoapClient->expects($this->any())->method('lockStatus')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->lockStatus( 'nobody' );
		$this->assertInstanceOf( 'edu\wisc\doit\RpcNetidStructLockStatus', $returnValue );
		$this->assertFalse($returnValue->getLocked());
		$this->assertEquals("Not locked out", $returnValue->getReason());
	}
	
	/**
	 * @test Valid call to lockStatus that returns true
	 */
	function lockStatus_validCall_ReturnsTrue(){
		$result = new stdClass();
		$result->result = 400;

		$this->mockSoapClient->expects($this->any())->method('lockStatus')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->lockStatus( 'nobody' );
		$this->assertInstanceOf( 'edu\wisc\doit\RpcNetidStructLockStatus', $returnValue );
		$this->assertTrue($returnValue->getLocked());
		$this->assertEquals("Locked out of password reset - too many attempts", $returnValue->getReason());
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function changePassword_UidIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->changePassword(123, "password");
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function changePassword_PasswordIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->changePassword("uid", 123);
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function changePassword_UnexpectedStatusCodeFromWebService(){
		$result = new stdClass();
		$result->result = 500;
		$this->mockSoapClient->expects($this->any())->method('changePassword')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->changePassword( 'uid', 'password' );
	}
	
	/**
	 * @test valid call to checkPassword that returns false
	 */
	function changePassword_ValidCall_ReturnsFalse(){
		$result = new stdClass();
		$result->result = 401;
		$this->mockSoapClient->expects($this->any())->method('changePassword')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->changePassword( 'uid', 'password' );
		$this->assertFalse($returnValue);
	}
	
	/**
	 * @test valid call to checkPassword that returns true
	 */
	function changePassword_ValidCall_ReturnsTrue(){
		$result = new stdClass();
		$result->result = 200;
		$this->mockSoapClient->expects($this->any())->method('changePassword')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->changePassword( 'uid', 'password' );
		$this->assertTrue($returnValue);
	}
	
	/**
	 * @test
	 * @expectedException InvalidArgumentException
	 */
		
	function checkAnswers_UidIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "question1", "answer1"),
							new RpcNetidStructQuestion(2, "question2", "answer2"));
		$client->checkAnswers(123, $questions, '127.0.0.1' );
	}
	
	/**
	 * @test
	 * @expectedException InvalidArgumentException
	 */
	function checkAnswers_IpIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "question1", "answer1"),
							new RpcNetidStructQuestion(2, "question2", "answer2"));
		$client->checkAnswers('uid', $questions, 123 );
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function checkAnswers_invalidIp() {
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "question1", "answer1"),
							new RpcNetidStructQuestion(2, "question2", "answer2"));
		$client->checkAnswers('uid', $questions, "asdfasdf" );
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function checkAnswers_QuestionsDoesNotContainRpcNetidStructQuestions(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	123, 456 );
		$client->checkAnswers('uid', $questions, '127.0.0.1' );
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function checkAnswers_QuestionsDoesNotContainNumberOrAnswer() {
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "asdf" ),
							new RpcNetidStructQuestion(2, "asdf2" ));
		$client->checkAnswers('uid', $questions, '127.0.0.1' );
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */	

	function checkAnswers_UnexpectedStatusCodeFromWebService(){
		$result = new stdClass();
		$result->result = 500;
		$this->mockSoapClient->expects($this->any())->method('checkAnswers')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "question1", "answer1"),
							new RpcNetidStructQuestion(2, "question2", "answer2"));
		$client->checkAnswers('uid', $questions, '127.0.0.1' );
	}
	
	/**
	 * @test Valid call to checkAnswers that returns false
	 */
	function checkAnswers_ValidCall_ReturnsFalse(){
		$result = new stdClass();
		$result->result = 400;
		$this->mockSoapClient->expects($this->any())->method('checkAnswers')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "question1", "answer1"),
							new RpcNetidStructQuestion(2, "question2", "answer2"));
		$returnValues = $client->checkAnswers('uid', $questions, '127.0.0.1' );
		$this->assertFalse($returnValues);
	}
	
	/**
	 * @test Valid call to checkAnswers that returns false
	 */
	function checkAnswers_ValidCall_ReturnsTrue(){
		$result = new stdClass();
		$result->result = 200;
		$this->mockSoapClient->expects($this->any())->method('checkAnswers')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$questions = array(	new RpcNetidStructQuestion(1, "question1", "answer1"),
							new RpcNetidStructQuestion(2, "question2", "answer2"));
		$returnValues = $client->checkAnswers( 'uid', $questions, '127.0.0.1' );
		$this->assertTrue($returnValues);
	}
	
	/**
	 * @test
	 * @expectedException InvalidArgumentException
	 */
	function getRecoveryEmail_UidIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getRecoveryEmail(123);
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function getRecoveryEmail_UnexpectedStatusCodeFromWebService(){
		$result = new stdClass();
		$result->result = 401;
		
		$this->mockSoapClient->expects($this->any())->method('getRecoveryEmail')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getRecoveryEmail("uid");
	}
	
	/**
	 * @test Valid uid with an email response when calling getRecoveryEmail
	 */
	function getRecoveryEmail_ValidCall(){
		$expectedEmail = "test@gmail.com";
		$result = new stdClass();
		$result->result = 200;
		$result->recoveryemail = $expectedEmail;
		
		$this->mockSoapClient->expects($this->any())->method('getRecoveryEmail')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValues = $client->getRecoveryEmail("uid");
		$this->assertEquals($expectedEmail,	$returnValues);
	}
	
	/**
	 * @test
	 * @expectedException InvalidArgumentException
	 */
	function getNetidForRecoveryEmail_RecoveryEmailIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getNetidForRecoveryEmail(123);
	}

	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function getNetidForRecoveryEmail_UnexpectedStatusCodeFromWebService(){
		$result = new stdClass();
		$result->result = 500;
		
		$this->mockSoapClient->expects($this->any())->method("getNetIDForRecoveryEmail")->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->getNetidForRecoveryEmail("test@gmail.com");
	}
	
	/**
	 * @test Valid call for getNetIDForRecoveryEmail with false response
	 */
	function getNetIDForRecoveryEmail_ValidCall_ReturnsFalse(){
		$result = new stdClass();
		$result->result = 204;
	
		$this->mockSoapClient->expects($this->any())->method("getNetIDForRecoveryEmail")->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValues = $client->getNetidForRecoveryEmail("test@gmail.com");
		
		$this->assertFalse($returnValues);
	}
	
	/**
	 * @test Valid call for getNetIDForRecoveryEmail with Netid response
	 */
	function getNetIDForRecoveryEmail_ValidCall_ReturnsTrue(){
		$expected = "test";
		$result = new stdClass();
		$result->result = 200;
		$result->netid = $expected;
	
		$this->mockSoapClient->expects($this->any())->method("getNetIDForRecoveryEmail")->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValues = $client->getNetidForRecoveryEmail("test@gmail.com");
	
		$this->assertEquals($expected, $returnValues);
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function setRecoveryEmail_UidIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->setRecoveryEmail( 123, 'email@address.com' );
	}
	
	/**
	 * @test
	 * @expectedException DomainException
	 */
	function setRecoveryEmail_RecoveryEmailIsNotString(){
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->setRecoveryEmail( 'uid', 123 );
	}
	
	/**
	 * @test setRecoveryEmail throws if 422 (invalid email) is returned by web service
	 * @expectedException DomainException
	 */
	function setRecoveryEmail_throwsExceptionIf422() {
		$soapResult = new StdClass();
		$soapResult->result = 422;
		$this->mockSoapClient->method('setRecoveryEmail')->willReturn( $soapResult );
		$client = new RpcNetidClientSoap( $this->mockSoapClient );
		$client->setRecoveryEmail( "nobody", "nowhere" );
	}
	
	/**
	 * @test
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function setRecoveryEmail_UnexpectedStatusCodeFromWebService(){
		$result = new stdClass();
		$result->result = 500;
		$this->mockSoapClient->expects($this->any())->method('setRecoveryEmail')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->setRecoveryEmail( 'uid', 'email@address.com');
	}
	
	/**
	 * @test Vaild call to setRecoveryEmail that returns false
	 */
	function setRecoveryEmail_ValidCall_ReturnsFalse(){
		$result = new stdClass();
		$result->result = 502;
		$this->mockSoapClient->expects($this->any())->method('setRecoveryEmail')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->setRecoveryEmail( 'uid', 'email@address.com');
		$this->assertFalse($returnValue);
	}
	
	/**
	 * @test Vaild call to setRecoveryEmail that returns true
	 */
	function setRecoveryEmail_ValidCall_ReturnsTrue(){
		$result = new stdClass();
		$result->result = 200;
		$this->mockSoapClient->expects($this->any())->method('setRecoveryEmail')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->setRecoveryEmail( 'uid', 'email@address.com');
		$this->assertTrue($returnValue);
	}

	/**
	 * @test factory create method with valid config
	 * 
	 * There are no additional tests for create() because a lot of the testing is implied in CertificateService and RpcNetidClientSoapConfig
	 */
	function create_validConfig() {
		$this->assertFileExists( __DIR__ . '/resources/rpctest-netid.wsdl');
		$this->assertFileExists(__DIR__ . '/resources/middleware-ws-client-test-ca.cer');
		$this->assertFileExists(__DIR__ . '/resources/testClientCert.pem');
		$config = new RpcNetidClientSoapConfig( __DIR__ . '/resources/rpctest-netid.wsdl',  
				__DIR__ . '/resources/middleware-ws-client-test-ca.cer', 
				__DIR__ . '/resources/testClientCert.pem');
		$this->assertInstanceOf("edu\wisc\doit\RpcNetidClientSoap", RpcNetidClientSoap::create( $config ) );
	}
	
	/**
	 * @test Valid call to passwordChoicePolicyCheck that returns false when password does not meet standards
	 */
	function passwordChoicePolicyCheck_ValidCall_ReturnsFalse400(){
		
		$result = new stdClass();
		$result->result = 400;
		$result->Reasons = new stdClass();
		$result->Reasons->Reason = array( "Bad Password" );
		
		$this->mockSoapClient->expects($this->any())->method('passwordChoicePolicyCheck')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->passwordChoicePolicyCheck("uid", "password");
		
		$this->assertFalse($returnValue->getIsValid());
		$this->assertEquals($result->Reasons->Reason, $returnValue->getReasons());
		
	}
	
	/**
	 * @test Valid call to passwordChoicePolicyCheck that returns false when passed invalid arguements
	 */
	function passwordChoicePolicyCheck_ValidCall_ReturnsFalse401(){
		
		$result = new stdClass();
		$result->result = 401;
		$result->Reasons = new stdClass();
		
		$result->Reasons->Reason = array( "Invalid Arguments" );
		$this->mockSoapClient->expects($this->any())->method('passwordChoicePolicyCheck')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->passwordChoicePolicyCheck("uid", "password");
		
		$this->assertFalse($returnValue->getIsValid());
		$this->assertEquals($result->Reasons->Reason, $returnValue->getReasons());
		
	}
	
	/**
	 * @test Valid call to passwordChoicePolicyCheck that returns true when passed a valid password
	 */
	function passwordChoicePolicyCheck_ValidCall_ReturnsTrue(){
		
		$result = new stdClass();
		$result->result = 200;
		
		$this->mockSoapClient->expects($this->any())->method('passwordChoicePolicyCheck')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returnValue = $client->passwordChoicePolicyCheck("uid", "password");
		
		$this->assertTrue($returnValue->getIsValid());
		
	}
	
	/* checkLOA tests ------------------------------- */
	
	/**
	 * @test returns false if 400 is returned by web service
	 */
	function checkLOA_400_returns_false() {
		
		$result = new stdClass();
		$result->result = 400;
		
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertFalse( $returned->getIsValid() );
		
	}
	
	/**
	 * @test returns false if web service returns 401 (invalid parameters)
	 */
	function checkLOA_401_returns_false() {
	
		$result = new stdClass();
		$result->result = 401;
	
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertFalse( $returned->getIsValid() );
	
	}
	
	/**
	 * @test returns false if web service returns 402 (No PVI found for UID)
	 */
	function checkLOA_402_returns_false() {
	
		$result = new stdClass();
		$result->result = 402;
	
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertFalse( $returned->getIsValid() );

	}
	
	/**
	 * @test returns false if web service returns 403 (No LOA found for UID)
	 */
	function checkLOA_403_returns_false() {
	
		$result = new stdClass();
		$result->result = 403;
	
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertFalse( $returned->getIsValid() );
	
	}
	
	/**
	 * @test returns false if web service returns 404 (No Wiscard eligibility found for user)
	 */
	function checkLOA_404_returns_false() {
	
		$result = new stdClass();
		$result->result = 404;
	
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertFalse( $returned->getIsValid() );
	
	}
	
	/**
	 * @test returns false validation object with reason if web service returns 405 (Person is LOA2, but the Wiscard was missing)
	 */
	function checkLOA_405_returns_false_with_reason() {
		
		$result = new stdClass();
		$result->result = 405;
		
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime() );
		
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertFalse( $returned->getIsValid() );
		$this->assertEquals( RpcNetidStructValidationResponse::REASON_NEEDS_WISCARD, $returned->getReasons() );
		
	}
	
	/**
	 * @test returns true validation object when web service returns 200
	 */
	function checkLOA_200_returns_true() {
		
		$result = new stdClass();
		$result->result = 200;
		
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$returned = $client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		
		$this->assertInstanceOf('edu\wisc\doit\RpcNetidStructValidationResponse', $returned );
		$this->assertTrue( $returned->getIsValid() );
		
	}
	
	/**
	 * @test throws exception if an unexpected response code was received by web service 
	 * @expectedException edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 100
	 */
	function checkLOA_500_throws_exception() {
		$result = new stdClass();
		$result->result = 500;
		
		$this->mockSoapClient->expects($this->any())->method('checkLOA')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->checkLOA( "jsmith", new \DateTime(), "12345678901" );
		
	}

	/**
	 * @test ping() returns the version on success
	 */
	function ping_200_returns_version() {
		$result = new stdClass();
		$result->version = "1.0";

		$this->mockSoapClient->expects($this->any())->method('ping')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$this->assertEquals( "1.0", $client->ping() );
	}

	/**
	 * @test throws exception if version is not supplied by web service
	 * @expectedException \edu\wisc\doit\RpcNetidClientSoapException
	 * @expectedExceptionCode 101
	 */
	function ping_no_version_throws() {
		$result = new stdClass();

		$this->mockSoapClient->expects($this->any())->method('ping')->will($this->returnValue($result));
		$client = new RpcNetidClientSoap($this->mockSoapClient);
		$client->ping();
	}

}