Passed
Push — master ( 9013bb...125cf1 )
by Kirill
03:56
created

AcceptHeaderTest::compareProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 32
rs 9.584
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Pavel Z
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Tests\Http;
13
14
use PHPUnit\Framework\TestCase;
15
use Spiral\Http\Exception\AcceptHeaderException;
16
use Spiral\Http\Header\AcceptHeader;
17
use Spiral\Http\Header\AcceptHeaderItem;
18
19
class AcceptHeaderTest extends TestCase
20
{
21
    public function testEmpty(): void
22
    {
23
        $header = new AcceptHeader([
24
            AcceptHeaderItem::fromString(''),
25
            new AcceptHeaderItem(''),
26
            (new AcceptHeaderItem('*/*'))->withValue('')
27
        ]);
28
29
        $this->assertCount(0, $header->getAll());
30
        $this->assertSame('', (string)$header);
31
    }
32
33
    public function testHeaderSanitize(): void
34
    {
35
        $headers = AcceptHeader::fromString('text/*, text/html, ,;,text/html;level=1, */*')->getAll();
36
37
        $this->assertCount(3, $headers);
38
        $this->assertSame('text/html', $headers[0]->getValue());
39
        $this->assertSame('text/*', $headers[1]->getValue());
40
        $this->assertSame('*/*', $headers[2]->getValue());
41
    }
42
43
    public function testHeaderConstructingTypeError(): void
44
    {
45
        $this->expectException(AcceptHeaderException::class);
46
47
        new AcceptHeader(['*', 'UTF-8', ['text/html;level=1']]);
48
    }
49
50
    public function testImmutability(): void
51
    {
52
        $firstItem = AcceptHeaderItem::fromString('*/*;q=1');
53
        $secondItem = AcceptHeaderItem::fromString('text/*;q=0.9');
54
        $header = new AcceptHeader([$firstItem]);
55
        $firstItem->withValue('text/html');
56
57
        $this->assertSame('*/*', $header->add($secondItem)->getAll()[0]->getValue());
58
    }
59
60
    /**
61
     * @dataProvider sameQualityCompareProvider
62
     * @param string $input
63
     * @param string $a
64
     * @param string $b
65
     */
66
    public function testCompareWithEqualQuality(string $input, string $a, string $b): void
67
    {
68
        $headers = AcceptHeader::fromString($input)->getAll();
69
70
        $this->assertCount(2, $headers);
71
        $this->assertEquals($a, $headers[0]->getValue());
72
        $this->assertEquals($b, $headers[1]->getValue());
73
    }
74
75
    /**
76
     * @return iterable
77
     */
78
    public function sameQualityCompareProvider(): iterable
79
    {
80
        return [
81
            ['text/css;q=0.3, text/html;q=0.3', 'text/css', 'text/html'],
82
            ['text/html;q=0.3, text/css;q=0.3', 'text/html', 'text/css'],
83
            ['text/html;q=1, text/css', 'text/html', 'text/css'],
84
            ['text/html, text/css;q=1', 'text/html', 'text/css'],
85
        ];
86
    }
87
88
    public function testDuplicatedItems(): void
89
    {
90
        $header = AcceptHeader::fromString('*/*;q=0.9,text/html,*/*');
91
        $this->assertSame('text/html, */*', (string)$header);
92
93
        $header = AcceptHeader::fromString('text/html;q=0.4,*/*;q=0.9,text/html;q=0.6');
94
        $this->assertSame('*/*; q=0.9, text/html; q=0.6', (string)$header);
95
    }
96
97
    public function testAccessor(): void
98
    {
99
        $acceptHeader = AcceptHeader::fromString('text/css;q=0.3, text/html;q=0.3');
100
        $this->assertTrue($acceptHeader->has('tExt/css '));
101
        $this->assertFalse($acceptHeader->has('tExt/javascript'));
102
103
        $this->assertSame('text/css; q=0.3', (string)$acceptHeader->get('text/css'));
104
        $this->assertSame('text/html; q=0.3', (string)$acceptHeader->get('text/html'));
105
    }
106
107
    /**
108
     * @dataProvider addAndSortProvider
109
     * @param string $items
110
     * @param string $item
111
     * @param array  $expected
112
     */
113
    public function testAddAndSort(string $items, string $item, array $expected): void
114
    {
115
        $acceptHeader = AcceptHeader::fromString($items);
116
        $acceptHeader = $acceptHeader->add($item);
117
118
        $headers = $acceptHeader->getAll();
119
        $this->assertCount(count($expected), $headers);
120
121
        foreach ($expected as $i => $value) {
122
            $this->assertSame($value, $headers[$i]->getValue());
123
        }
124
    }
125
126
    /**
127
     * @return iterable
128
     */
129
    public function addAndSortProvider(): iterable
130
    {
131
        return [
132
            [
133
                'text/css;q=0.3,text/html;q=0.4',
134
                '',
135
                ['text/html', 'text/css']
136
            ],
137
            [
138
                'text/css;q=0.3,text/html;q=0.4',
139
                'text/javascript;q=0.35',
140
                ['text/html', 'text/javascript', 'text/css']
141
            ],
142
            [
143
                'text/css;q=0.3,text/html;q=0.4',
144
                'text/javascript;q=0.5',
145
                ['text/javascript', 'text/html', 'text/css']
146
            ],
147
            [
148
                'text/css;q=0.3,text/html;q=0.4',
149
                'text/javascript;q=.25',
150
                ['text/html', 'text/css', 'text/javascript']
151
            ],
152
        ];
153
    }
154
155
    /**
156
     * @dataProvider compareProvider
157
     * @param string $items
158
     * @param array  $expected
159
     */
160
    public function testCompare(string $items, array $expected): void
161
    {
162
        $acceptHeader = AcceptHeader::fromString($items);
163
164
        $headers = $acceptHeader->getAll();
165
        $this->assertCount(count($expected), $headers);
166
167
        foreach ($expected as $i => $value) {
168
            $this->assertSame($value, (string)$headers[$i]);
169
        }
170
    }
171
172
    /**
173
     * @return iterable
174
     */
175
    public function compareProvider(): iterable
176
    {
177
        return [
178
            //quality based
179
            ['text/html;q=0.8, text/css;q=0.9', ['text/css; q=0.9', 'text/html; q=0.8']],
180
            ['text/*;q=0.9, text/css;q=0.8;a=b;c=d', ['text/*; q=0.9', 'text/css; q=0.8; a=b; c=d']],
181
            ['text/html;q=1, text/*;', ['text/html', 'text/*']],
182
            ['text/html, text/css;q=1', ['text/html', 'text/css']],
183
184
            //.../subType based
185
            ['text/html, text/css', ['text/html', 'text/css']],
186
            ['text/css, text/html', ['text/css', 'text/html']],
187
            ['text/*, text/html', ['text/html', 'text/*']],
188
            ['text/html, text/*', ['text/html', 'text/*']],
189
190
            //type/... based
191
            ['text/html, */css', ['text/html', '*/css']],
192
            ['*/css,text/html', ['text/html', '*/css']],
193
194
            //value based
195
            ['text/*, text', ['text/*', 'text']],
196
            ['text, */*', ['text', '*/*']],
197
            ['text, *', ['text', '*']],
198
            ['*/*, text', ['text', '*/*']],
199
            ['*, text', ['text', '*']],
200
            ['*, */*', ['*', '*/*']],
201
            ['*/*,*', ['*/*', '*']],
202
            ['*,*', ['*']],
203
204
            //params count based
205
            ['text-html, text-css;a=b;c=d', ['text-css; a=b; c=d', 'text-html']],
206
            ['text-html;a=b;c=d;e=f, text-css;a=b;c=d', ['text-html; a=b; c=d; e=f', 'text-css; a=b; c=d']],
207
        ];
208
    }
209
}
210