-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy pathRedirectPluginTest.php
116 lines (102 loc) · 6.17 KB
/
RedirectPluginTest.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
declare(strict_types=1);
namespace Tests\Http\Client\Common\Plugin;
use Http\Client\Common\Exception\CircularRedirectionException;
use Http\Client\Common\Plugin\RedirectPlugin;
use Http\Promise\FulfilledPromise;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7\Request;
use Nyholm\Psr7\Response;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class RedirectPluginTest extends TestCase
{
public function testCircularDetection(): void
{
$this->expectException(CircularRedirectionException::class);
(new RedirectPlugin())->handleRequest(
new Request('GET', 'https://example.com/path?query=value'),
function () {
return new FulfilledPromise(new Response(302, ['Location' => 'https://example.com/path?query=value']));
},
function () {}
)->wait();
}
public function testPostGetDropRequestBody(): void
{
$response = (new RedirectPlugin())->handleRequest(
new Request('POST', 'https://example.com/path', ['Content-Type' => 'text/plain', 'Content-Length' => '10'], (new Psr17Factory())->createStream('hello test')),
function (RequestInterface $request) {
$this->assertSame(10, $request->getBody()->getSize());
$this->assertTrue($request->hasHeader('Content-Type'));
$this->assertTrue($request->hasHeader('Content-Length'));
return new FulfilledPromise(new Response(302, ['Location' => 'https://example.com/other']));
},
function (RequestInterface $request) {
$this->assertSame('GET', $request->getMethod());
$this->assertSame(0, $request->getBody()->getSize());
$this->assertFalse($request->hasHeader('Content-Type'));
$this->assertFalse($request->hasHeader('Content-Length'));
return new FulfilledPromise(new Response(200, ['uri' => $request->getUri()->__toString()]));
}
)->wait();
$this->assertSame('https://example.com/other', $response->getHeaderLine('uri'));
}
public function testPostGetNoFactory(): void
{
// We explicitly set the stream factory to null. Same happens if no factory can be found.
// In this case, the redirect will leave the body alone.
$response = (new RedirectPlugin(['stream_factory' => null]))->handleRequest(
new Request('POST', 'https://example.com/path', ['Content-Type' => 'text/plain', 'Content-Length' => '10'], (new Psr17Factory())->createStream('hello test')),
function (RequestInterface $request) {
$this->assertSame(10, $request->getBody()->getSize());
$this->assertTrue($request->hasHeader('Content-Type'));
$this->assertTrue($request->hasHeader('Content-Length'));
return new FulfilledPromise(new Response(302, ['Location' => 'https://example.com/other']));
},
function (RequestInterface $request) {
$this->assertSame('GET', $request->getMethod());
$this->assertSame(10, $request->getBody()->getSize());
$this->assertTrue($request->hasHeader('Content-Type'));
$this->assertTrue($request->hasHeader('Content-Length'));
return new FulfilledPromise(new Response(200, ['uri' => $request->getUri()->__toString()]));
}
)->wait();
$this->assertSame('https://example.com/other', $response->getHeaderLine('uri'));
}
public static function provideRedirections(): array
{
return [
'no path on target' => ['https://example.com/path?query=value', 'https://example.com?query=value', 'https://example.com?query=value'],
'root path on target' => ['https://example.com/path?query=value', 'https://example.com/?query=value', 'https://example.com/?query=value'],
'redirect to query' => ['https://example.com', 'https://example.com?query=value', 'https://example.com?query=value'],
'redirect to different domain without port' => ['https://example.com:8000', 'https://foo.com?query=value', 'https://foo.com?query=value'],
'network-path redirect, preserve scheme' => ['https://example.com:8000', '//foo.com/path?query=value', 'https://foo.com/path?query=value'],
'absolute-path redirect, preserve host' => ['https://example.com:8000', '/path?query=value', 'https://example.com:8000/path?query=value'],
'relative-path redirect, append' => ['https://example.com:8000/path/', 'sub/path?query=value', 'https://example.com:8000/path/sub/path?query=value'],
'relative-path on non-folder' => ['https://example.com:8000/path/foo', 'sub/path?query=value', 'https://example.com:8000/path/sub/path?query=value'],
'relative-path moving up' => ['https://example.com:8000/path/', '../other?query=value', 'https://example.com:8000/other?query=value'],
'relative-path with ./' => ['https://example.com:8000/path/', './other?query=value', 'https://example.com:8000/path/other?query=value'],
'relative-path with //' => ['https://example.com:8000/path/', 'other//sub?query=value', 'https://example.com:8000/path/other//sub?query=value'],
'relative-path redirect with only query' => ['https://example.com:8000/path', '?query=value', 'https://example.com:8000/path?query=value'],
];
}
/**
* @dataProvider provideRedirections
*/
public function testTargetUriMappingFromLocationHeader(string $originalUri, string $locationUri, string $targetUri): void
{
$response = (new RedirectPlugin())->handleRequest(
new Request('GET', $originalUri),
function () use ($locationUri) {
return new FulfilledPromise(new Response(302, ['Location' => $locationUri]));
},
function (RequestInterface $request) {
return new FulfilledPromise(new Response(200, ['uri' => $request->getUri()->__toString()]));
}
)->wait();
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertSame($targetUri, $response->getHeaderLine('uri'));
}
}