AutorÃa | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>.namespace core\router;use core\param;use core\router\response\empty_response;use core\router\route;use core\router\schema\parameters\header_object;use core\router\schema\parameters\path_parameter;use core\router\schema\parameters\query_parameter;use core\router\schema\request_body;use core\router\schema\response\response;use core\tests\router\route_testcase;/*** Tests for user preference API handler.** @package core* @copyright Andrew Lyons <andrew@nicols.co.uk>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later* @covers \core\router\route*/final class route_test extends route_testcase {/*** Test that the Attribute is configured correctly.*/public function test_attributes(): void {$route = new \ReflectionClass(route::class);$this->assertNotEmpty($route->getAttributes());$this->assertNotEmpty($route->getAttributes(\Attribute::class));$attributes = $route->getAttributes(\Attribute::class);$this->assertCount(1, $attributes);$attribute = reset($attributes);$flags = $attribute->getArguments()[0];// This can only be set on class, and method.$this->assertEquals(\Attribute::TARGET_CLASS, $flags & \Attribute::TARGET_CLASS);$this->assertEquals(\Attribute::TARGET_METHOD, $flags & \Attribute::TARGET_METHOD);// Only one per method or class allowed.$this->assertEquals(0, \Attribute::IS_REPEATABLE & $flags);// Yes, this is a poor test, but if someone wants to extend this attribute in future,// they need to write appropriate tests for it.$this->assertEquals(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD, $flags);}/*** Test that path setting and getting works as expected.*/public function test_get_path(): void {$route = new route(path: '/example',);$this->assertEquals('/example', $route->get_path());// And with a parent.$child = new route(path: '/child/path',);$child->set_parent($route);$this->assertEquals('/example/child/path', $child->get_path());// But the parent is not changed in any way.$this->assertEquals('/example', $route->get_path());}/*** Test the default method.*/public function test_get_methods(): void {// No method specified.$route = new route();$this->assertNull($route->get_methods());// With a method.$route = new route(method: 'POST',);$this->assertEquals(['POST'], $route->get_methods());// An array of methods.$route = new route(method: ['POST', 'PUT'],);$this->assertEquals(['POST', 'PUT'], $route->get_methods());// A route which inherits its method from its parent.$child = new route();$child->set_parent($route);$this->assertEquals(['POST', 'PUT'], $child->get_methods());// A child route will merge its own methods with its parents.$child = new route(method: 'GET',);$child->set_parent($route);$this->assertEquals(['GET', 'POST', 'PUT'], $child->get_methods());// A child route which shares some will not duplicate.$child = new route(method: ['GET', 'PUT'],);$child->set_parent($route);$this->assertEquals(['GET', 'POST', 'PUT'], $child->get_methods());}/*** Ensure that pathtypes and queryparams accept query parameters correctly.*/public function test_params_are_params(): void {$route = new route(pathtypes: [new path_parameter(name: 'example',type: param::RAW,),new path_parameter(name: 'another',type: param::INT,),],queryparams: [new query_parameter(name: 'example',type: param::RAW,),new query_parameter(name: 'another',type: param::INT,),],);$this->assertInstanceOf(route::class, $route);}/*** Ensure that pathtypes and queryparams do not accept the wrong type of parameter.** @dataProvider invalid_constructor_param_types* @param array $args*/public function test_params_not_params(array $args): void {$this->expectException(\coding_exception::class);new route(...$args);}/*** Data provider for test_params_not_params.** @return array*/public static function invalid_constructor_param_types(): array {return ['not a param at all in queryparams' => ['args' => ['queryparams' => [new query_parameter(name: 'another',type: param::INT,),new \stdClass(),],],],'not a param at all in pathtypes' => ['args' => ['pathtypes' => [new path_parameter(name: 'another',type: param::INT,),new \stdClass(),],],],'not a param at all in headerparams' => ['args' => ['headerparams' => [new header_object(name: 'another',type: param::INT,),new \stdClass(),],],],'path_parameter in queryparams' => ['args' => ['queryparams' => [new path_parameter(name: 'example',type: param::RAW,),new query_parameter(name: 'another',type: param::INT,),],],],'query_parameter in pathtype' => ['args' => ['pathtypes' => [new path_parameter(name: 'example',type: param::RAW,),new query_parameter(name: 'another',type: param::INT,),],],],'query_parameter in header' => ['args' => ['headerparams' => [new path_parameter(name: 'example',type: param::RAW,),new query_parameter(name: 'another',type: param::INT,),],],],];}public function test_get_path_parameters(): void {// No parameters at all.$route = new route();$this->assertEmpty($route->get_path_parameters());$child = new route();$child->set_parent($route);$this->assertEmpty($child->get_path_parameters());// A route with a single parameter.$route = new route(pathtypes: [new path_parameter(name: 'example',type: param::SAFEPATH,),],);$params = $route->get_path_parameters();$this->assertCount(1, $params);$this->assertArrayHasKey('example', $params);$this->assertInstanceOf(path_parameter::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());// A route with a multiple parameters.$route = new route(pathtypes: [new path_parameter(name: 'example',type: param::SAFEPATH,),new path_parameter(name: 'another',type: param::INT,),],);$params = $route->get_path_parameters();$this->assertCount(2, $params);$this->assertArrayHasKey('example', $params);$this->assertArrayHasKey('another', $params);$this->assertInstanceOf(path_parameter::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());$this->assertInstanceOf(path_parameter::class, $params['another']);$this->assertEquals(param::INT, $params['another']->get_type());// A child will also inhereit any params from the parent.$child = new route(pathtypes: [new path_parameter(name: 'childparam',type: param::COMPONENT,),],);$child->set_parent($route);$params = $child->get_path_parameters();$this->assertCount(3, $params);$this->assertArrayHasKey('example', $params);$this->assertArrayHasKey('another', $params);$this->assertArrayHasKey('childparam', $params);$this->assertInstanceOf(path_parameter::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());$this->assertInstanceOf(path_parameter::class, $params['another']);$this->assertEquals(param::INT, $params['another']->get_type());$this->assertInstanceOf(path_parameter::class, $params['childparam']);$this->assertEquals(param::COMPONENT, $params['childparam']->get_type());}public function test_get_header_parameters(): void {// No parameters at all.$route = new route();$this->assertEmpty($route->get_header_parameters());$child = new route();$child->set_parent($route);$this->assertEmpty($child->get_header_parameters());// A route with a single parameter.$route = new route(headerparams: [new header_object(name: 'example',type: param::SAFEPATH,),],);$params = $route->get_header_parameters();$this->assertCount(1, $params);$this->assertArrayHasKey('example', $params);$this->assertInstanceOf(header_object::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());// A route with a multiple parameters.$route = new route(headerparams: [new header_object(name: 'example',type: param::SAFEPATH,),new header_object(name: 'another',type: param::INT,),],);$params = $route->get_header_parameters();$this->assertCount(2, $params);$this->assertArrayHasKey('example', $params);$this->assertArrayHasKey('another', $params);$this->assertInstanceOf(header_object::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());$this->assertInstanceOf(header_object::class, $params['another']);$this->assertEquals(param::INT, $params['another']->get_type());// A child will also inhereit any params from the parent.$child = new route(headerparams: [new header_object(name: 'childparam',type: param::COMPONENT,),],);$child->set_parent($route);$params = $child->get_header_parameters();$this->assertCount(3, $params);$this->assertArrayHasKey('example', $params);$this->assertArrayHasKey('another', $params);$this->assertArrayHasKey('childparam', $params);$this->assertInstanceOf(header_object::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());$this->assertInstanceOf(header_object::class, $params['another']);$this->assertEquals(param::INT, $params['another']->get_type());$this->assertInstanceOf(header_object::class, $params['childparam']);$this->assertEquals(param::COMPONENT, $params['childparam']->get_type());}public function test_get_query_parameters(): void {// No parameters at all.$route = new route();$this->assertEmpty($route->get_query_parameters());$child = new route();$child->set_parent($route);$this->assertEmpty($child->get_query_parameters());// A route with a single parameter.$route = new route(queryparams: [new query_parameter(name: 'example',type: param::SAFEPATH,),],);$params = $route->get_query_parameters();$this->assertCount(1, $params);$this->assertArrayHasKey('example', $params);$this->assertInstanceOf(query_parameter::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());// A route with a multiple parameters.$route = new route(queryparams: [new query_parameter(name: 'example',type: param::SAFEPATH,),new query_parameter(name: 'another',type: param::INT,),],);$params = $route->get_query_parameters();$this->assertCount(2, $params);$this->assertArrayHasKey('example', $params);$this->assertArrayHasKey('another', $params);$this->assertInstanceOf(query_parameter::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());$this->assertInstanceOf(query_parameter::class, $params['another']);$this->assertEquals(param::INT, $params['another']->get_type());// A child will also inhereit any params from the parent.$child = new route(queryparams: [new query_parameter(name: 'childparam',type: param::COMPONENT,),],);$child->set_parent($route);$params = $child->get_query_parameters();$this->assertCount(3, $params);$this->assertArrayHasKey('example', $params);$this->assertArrayHasKey('another', $params);$this->assertArrayHasKey('childparam', $params);$this->assertInstanceOf(query_parameter::class, $params['example']);$this->assertEquals(param::SAFEPATH, $params['example']->get_type());$this->assertInstanceOf(query_parameter::class, $params['another']);$this->assertEquals(param::INT, $params['another']->get_type());$this->assertInstanceOf(query_parameter::class, $params['childparam']);$this->assertEquals(param::COMPONENT, $params['childparam']->get_type());}/*** Test that has_request_body works as expected.*/public function test_has_request_body(): void {$route = new route();$this->assertFalse($route->has_request_body());$route = new route(requestbody: new request_body(),);$this->assertTrue($route->has_request_body());}public function test_get_request_body(): void {$route = new route();$this->assertNull($route->get_request_body());$body = new request_body();$route = new route(requestbody: $body,);$this->assertEquals($body, $route->get_request_body());}/*** Ensure that has_any_validatable_parameter checks the param types.*/public function test_has_any_validatable_parameter(): void {// No validatable params.$route = new route();$this->assertFalse($route->has_any_validatable_parameter());// A pathtype is a validatable param.$route = new route(pathtypes: [new path_parameter(name: 'example',type: param::INT,),],);$this->assertTrue($route->has_any_validatable_parameter());// A pathtype is a validatable param.$route = new route(queryparams: [new query_parameter(name: 'example',type: param::INT,),],);$this->assertTrue($route->has_any_validatable_parameter());// A request body is a validatable param.$route = new route(requestbody: new request_body(),);$this->assertTrue($route->has_any_validatable_parameter());}/*** Test cookie control.*/public function test_cookies(): void {// By default we allow cookie access.$route = new route();$this->assertTrue($route->cookies);}/*** Test abort_after_config control.*/public function test_abort_after_config(): void {// By default we do not abort after config.$route = new route();$this->assertFalse($route->abortafterconfig);}public function test_get_responses(): void {$route = new route(responses: [new response(statuscode: 201,description: 'Example response',),new empty_response(),],);$this->assertCount(2, $route->get_responses());$this->assertNull($route->get_response_with_status_code(200));$this->assertInstanceOf(empty_response::class,$route->get_response_with_status_code(204),);$this->assertInstanceOf(response::class,$route->get_response_with_status_code(201),);$this->assertEquals('Example response', $route->get_response_with_status_code(201)->description);}}