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

ScriptHandlerTest::testInvokeWithNoPush()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 28
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\HeadScript;
14
use Zend\View\Helper\Placeholder\Container\AbstractContainer;
15
16
class ScriptHandlerTest extends TestCase
17
{
18
    public function testInvokeWithAnotherResponse()
19
    {
20
        $headScript = $this->prophesize(HeadScript::class);
21
        $options = $this->prophesize(OptionsInterface::class);
22
        $event = $this->prophesize(MvcEvent::class);
23
        $response = $this->prophesize(Response::class);
24
25
        $headScript->getContainer()->shouldNotBeCalled();
26
        $response->getHeaders()->shouldNotBeCalled();
27
        $event->getResponse()->willReturn($response->reveal());
28
        $options->isScriptEnabled()->willReturn(true);
29
30
        $injector = new ScriptHandler($headScript->reveal(), $options->reveal());
31
32
        $injector($event->reveal());
33
    }
34
35
    public function testInvokeWithDisabled()
36
    {
37
        $headScript = $this->prophesize(HeadScript::class);
38
        $options = $this->prophesize(OptionsInterface::class);
39
        $event = $this->prophesize(MvcEvent::class);
40
        $response = $this->prophesize(PhpEnvironment\Response::class);
41
42
        $headScript->getContainer()->shouldNotBeCalled();
43
        $response->getHeaders()->shouldNotBeCalled();
44
        $event->getResponse()->willReturn($response->reveal());
45
        $options->isScriptEnabled()->willReturn(false);
46
47
        $injector = new ScriptHandler($headScript->reveal(), $options->reveal());
48
49
        $injector($event->reveal());
50
    }
51
52
    public function testInvokeWithNoPush()
53
    {
54
        $links = [
55
            $this->createStdClass([
56
                'attributes' => [
57
                    'src' => '/foo.js',
58
                ],
59
            ]),
60
            $this->createStdClass([
61
                'content' => 'foo',
62
                'attributes' => [],
63
            ]),
64
        ];
65
66
        $headScript = $this->prophesize(HeadScript::class);
67
        $options = $this->prophesize(OptionsInterface::class);
68
        $event = $this->prophesize(MvcEvent::class);
69
        $responseHeaders = $this->prophesize(Headers::class);
70
        $headContainer = $this->prophesize(AbstractContainer::class);
71
        $response = $this->prophesize(PhpEnvironment\Response::class);
72
73
        $options->getScriptMode()->willReturn('preload');
74
        $options->isHttp2PushEnabled()->willReturn(false);
75
        $options->isScriptEnabled()->willReturn(true);
76
77
        $headContainer->getIterator()->willReturn(new \ArrayIterator($links));
78
79
        $headScript->getContainer()->willReturn($headContainer->reveal());
80
        $response->getHeaders()->willReturn($responseHeaders->reveal());
81
        $event->getResponse()->willReturn($response->reveal());
82
83
        $responseHeaders->addHeader(Argument::allOf(
84
            Argument::type(GenericMultiHeader::class),
85
            Argument::which('getFieldName', 'Link'),
86
            Argument::which('getFieldValue', '</foo.js>; rel="preload"; as="script"; nopush')
87
        ))
88
            ->shouldBeCalled();
89
90
        $injector = new ScriptHandler($headScript->reveal(), $options->reveal());
91
92
        $injector($event->reveal());
93
    }
94
95
    public function testInvokeWithPushAndPrefetch()
96
    {
97
        $links = [
98
            $this->createStdClass([
99
                'attributes' => [
100
                    'src' => '/foo.js',
101
                ],
102
            ]),
103
            $this->createStdClass([
104
                'content' => 'foo',
105
                'attributes' => [],
106
            ]),
107
        ];
108
109
        $headScript = $this->prophesize(HeadScript::class);
110
        $options = $this->prophesize(OptionsInterface::class);
111
        $event = $this->prophesize(MvcEvent::class);
112
        $responseHeaders = $this->prophesize(Headers::class);
113
        $headContainer = $this->prophesize(AbstractContainer::class);
114
        $response = $this->prophesize(PhpEnvironment\Response::class);
115
116
        $options->getScriptMode()->willReturn('prefetch');
117
        $options->isHttp2PushEnabled()->willReturn(true);
118
        $options->isScriptEnabled()->willReturn(true);
119
120
        $headContainer->getIterator()->willReturn(new \ArrayIterator($links));
121
122
        $headScript->getContainer()->willReturn($headContainer->reveal());
123
        $response->getHeaders()->willReturn($responseHeaders->reveal());
124
        $event->getResponse()->willReturn($response->reveal());
125
126
        $responseHeaders->addHeader(Argument::allOf(
127
            Argument::type(GenericMultiHeader::class),
128
            Argument::which('getFieldName', 'Link'),
129
            Argument::which('getFieldValue', '</foo.js>; rel="prefetch"; as="script"')
130
        ))
131
            ->shouldBeCalled();
132
133
        $injector = new ScriptHandler($headScript->reveal(), $options->reveal());
134
135
        $injector($event->reveal());
136
    }
137
138
    /**
139
     * @param array $properties
140
     * @return \stdClass
141
     */
142
    private function createStdClass(array $properties): \stdClass
143
    {
144
        $item = new \stdClass();
145
146
        foreach ($properties as $name => $value) {
147
            $item->{$name} = $value;
148
        }
149
150
        return $item;
151
    }
152
}
153