Completed
Push — master ( 47b9ab...741c62 )
by Thomas Mauro
01:54
created

LinkHandlerTest::testInvokeWithPush()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 23
nc 1
nop 0
1
<?php
2
3
namespace Facile\ZFLinkHeadersModule\Listener;
4
5
use Facile\ZFLinkHeadersModule\OptionsInterface;
6
use PHPUnit\Framework\TestCase;
7
use Prophecy\Argument;
8
use Zend\Http\Header\GenericMultiHeader;
9
use Zend\Http\Headers;
10
use Zend\Http\PhpEnvironment;
11
use Zend\Http\Response;
12
use Zend\Mvc\MvcEvent;
13
use Zend\View\Helper\HeadLink;
14
use Zend\View\Helper\Placeholder\Container\AbstractContainer;
15
16
class LinkHandlerTest extends TestCase
17
{
18
    public function testInvokeWithAnotherResponse()
19
    {
20
        $headLink = $this->prophesize(HeadLink::class);
21
        $options = $this->prophesize(OptionsInterface::class);
22
        $event = $this->prophesize(MvcEvent::class);
23
        $response = $this->prophesize(Response::class);
24
25
        $headLink->getContainer()->shouldNotBeCalled();
26
        $response->getHeaders()->shouldNotBeCalled();
27
        $event->getResponse()->willReturn($response->reveal());
28
29
        $injector = new LinkHandler($headLink->reveal(), $options->reveal());
30
31
        $injector($event->reveal());
32
    }
33
34
    public function testInvokeWithNoPush()
35
    {
36
        $links = [
37
            $this->createStdClass([
38
                'rel' => OptionsInterface::MODE_PRELOAD,
39
                'href' => '/foo.css',
40
            ]),
41
            $this->createStdClass([
42
                'rel' => OptionsInterface::MODE_PREFETCH,
43
                'href' => '/bar.css',
44
                'as' => 'style',
45
                'crossorigin' => 'same-origin',
46
                'type' => 'text/style',
47
                'media' => '(min-width: 100px)',
48
                'nopush' => 'nopush',
49
            ]),
50
            $this->createStdClass([
51
                'rel' => OptionsInterface::MODE_DNS_PREFETCH,
52
                'href' => '/foo-dns-prefetch.css',
53
            ]),
54
            $this->createStdClass([
55
                'rel' => OptionsInterface::MODE_PRECONNECT,
56
                'href' => '/foo-preconnect.css',
57
            ]),
58
            $this->createStdClass([
59
                'rel' => OptionsInterface::MODE_PRERENDER,
60
                'href' => '/foo-prerender.css',
61
            ]),
62
        ];
63
64
        $headLink = $this->prophesize(HeadLink::class);
65
        $options = $this->prophesize(OptionsInterface::class);
66
        $event = $this->prophesize(MvcEvent::class);
67
        $responseHeaders = $this->prophesize(Headers::class);
68
        $headContainer = $this->prophesize(AbstractContainer::class);
69
        $response = $this->prophesize(PhpEnvironment\Response::class);
70
71
        $options->isHttp2PushEnabled()->willReturn(false);
72
73
        $headContainer->getIterator()->willReturn(new \ArrayIterator($links));
74
75
        $headLink->getContainer()->willReturn($headContainer->reveal());
76
        $response->getHeaders()->willReturn($responseHeaders->reveal());
77
        $event->getResponse()->willReturn($response->reveal());
78
79
        $responseHeaders->addHeader(Argument::allOf(
80
            Argument::type(GenericMultiHeader::class),
81
            Argument::which('getFieldName', 'Link'),
82
            Argument::which('getFieldValue', '</foo.css>; rel="preload"; nopush')
83
        ))
84
            ->shouldBeCalled();
85
        $responseHeaders->addHeader(Argument::allOf(
86
            Argument::type(GenericMultiHeader::class),
87
            Argument::which('getFieldName', 'Link'),
88
            Argument::which('getFieldValue', '</bar.css>; rel="prefetch"; as="style"; crossorigin="same-origin"; type="text/style"; media="(min-width: 100px)"; nopush')
89
        ))
90
            ->shouldBeCalled();
91
        $responseHeaders->addHeader(Argument::allOf(
92
            Argument::type(GenericMultiHeader::class),
93
            Argument::which('getFieldName', 'Link'),
94
            Argument::which('getFieldValue', '</foo-dns-prefetch.css>; rel="dns-prefetch"; nopush')
95
        ))
96
            ->shouldBeCalled();
97
        $responseHeaders->addHeader(Argument::allOf(
98
            Argument::type(GenericMultiHeader::class),
99
            Argument::which('getFieldName', 'Link'),
100
            Argument::which('getFieldValue', '</foo-preconnect.css>; rel="preconnect"; nopush')
101
        ))
102
            ->shouldBeCalled();
103
        $responseHeaders->addHeader(Argument::allOf(
104
            Argument::type(GenericMultiHeader::class),
105
            Argument::which('getFieldName', 'Link'),
106
            Argument::which('getFieldValue', '</foo-prerender.css>; rel="prerender"; nopush')
107
        ))
108
            ->shouldBeCalled();
109
110
        $injector = new LinkHandler($headLink->reveal(), $options->reveal());
111
112
        $injector($event->reveal());
113
    }
114
115
    public function testInvokeWithPush()
116
    {
117
        $links = [
118
            $this->createStdClass([
119
                'rel' => OptionsInterface::MODE_PRELOAD,
120
                'href' => '/foo.css',
121
            ]),
122
        ];
123
124
        $headLink = $this->prophesize(HeadLink::class);
125
        $options = $this->prophesize(OptionsInterface::class);
126
        $event = $this->prophesize(MvcEvent::class);
127
        $responseHeaders = $this->prophesize(Headers::class);
128
        $headContainer = $this->prophesize(AbstractContainer::class);
129
        $response = $this->prophesize(PhpEnvironment\Response::class);
130
131
        $options->isHttp2PushEnabled()->willReturn(true);
132
133
        $headContainer->getIterator()->willReturn(new \ArrayIterator($links));
134
135
        $headLink->getContainer()->willReturn($headContainer->reveal());
136
        $response->getHeaders()->willReturn($responseHeaders->reveal());
137
        $event->getResponse()->willReturn($response->reveal());
138
139
        $responseHeaders->addHeader(Argument::allOf(
140
            Argument::type(GenericMultiHeader::class),
141
            Argument::which('getFieldName', 'Link'),
142
            Argument::which('getFieldValue', '</foo.css>; rel="preload"')
143
        ))
144
            ->shouldBeCalled();
145
146
        $injector = new LinkHandler($headLink->reveal(), $options->reveal());
147
148
        $injector($event->reveal());
149
    }
150
151
    public function testInvokeWithNoRelAttribute()
152
    {
153
        $links = [
154
            $this->createStdClass([
155
                'rel' => OptionsInterface::MODE_PRELOAD,
156
                'href' => '/foo.css',
157
            ]),
158
            $this->createStdClass([
159
                'href' => '/bar.css',
160
            ]),
161
        ];
162
163
        $headLink = $this->prophesize(HeadLink::class);
164
        $options = $this->prophesize(OptionsInterface::class);
165
        $event = $this->prophesize(MvcEvent::class);
166
        $responseHeaders = $this->prophesize(Headers::class);
167
        $headContainer = $this->prophesize(AbstractContainer::class);
168
        $response = $this->prophesize(PhpEnvironment\Response::class);
169
170
        $options->isHttp2PushEnabled()->willReturn(true);
171
172
        $headContainer->getIterator()->willReturn(new \ArrayIterator($links));
173
174
        $headLink->getContainer()->willReturn($headContainer->reveal());
175
        $response->getHeaders()->willReturn($responseHeaders->reveal());
176
        $event->getResponse()->willReturn($response->reveal());
177
178
        $responseHeaders->addHeader(Argument::allOf(
179
            Argument::type(GenericMultiHeader::class),
180
            Argument::which('getFieldName', 'Link'),
181
            Argument::which('getFieldValue', '</foo.css>; rel="preload"')
182
        ))
183
            ->shouldBeCalled();
184
185
        $injector = new LinkHandler($headLink->reveal(), $options->reveal());
186
187
        $injector($event->reveal());
188
    }
189
190
    public function testInvokeWithNoHrefAttribute()
191
    {
192
        $links = [
193
            $this->createStdClass([
194
                'rel' => OptionsInterface::MODE_PRELOAD,
195
                'href' => '/foo.css',
196
            ]),
197
            $this->createStdClass([
198
                'rel' => OptionsInterface::MODE_PRELOAD,
199
            ]),
200
            $this->createStdClass([
201
                'rel' => 'stylesheet',
202
            ]),
203
        ];
204
205
        $headLink = $this->prophesize(HeadLink::class);
206
        $options = $this->prophesize(OptionsInterface::class);
207
        $event = $this->prophesize(MvcEvent::class);
208
        $responseHeaders = $this->prophesize(Headers::class);
209
        $headContainer = $this->prophesize(AbstractContainer::class);
210
        $response = $this->prophesize(PhpEnvironment\Response::class);
211
212
        $options->isHttp2PushEnabled()->willReturn(true);
213
214
        $headContainer->getIterator()->willReturn(new \ArrayIterator($links));
215
216
        $headLink->getContainer()->willReturn($headContainer->reveal());
217
        $response->getHeaders()->willReturn($responseHeaders->reveal());
218
        $event->getResponse()->willReturn($response->reveal());
219
220
        $responseHeaders->addHeader(Argument::allOf(
221
            Argument::type(GenericMultiHeader::class),
222
            Argument::which('getFieldName', 'Link'),
223
            Argument::which('getFieldValue', '</foo.css>; rel="preload"')
224
        ))
225
            ->shouldBeCalled();
226
227
        $injector = new LinkHandler($headLink->reveal(), $options->reveal());
228
229
        $injector($event->reveal());
230
    }
231
232
    /**
233
     * @param array $properties
234
     * @return \stdClass
235
     */
236
    private function createStdClass(array $properties): \stdClass
237
    {
238
        $item = new \stdClass();
239
240
        foreach ($properties as $name => $value) {
241
            $item->{$name} = $value;
242
        }
243
244
        return $item;
245
    }
246
}
247