Passed
Push — master ( fcb909...cb681d )
by Robbie
02:26
created

ApiLoaderTest::getLoader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 1
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace BringYourOwnIdeas\Maintenance\Tests\Util;
4
5
use BringYourOwnIdeas\Maintenance\Util\ApiLoader;
6
use GuzzleHttp\Client;
7
use GuzzleHttp\Handler\MockHandler;
8
use GuzzleHttp\HandlerStack;
9
use GuzzleHttp\Psr7\Response;
10
use SilverStripe\Dev\SapphireTest;
11
use Symfony\Component\Cache\Simple\NullCache;
12
13
class ApiLoaderTest extends SapphireTest
14
{
15
    /**
16
     * @expectedException RuntimeException
17
     * @expectedExceptionMessage Could not obtain information about module. Error code 404
18
     */
19
    public function testNon200ErrorCodesAreHandled()
20
    {
21
        $loader = $this->getLoader();
22
        $loader->setGuzzleClient($this->getMockClient(new Response(404)));
23
24
        $loader->doRequest('foo', function () {
25
            // noop
26
        });
27
    }
28
29
    /**
30
     * @expectedException RuntimeException
31
     * @expectedExceptionMessage Could not obtain information about module. Response is not JSON
32
     */
33
    public function testNonJsonResponsesAreHandled()
34
    {
35
        $loader = $this->getLoader();
36
        $loader->setGuzzleClient($this->getMockClient(new Response(
37
            200,
38
            ['Content-Type' => 'text/html; charset=utf-8']
39
        )));
40
41
        $loader->doRequest('foo', function () {
42
            // noop
43
        });
44
    }
45
46
    /**
47
     * @expectedException RuntimeException
48
     * @expectedExceptionMessage Could not obtain information about module. Response returned unsuccessfully
49
     */
50
    public function testUnsuccessfulResponsesAreHandled()
51
    {
52
        $loader = $this->getLoader();
53
        $loader->setGuzzleClient($this->getMockClient(new Response(
54
            200,
55
            ['Content-Type' => 'application/json'],
56
            json_encode(['success' => false])
57
        )));
58
59
        $loader->doRequest('foo', function () {
60
            // noop
61
        });
62
    }
63
64
    /**
65
     * Note: contains some logic from SupportedAddonsLoader for context
66
     *
67
     * @group integration
68
     */
69
    public function testAddonsAreParsedAndReturnedCorrectly()
70
    {
71
        $fakeAddons = ['foo/bar', 'bin/baz'];
72
73
        $loader = $this->getLoader();
74
        $loader->setGuzzleClient($this->getMockClient(new Response(
75
            200,
76
            ['Content-Type' => 'application/json'],
77
            json_encode(['success' => true, 'addons' => $fakeAddons])
78
        )));
79
80
        $addons = $loader->doRequest('foo', function ($responseBody) {
81
            return $responseBody['addons'];
82
        });
83
84
        $this->assertSame($fakeAddons, $addons);
85
    }
86
87
    /**
88
     * Note: contains some logic from SupportedAddonsLoader for context
89
     *
90
     * @group integration
91
     */
92
    public function testCacheControlSettingsAreRespected()
93
    {
94
        $fakeAddons = ['foo/bar', 'bin/baz'];
95
96
        $cacheMock = $this->getMockBuilder(NullCache::class)
97
            ->setMethods(['get', 'set'])
98
            ->getMock();
99
100
        $cacheMock->expects($this->once())->method('get')->will($this->returnValue(false));
101
        $cacheMock->expects($this->once())
102
            ->method('set')
103
            ->with($this->anything(), json_encode($fakeAddons), 5000)
104
            ->will($this->returnValue(true));
105
106
        $loader = $this->getLoader($cacheMock);
107
        $loader->setGuzzleClient($this->getMockClient(new Response(
108
            200,
109
            ['Content-Type' => 'application/json', 'Cache-Control' => 'max-age=5000'],
110
            json_encode(['success' => true, 'addons' => $fakeAddons])
111
        )));
112
113
        $loader->doRequest('foo', function ($responseBody) {
114
            return $responseBody['addons'];
115
        });
116
    }
117
118
    public function testCachedAddonsAreUsedWhenAvailable()
119
    {
120
        $fakeAddons = ['foo/bar', 'bin/baz'];
121
122
        $cacheMock = $this->getMockBuilder(NullCache::class)
123
            ->setMethods(['get', 'set'])
124
            ->getMock();
125
126
        $cacheMock->expects($this->once())->method('get')->will($this->returnValue(json_encode($fakeAddons)));
127
        $loader = $this->getLoader($cacheMock);
128
129
        $mockClient = $this->getMockBuilder(Client::class)->setMethods(['send'])->getMock();
130
        $mockClient->expects($this->never())->method('send');
131
        $loader->setGuzzleClient($mockClient);
132
133
        $addons = $loader->doRequest('foo', function () {
134
            // noop
135
        });
136
137
        $this->assertSame($fakeAddons, $addons);
138
    }
139
140
    /**
141
     * @param Response $withResponse
142
     * @return Client
143
     */
144
    protected function getMockClient(Response $withResponse)
145
    {
146
        $mock = new MockHandler([
147
            $withResponse
148
        ]);
149
150
        $handler = HandlerStack::create($mock);
151
        return new Client(['handler' => $handler]);
152
    }
153
154
    /**
155
     * @param bool $cacheMock
156
     * @return ApiLoader
157
     */
158
    protected function getLoader($cacheMock = false)
159
    {
160
        if (!$cacheMock) {
161
            $cacheMock = $this->getMockBuilder(NullCache::class)
162
                ->setMethods(['get', 'set'])
163
                ->getMock();
164
165
            $cacheMock->expects($this->any())->method('get')->will($this->returnValue(false));
166
            $cacheMock->expects($this->any())->method('set')->will($this->returnValue(true));
167
        }
168
169
        $loader = $this->getMockBuilder(ApiLoader::class)
170
            ->getMockForAbstractClass();
171
172
        $loader->setCache($cacheMock);
173
174
        return $loader;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $loader returns the type PHPUnit_Framework_MockObject_MockObject which is incompatible with the documented return type BringYourOwnIdeas\Maintenance\Util\ApiLoader.
Loading history...
175
    }
176
}
177