ApiLoaderTest::getMockClient()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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