From c3f7bd96b26c3bd2e9291a629157a4d58e2ce68e Mon Sep 17 00:00:00 2001 From: leo108 Date: Sat, 15 Oct 2016 15:09:31 +0800 Subject: [PATCH] add more tests && improve robustness --- composer.json | 3 +- src/Http/Controllers/ValidateController.php | 16 +++- .../Controllers/ValidateControllerTest.php | 92 +++++++++++++++++-- tests/_support/SerializableModel.php | 20 ++++ 4 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 tests/_support/SerializableModel.php diff --git a/composer.json b/composer.json index 154e7ff..41735f5 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "autoload-dev": { "classmap": [ "tests/TestCase.php", - "tests/_support/User.php" + "tests/_support/User.php", + "tests/_support/SerializableModel.php" ] } } diff --git a/src/Http/Controllers/ValidateController.php b/src/Http/Controllers/ValidateController.php index 8f21194..96d8a8c 100644 --- a/src/Http/Controllers/ValidateController.php +++ b/src/Http/Controllers/ValidateController.php @@ -151,7 +151,21 @@ protected function successResponse($username, $attrs, $format) if (!empty($attrs)) { $childAttrs = $childSuccess->addChild('cas:attributes'); foreach ($attrs as $key => $value) { - $childAttrs->addChild('cas:'.$key, $value); + if (is_string($value)) { + $str = $value; + } else if (is_object($value) && method_exists($value, '__toString')) { + $str = $value->__toString(); + } else if ($value instanceof \Serializable) { + $str = serialize($value); + } else { + //array or object that doesn't have __toString method + //json_encode will return false if encode failed + $str = json_encode($value); + } + + if (is_string($str)) { + $childAttrs->addChild('cas:'.$key, $str); + } } } diff --git a/tests/Http/Controllers/ValidateControllerTest.php b/tests/Http/Controllers/ValidateControllerTest.php index 574fad4..0d44b13 100644 --- a/tests/Http/Controllers/ValidateControllerTest.php +++ b/tests/Http/Controllers/ValidateControllerTest.php @@ -15,16 +15,25 @@ use Leo108\CAS\Models\Ticket; use Leo108\CAS\Repositories\TicketRepository; use ReflectionClass; +use SerializableModel; use SimpleXMLElement; use TestCase; use Mockery; use User; +function method_exists($obj, $method) +{ + return ValidateControllerTest::$functions->method_exists($obj, $method); +} + class ValidateControllerTest extends TestCase { + public static $functions; + public function setUp() { parent::setUp(); + self::$functions = Mockery::mock(); app()->instance(TicketLocker::class, Mockery::mock(TicketLocker::class)); } @@ -386,12 +395,29 @@ function ($xml) { $method = self::getMethod($controller, 'successResponse'); $this->assertEquals('returnXML called', $method->invokeArgs($controller, ['test_name', [], 'XML'])); + $objWithToString = Mockery::mock()->shouldReceive('__toString')->andReturn('string from __toString'); + self::$functions + ->shouldReceive('method_exists') + ->with($objWithToString, '__toString') + ->andReturn(true) + ->shouldReceive('method_exists') + ->andReturn(false); + + $attributes = [ + 'string' => 'real_name', + 'simple_array' => [1, 2, 3], + 'kv_array' => ['key' => 'value'], + 'simple_object' => (object) ['key' => 'value'], + 'obj_with_to_string' => $objWithToString, + 'serializable' => new SerializableModel(), + 'resource' => fopen(__FILE__, 'a'), + ]; $controller = Mockery::mock(ValidateController::class) ->makePartial() ->shouldAllowMockingProtectedMethods() ->shouldReceive('returnXML') ->andReturnUsing( - function ($xml) { + function ($xml) use ($attributes) { $this->assertInstanceOf(SimpleXMLElement::class, $xml); /* @var SimpleXMLElement $xml */ $children = $xml->xpath('cas:authenticationSuccess'); @@ -401,19 +427,40 @@ function ($xml) { $this->assertEquals('test_name', $user[0]->__toString()); $attr = $children[0]->xpath('cas:attributes'); $this->assertCount(1, $attr); - $rn = $attr[0]->xpath('cas:real_name'); - $this->assertCount(1, $rn); - $this->assertEquals('real_name', $rn[0]->__toString()); + + $str = $attr[0]->xpath('cas:string'); + $this->assertCount(1, $str); + $this->assertEquals($attributes['string'], $str[0]->__toString()); + + $str = $attr[0]->xpath('cas:simple_array'); + $this->assertCount(1, $str); + $this->assertEquals(json_encode($attributes['simple_array']), $str[0]->__toString()); + + $str = $attr[0]->xpath('cas:kv_array'); + $this->assertCount(1, $str); + $this->assertEquals(json_encode($attributes['kv_array']), $str[0]->__toString()); + + $str = $attr[0]->xpath('cas:simple_object'); + $this->assertCount(1, $str); + $this->assertEquals(json_encode($attributes['simple_object']), $str[0]->__toString()); + + $str = $attr[0]->xpath('cas:obj_with_to_string'); + $this->assertCount(1, $str); + $this->assertEquals($attributes['obj_with_to_string']->__toString(), $str[0]->__toString()); + + $str = $attr[0]->xpath('cas:serializable'); + $this->assertCount(1, $str); + $this->assertEquals(serialize($attributes['serializable']), $str[0]->__toString()); + + $str = $attr[0]->xpath('cas:resource'); + $this->assertCount(0, $str); return 'returnXML called'; } ) ->getMock(); $method = self::getMethod($controller, 'successResponse'); - $this->assertEquals( - 'returnXML called', - $method->invokeArgs($controller, ['test_name', ['real_name' => 'real_name'], 'XML']) - ); + $this->assertEquals('returnXML called', $method->invokeArgs($controller, ['test_name', $attributes, 'XML',])); } public function testFailureResponse() @@ -457,6 +504,35 @@ function ($xml) { $this->assertEquals('returnXML called', $method->invokeArgs($controller, ['code', 'desc', 'XML'])); } + public function testRemoveXmlFirstLine() + { + $xml = new SimpleXMLElement(ValidateController::BASE_XML); + $controller = Mockery::mock(ValidateController::class); + $method = self::getMethod($controller, 'removeXmlFirstLine'); + $this->assertNotContains('', $method->invoke($controller, $xml->asXML())); + + $normalStr = 'some string'; + $this->assertEquals($normalStr, $method->invoke($controller, $normalStr)); + } + + public function testReturnXML() + { + $xml = new SimpleXMLElement(ValidateController::BASE_XML); + $controller = Mockery::mock(ValidateController::class) + ->makePartial() + ->shouldAllowMockingProtectedMethods() + ->shouldReceive('removeXmlFirstLine') + ->andReturn('parsed string') + ->getMock(); + + $method = self::getMethod($controller, 'returnXML'); + $resp = $method->invoke($controller, $xml); + $this->assertInstanceOf(Response::class, $resp); + $this->assertEquals(200, $resp->getStatusCode()); + $this->assertTrue($resp->headers->has('Content-Type')); + $this->assertEquals('application/xml', $resp->headers->get('Content-Type')); + } + protected static function getMethod($obj, $name) { $class = new ReflectionClass($obj); diff --git a/tests/_support/SerializableModel.php b/tests/_support/SerializableModel.php new file mode 100644 index 0000000..6e24d27 --- /dev/null +++ b/tests/_support/SerializableModel.php @@ -0,0 +1,20 @@ +