<?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(); } }