Passed
Pull Request — master (#105)
by
unknown
02:33
created

ApiLoaderTest::getMockClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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