true) is returned. */ $this->assertEquals(["_matched" => true], $request->match('admin/crm', true)); /* Because we shifted admin/crm off the stack, just "add" should be remaining */ $this->assertEquals("add", $request->remaining()); $this->assertEquals(["_matched" => true], $request->match('add', true)); } /** * @useDatabase false */ public function testWildCardMatch() { $request = new HTTPRequest('GET', 'admin/crm/test'); $this->assertEquals(['$1' => 'crm', '$2' => 'test'], $request->match('admin/$@', true)); $this->assertTrue($request->allParsed()); $request = new HTTPRequest('GET', 'admin/crm/test'); $this->assertEquals(['_matched' => true], $request->match('admin/$*', true)); $this->assertTrue($request->allParsed()); $this->assertEquals('crm/test', $request->remaining()); $request = new HTTPRequest('GET', 'admin/crm/test/part1/part2'); $this->assertEquals(['Action' => 'crm', '$1' => 'test', '$2' => 'part1', '$3' => 'part2'], $request->match('admin/$Action/$@', true)); $this->assertTrue($request->allParsed()); $request = new HTTPRequest('GET', 'admin/crm/test/part1/part2'); $this->assertEquals(['Action' => 'crm'], $request->match('admin/$Action/$*', true)); $this->assertTrue($request->allParsed()); $this->assertEquals('test/part1/part2', $request->remaining()); } /** * This test just asserts a warning is given if there is more than one wildcard parameter. Note that this isn't an * enforcement of an API and we an add new behaviour in the future to allow many wildcard params if we want to */ public function testWildCardWithFurtherParams() { $this->expectWarning(); $request = new HTTPRequest('GET', 'admin/crm/test'); // all parameters after the first wildcard parameter are ignored $request->match('admin/$Action/$@/$Other/$*', true); } public function testHttpMethodOverrides() { $request = new HTTPRequest( 'GET', 'admin/crm' ); $this->assertTrue( $request->isGET(), 'GET with no method override' ); $request = new HTTPRequest( 'POST', 'admin/crm' ); $this->assertTrue( $request->isPOST(), 'POST with no method override' ); $request = new HTTPRequest( 'GET', 'admin/crm', ['_method' => 'DELETE'] ); $this->assertTrue( $request->isGET(), 'GET with invalid POST method override' ); $request = new HTTPRequest( 'POST', 'admin/crm', [], ['_method' => 'DELETE'] ); $this->assertTrue( $request->isPOST(), '_method override is no longer honored' ); $this->assertFalse( $request->isDELETE(), 'DELETE _method override is not honored' ); $request = new HTTPRequest( 'POST', 'admin/crm', [], ['_method' => 'put'] ); $this->assertFalse( $request->isPUT(), 'PUT _method override is not honored' ); $request = new HTTPRequest( 'POST', 'admin/crm', [], ['_method' => 'head'] ); $this->assertFalse( $request->isHEAD(), 'HEAD _method override is not honored' ); } public function detectMethodDataProvider() { return [ 'Plain POST request' => ['POST', [], 'POST'], 'Plain GET request' => ['GET', [], 'GET'], 'Plain DELETE request' => ['DELETE', [], 'DELETE'], 'Plain PUT request' => ['PUT', [], 'PUT'], 'Plain HEAD request' => ['HEAD', [], 'HEAD'], 'Request with GET method override' => ['POST', ['_method' => 'GET'], 'GET'], 'Request with HEAD method override' => ['POST', ['_method' => 'HEAD'], 'HEAD'], 'Request with DELETE method override' => ['POST', ['_method' => 'DELETE'], 'DELETE'], 'Request with PUT method override' => ['POST', ['_method' => 'PUT'], 'PUT'], 'Request with POST method override' => ['POST', ['_method' => 'POST'], 'POST'], 'Request with mixed case method override' => ['POST', ['_method' => 'gEt'], 'GET'] ]; } /** * @dataProvider detectMethodDataProvider */ public function testDetectMethod($realMethod, $post, $expected) { $actual = HTTPRequest::detect_method($realMethod, $post); $this->assertEquals($expected, $actual); } public function testBadDetectMethod() { $this->expectException(\InvalidArgumentException::class); HTTPRequest::detect_method('POST', ['_method' => 'Boom']); } public function setHttpMethodDataProvider() { return [ 'POST request' => ['POST','POST'], 'GET request' => ['GET', 'GET'], 'DELETE request' => ['DELETE', 'DELETE'], 'PUT request' => ['PUT', 'PUT'], 'HEAD request' => ['HEAD', 'HEAD'], 'Mixed case POST' => ['gEt', 'GET'], ]; } /** * @dataProvider setHttpMethodDataProvider */ public function testSetHttpMethod($method, $expected) { $request = new HTTPRequest('GET', '/hello'); $returnedRequest = $request->setHttpMethod($method); $this->assertEquals($expected, $request->httpMethod()); $this->assertEquals($request, $returnedRequest); } public function testBadSetHttpMethod() { $this->expectException(\InvalidArgumentException::class); $request = new HTTPRequest('GET', '/hello'); $request->setHttpMethod('boom'); } public function testRequestVars() { $getVars = [ 'first' => 'a', 'second' => 'b', ]; $postVars = [ 'third' => 'c', 'fourth' => 'd', ]; $requestVars = [ 'first' => 'a', 'second' => 'b', 'third' => 'c', 'fourth' => 'd', ]; $request = new HTTPRequest( 'POST', 'admin/crm', $getVars, $postVars ); $this->assertEquals( $requestVars, $request->requestVars(), 'GET parameters should supplement POST parameters' ); $getVars = [ 'first' => 'a', 'second' => 'b', ]; $postVars = [ 'first' => 'c', 'third' => 'd', ]; $requestVars = [ 'first' => 'c', 'second' => 'b', 'third' => 'd', ]; $request = new HTTPRequest( 'POST', 'admin/crm', $getVars, $postVars ); $this->assertEquals( $requestVars, $request->requestVars(), 'POST parameters should override GET parameters' ); $getVars = [ 'first' => [ 'first' => 'a', ], 'second' => [ 'second' => 'b', ], ]; $postVars = [ 'first' => [ 'first' => 'c', ], 'third' => [ 'third' => 'd', ], ]; $requestVars = [ 'first' => [ 'first' => 'c', ], 'second' => [ 'second' => 'b', ], 'third' => [ 'third' => 'd', ], ]; $request = new HTTPRequest( 'POST', 'admin/crm', $getVars, $postVars ); $this->assertEquals( $requestVars, $request->requestVars(), 'Nested POST parameters should override GET parameters' ); $getVars = [ 'first' => [ 'first' => 'a', ], 'second' => [ 'second' => 'b', ], ]; $postVars = [ 'first' => [ 'second' => 'c', ], 'third' => [ 'third' => 'd', ], ]; $requestVars = [ 'first' => [ 'first' => 'a', 'second' => 'c', ], 'second' => [ 'second' => 'b', ], 'third' => [ 'third' => 'd', ], ]; $request = new HTTPRequest( 'POST', 'admin/crm', $getVars, $postVars ); $this->assertEquals( $requestVars, $request->requestVars(), 'Nested GET parameters should supplement POST parameters' ); } public function testIsAjax() { $req = new HTTPRequest('GET', '/', ['ajax' => 0]); $this->assertFalse($req->isAjax()); $req = new HTTPRequest('GET', '/', ['ajax' => 1]); $this->assertTrue($req->isAjax()); $req = new HTTPRequest('GET', '/'); $req->addHeader('X-Requested-With', 'XMLHttpRequest'); $this->assertTrue($req->isAjax()); } public function testGetURL() { $req = new HTTPRequest('GET', '/'); $this->assertEquals('', $req->getURL()); $req = new HTTPRequest('GET', '/assets/somefile.gif'); $this->assertEquals('assets/somefile.gif', $req->getURL()); $req = new HTTPRequest('GET', '/home?test=1'); $this->assertEquals('home?test=1', $req->getURL(true)); $this->assertEquals('home', $req->getURL()); } public function testSetIPFromHeaderValue() { $req = new TrustedProxyMiddleware(); $reflectionMethod = new ReflectionMethod($req, 'getIPFromHeaderValue'); $reflectionMethod->setAccessible(true); $headers = [ '80.79.208.21, 149.126.76.1, 10.51.0.68' => '80.79.208.21', '52.19.19.103, 10.51.0.49' => '52.19.19.103', '10.51.0.49, 52.19.19.103' => '52.19.19.103', '10.51.0.49' => '10.51.0.49', '127.0.0.1, 10.51.0.49' => '127.0.0.1', ]; foreach ($headers as $header => $ip) { $this->assertEquals($ip, $reflectionMethod->invoke($req, $header)); } } public function testHasSession() { $request = new HTTPRequest('GET', '/'); $this->assertFalse($request->hasSession()); $request->setSession($this->createMock(Session::class)); $this->assertTrue($request->hasSession()); } }