Completed
Pull Request — master (#175)
by
unknown
01:58
created

SapiEmitterTest::createEmitter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Yiisoft\Yii\Web\Emitter;
4
5
use Yiisoft\Yii\Web\Tests\Emitter\HTTPFunctions;
6
7
/**
8
 * Mock for the headers_sent() function for Emitter class.
9
 */
10
function headers_sent(): bool
11
{
12
    return false;
13
}
14
/**
15
 * Mock for the header() function for Emitter class.
16
 */
17
function header(string $string, bool $replace = true, ?int $http_response_code = null): void
18
{
19
    HTTPFunctions::header($string, $replace, $http_response_code);
20
}
21
/**
22
 * Mock for the header_remove() function for Emitter class.
23
 */
24
function header_remove(): void
25
{
26
    HTTPFunctions::header_remove();
27
}
28
/**
29
 * Mock for the header_list() function for Emitter class.
30
 */
31
function header_list(): array
32
{
33
    return HTTPFunctions::headers_list();
34
}
35
/**
36
 * Mock for the http_response_code() function for Emitter class.
37
 */
38
function http_response_code(?int $response_code = null): int
39
{
40
    return HTTPFunctions::http_response_code($response_code);
41
}
42
43
namespace Yiisoft\Yii\Web\Tests\Emitter;
44
45
use Nyholm\Psr7\Response;
46
use PHPUnit\Framework\TestCase;
47
use Psr\Http\Message\ResponseInterface;
48
use Psr\Http\Message\StreamInterface;
49
use Yiisoft\Yii\Web\Emitter\SapiEmitter;
50
51
/**
52
 * @runTestsInSeparateProcesses
53
 */
54
class SapiEmitterTest extends TestCase
55
{
56
    public function setUp(): void
57
    {
58
        HTTPFunctions::reset();
59
    }
60
61
    public function tearDown(): void
62
    {
63
        HTTPFunctions::reset();
64
    }
65
66
    public function testHTTPFunctions(): void
67
    {
68
        // check default code 200
69
        $this->checkResponseCodeEquals(200);
70
        $this->assertFalse(HTTPFunctions::hasHeader('x-test'));
71
        // add header
72
        HTTPFunctions::header('X-Test: 1');
73
        $this->assertTrue(HTTPFunctions::hasHeader('x-test'));
74
        // added header, change status
75
        HTTPFunctions::header('X-Test: 2', false, 300);
76
        $this->checkHeadersEquals(['X-Test: 1', 'X-Test: 2']);
77
        $this->checkResponseCodeEquals(300);
78
        // replace x-test headers, change status
79
        HTTPFunctions::header('X-Test: 3', true, 404);
80
        HTTPFunctions::header('Control-Cache: no-cache');
81
        $this->checkHeadersEquals(['X-Test: 3', 'Control-Cache: no-cache']);
82
        $this->checkResponseCodeEquals(404);
83
        // remove x-test header
84
        HTTPFunctions::header_remove('x-test');
85
        $this->checkHeadersEquals(['Control-Cache: no-cache']);
86
        // remove all headers and check code
87
        HTTPFunctions::header_remove();
88
        $this->checkResponseCodeEquals(404);
89
        $this->checkHeadersEquals([]);
90
        // check defaults after reset
91
        HTTPFunctions::header('X-Test: 3', true, 404);
92
        HTTPFunctions::reset();
93
        $this->checkResponseCodeEquals(200);
94
        $this->checkHeadersEquals([]);
95
    }
96
97
    public function testEmit(): void
98
    {
99
        $body = 'Example body';
100
        $response = $this->createResponse(200, ['X-Test' => 1], $body);
101
102
        $this->createEmitter()->emit($response);
103
104
        $this->checkResponseCodeEquals(200);
105
        $this->checkHeadersEquals([
106
            'X-Test: 1',
107
            'Content-Length: ' . strlen($body),
108
        ]);
109
        $this->expectOutputString($body);
110
    }
111
112
    /**
113
     * @test
114
    //  */
115
    public function shouldNotOutputBodyWhenResponseCodeIs204(): void
116
    {
117
        $response = $this->createResponse(204, ['X-Test' => 1], 'Example body');
118
119
        $this->createEmitter()->emit($response);
120
121
        $this->checkResponseCodeEquals(204);
122
        $this->assertTrue(HTTPFunctions::hasHeader('X-Test'));
123
        $this->assertFalse(HTTPFunctions::hasHeader('Content-Length'));
124
        $this->expectOutputString('');
125
    }
126
127
    /**
128
     * @test
129
     */
130
    public function shouldNotOutputBodyAndContentLengthIfEmitToldSo(): void
131
    {
132
        $response = $this->createResponse(200, ['X-Test' => 1], 'Example body');
133
134
        $this->createEmitter()->emit($response, true);
135
136
        $this->checkResponseCodeEquals(200);
137
        $this->assertTrue(HTTPFunctions::hasHeader('X-Test'));
138
        $this->assertFalse(HTTPFunctions::hasHeader('Content-Length'));
139
        $this->expectOutputString('');
140
    }
141
142
    /**
143
     * @test
144
     */
145
    public function contentLengthShouldNotBeOverwrittenIfPresent(): void
146
    {
147
        $length = 100;
148
        $response = $this->createResponse(200, ['Content-Length' => $length, 'X-Test' => 1], '');
149
150
        $this->createEmitter()->emit($response);
151
152
        $this->checkResponseCodeEquals(200);
153
        $this->checkHeadersEquals([
154
            'X-Test: 1',
155
            'Content-Length: ' . $length,
156
        ]);
157
        $this->expectOutputString('');
158
    }
159
160
    /**
161
     * @test
162
     */
163
    public function contentAlwaysShouldBeFullyEmitted(): void
164
    {
165
        $body = 'Example body';
166
        $response = $this->createResponse(200, ['Content-length' => 1, 'X-Test' => 1], $body);
167
168
        $this->createEmitter()->emit($response);
169
170
        $this->expectOutputString($body);
171
    }
172
173
    private function createEmitter(?int $bufferSize = null): SapiEmitter
174
    {
175
        return new SapiEmitter($bufferSize);
176
    }
177
178
    private function createResponse(
179
        int $status = 200,
180
        array $headers = [],
181
        $body = null,
182
        string $version = '1.1'
183
    ): ResponseInterface {
184
        $response = (new Response())
185
            ->withStatus($status)
186
            ->withProtocolVersion($version);
187
        foreach ($headers as $header => $value) {
188
            $response = $response->withHeader($header, $value);
189
        }
190
        if ($body instanceof StreamInterface) {
191
            $response = $response->withBody($body);
192
        } elseif (is_string($body)) {
193
            $response->getBody()->write($body);
194
        }
195
        return $response;
196
    }
197
198
    private function checkHeadersEquals(array $expected): void
199
    {
200
        $actual = HTTPFunctions::headers_list();
201
        sort($expected, SORT_STRING);
202
        sort($actual, SORT_STRING);
203
        $this->assertEquals($expected, $actual);
204
    }
205
206
    private function checkResponseCodeEquals(int $expected): void
207
    {
208
        $this->assertEquals($expected, HTTPFunctions::http_response_code());
209
    }
210
}
211