DetectLocaleMiddlewareTest   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Importance

Changes 7
Bugs 2 Features 0
Metric Value
eloc 88
c 7
b 2
f 0
dl 0
loc 213
rs 10
wmc 12

10 Methods

Rating   Name   Duplication   Size   Complexity  
A testGetLocalePriority() 0 15 3
A localePriorityProvider() 0 13 1
A testLocaleIsPersistedFromSession() 0 18 1
A testLocaleIsPersistedFromCookie() 0 18 1
A testLocaleIsOnlyPersistedWhenSet() 0 16 1
A testLocaleIsNotPersistedFromSessionWhenSessionIsNotStarted() 0 18 1
A testGetPersistKey() 0 8 1
A testLocaleIsAlwaysPersistedEvenIfNotSetByTheMiddleware() 0 16 1
A setUp() 0 17 1
A testLocaleIsNotPersistedFromCookieWhenPersistCookieFalse() 0 5 1
1
<?php
2
3
namespace TractorCow\Fluent\Tests\Middleware;
4
5
use PHPUnit_Framework_MockObject_MockObject;
0 ignored issues
show
Bug introduced by
The type PHPUnit_Framework_MockObject_MockObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Control\Controller;
7
use SilverStripe\Control\Cookie;
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Control\Session;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Dev\SapphireTest;
12
use TractorCow\Fluent\Extension\FluentDirectorExtension;
13
use TractorCow\Fluent\Middleware\DetectLocaleMiddleware;
14
use TractorCow\Fluent\Model\Domain;
15
use TractorCow\Fluent\Model\Locale;
16
use TractorCow\Fluent\State\FluentState;
17
18
class DetectLocaleMiddlewareTest extends SapphireTest
19
{
20
    protected static $fixture_file = 'DetectLocaleMiddlewareTest.yml';
21
22
    /**
23
     * @var Stub\DetectLocaleMiddlewareSpy
24
     */
25
    protected $middleware;
26
27
    /**
28
     * @var string
29
     */
30
    protected $globalDefaultLocale;
31
32
    protected function setUp(): void
33
    {
34
        parent::setUp();
35
        $this->middleware = new Stub\DetectLocaleMiddlewareSpy;
36
37
        Config::modify()->set(FluentDirectorExtension::class, 'query_param', 'l');
38
39
        // Enable localedetection
40
        FluentDirectorExtension::config()->set('detect_locale', true);
41
42
        // Clear cache
43
        Locale::clearCached();
44
        Domain::clearCached();
45
46
        // Get defaults from fixture
47
        // Note: es_ES
48
        $this->globalDefaultLocale = Locale::get()->find('IsGlobalDefault', 1)->Locale;
49
    }
50
51
    public function testGetPersistKey()
52
    {
53
        FluentState::singleton()->withState(function (FluentState $newState) {
54
            $newState->setIsFrontend(true);
55
            $this->assertSame('FluentLocale', $this->middleware->getPersistKey());
56
57
            $newState->setIsFrontend(false);
58
            $this->assertSame('FluentLocale_CMS', $this->middleware->getPersistKey());
59
        });
60
    }
61
62
    /**
63
     * @dataProvider localePriorityProvider
64
     * @param string $url
65
     * @param array  $routeParams
66
     * @param array  $queryParams
67
     * @param bool   $persisted
68
     * @param string $header
69
     * @param string $expected
70
     */
71
    public function testGetLocalePriority($url, $routeParams, $queryParams, $persisted, $header, $expected)
72
    {
73
        $request = new HTTPRequest('GET', $url, $queryParams);
74
        $request->setRouteParams($routeParams);
75
        $request->setSession(Controller::curr()->getRequest()->getSession());
76
        $this->middleware->setPersistLocale($request, null);
77
78
        if ($persisted) {
79
            $this->middleware->setPersistLocale($request, $persisted);
80
        }
81
        if ($header) {
82
            $request->addHeader('Accept-Language', $header);
83
        }
84
85
        $this->assertSame($expected, $this->middleware->getLocale($request));
86
    }
87
88
    /**
89
     * @return array[] List of tests with arguments: $url, $routeParams, $queryParams, $persisted, $header, $expected
90
     */
91
    public function localePriorityProvider()
92
    {
93
        return [/*
94
            // First priority: controller routing params
95
            ['/nz/foo', ['l' => 'en_NZ'], ['l' => 'en_AU'], 'fr_FR', 'es-US', 'en_NZ'],
96
            // Second priority: request params
97
            ['/foo', [], ['l' => 'en_AU'], 'fr_FR', 'es-US', 'en_AU'],
98
            // Third priority: persisted locale
99
            ['/foo', [], [], 'fr_FR', 'es-US', 'fr_FR'],
100
            // Default to the default locale when not on the homepage
101
            ['/foo', [], [], null, 'es-US', 'es_ES'],*/
102
            // Home page only - fourth priority is request header
103
            ['/', [], [], null, 'es-US', 'es_US'],
104
        ];
105
    }
106
107
    public function testLocaleIsAlwaysPersistedEvenIfNotSetByTheMiddleware()
108
    {
109
        FluentState::singleton()->withState(function (FluentState $newState) {
110
            $request = new HTTPRequest('GET', '/');
111
            $newState->setIsFrontend(true);
112
            $newState->setLocale('en_AU');
113
114
            /** @var DetectLocaleMiddleware|PHPUnit_Framework_MockObject_MockObject $middleware */
115
            $middleware = $this->getMockBuilder(DetectLocaleMiddleware::class)
116
                ->setMethods(['getLocale', 'setPersistLocale'])
117
                ->getMock();
118
119
            $middleware->expects($this->never())->method('getLocale');
0 ignored issues
show
introduced by
The method expects() does not exist on TractorCow\Fluent\Middle...\DetectLocaleMiddleware. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

119
            $middleware->/** @scrutinizer ignore-call */ 
120
                         expects($this->never())->method('getLocale');
Loading history...
120
            $middleware->expects($this->once())->method('setPersistLocale')->with($request, 'en_AU');
121
122
            $middleware->process($request, function () {
123
                // no-op
124
            });
125
        });
126
    }
127
128
    public function testLocaleIsOnlyPersistedWhenSet()
129
    {
130
        $request = new HTTPRequest('GET', '/');
131
        FluentState::singleton()
132
            ->setLocale(null)
133
            ->setIsFrontend(true);
134
135
        /** @var DetectLocaleMiddleware|PHPUnit_Framework_MockObject_MockObject $middleware */
136
        $middleware = $this->getMockBuilder(DetectLocaleMiddleware::class)
137
            ->setMethods(['getLocale', 'setPersistLocale'])
138
            ->getMock();
139
140
        $middleware->expects($this->once())->method('getLocale')->willReturn(null);
141
        $middleware->expects($this->never())->method('setPersistLocale');
142
143
        $middleware->process($request, function () {
144
            // no-op
145
        });
146
    }
147
148
    public function testLocaleIsPersistedFromCookie()
149
    {
150
        $newLocale = 'fr_FR';
151
        $middleware = $this->middleware;
152
        $key = $middleware->getPersistKey();
153
        $request = new HTTPRequest('GET', '/');
154
155
        $sessionData = [];
156
        $sessionMock = $this->getMockBuilder(Session::class)
157
            ->setMethods(['set', 'getAll'])
158
            ->setConstructorArgs([$sessionData])
159
            ->getMock();
160
        $sessionMock->expects($this->once())->method('set')->with($key, $newLocale);
161
        $sessionMock->expects($this->once())->method('getAll')->willReturn([true]);
162
        $request->setSession($sessionMock);
163
164
        Cookie::set($key, $newLocale);
165
        $middleware->process($request, function () {
166
            // no-op
167
        });
168
169
        // TODO PHPUnit's headers_sent() always returns true, so we can't check for cookie values.
170
        // PHPUnit has process isolation for this purpose, but we can't use it because autoloading breaks.
171
        // $this->assertEquals($newLocale, Cookie::get($key));
172
    }
173
174
    public function testLocaleIsPersistedFromSession()
175
    {
176
        $newLocale = 'fr_FR';
177
        $middleware = $this->middleware;
178
        $key = $middleware->getPersistKey();
179
        $request = new HTTPRequest('GET', '/');
180
181
        $sessionData = [$key => $newLocale];
182
        $sessionMock = $this->getMockBuilder(Session::class)
183
            ->setMethods(['set', 'isStarted'])
184
            ->setConstructorArgs([$sessionData])
185
            ->getMock();
186
187
        $sessionMock->expects($this->any())->method('isStarted')->willReturn(true);
188
        $sessionMock->expects($this->once())->method('set')->with($key, $newLocale);
189
        $request->setSession($sessionMock);
190
191
        $middleware->process($request, function () {
192
            // no-op
193
        });
194
195
        // TODO PHPUnit's headers_sent() always returns true, so we can't check for cookie values.
196
        // PHPUnit has process isolation for this purpose, but we can't use it because autoloading breaks.
197
        // $this->assertEquals($newLocale, Cookie::get($key));
198
    }
199
200
    public function testLocaleIsNotPersistedFromSessionWhenSessionIsNotStarted()
201
    {
202
        $newLocale = 'fr_FR';
203
        $middleware = $this->middleware;
204
        $key = $middleware->getPersistKey();
205
        $request = new HTTPRequest('GET', '/');
206
207
        $sessionData = [$key => $newLocale];
208
        $sessionMock = $this->getMockBuilder(Session::class)
209
            ->setMethods(['set', 'isStarted'])
210
            ->setConstructorArgs([$sessionData])
211
            ->getMock();
212
213
        $sessionMock->expects($this->any())->method('isStarted')->willReturn(false);
214
        $sessionMock->expects($this->never())->method('set');
215
        $request->setSession($sessionMock);
216
217
        $middleware->process($request, function () {
218
            // no-op
219
        });
220
221
        // TODO PHPUnit's headers_sent() always returns true, so we can't check for cookie values.
222
        // PHPUnit has process isolation for this purpose, but we can't use it because autoloading breaks.
223
        // $this->assertEquals($this->globalDefaultLocale, Cookie::get($key));
224
    }
225
226
    public function testLocaleIsNotPersistedFromCookieWhenPersistCookieFalse()
227
    {
228
        // TODO PHPUnit's headers_sent() always returns true, so we can't check for cookie values.
229
        // PHPUnit has process isolation for this purpose, but we can't use it because autoloading breaks.
230
        $this->markTestIncomplete();
231
232
        // $newLocale = 'fr_FR';
233
        // $middleware = $this->middleware;
234
        // $middleware->config()->update('persist_cookie', false);
235
        // $key = $this->middleware->getPersistKey();
236
        // $request = new HTTPRequest('GET', '/');
237
        //
238
        // $sessionData = [$key => $newLocale];
239
        // $sessionMock = $this->getMockBuilder(Session::class)
240
        //     ->setMethods(['set'])
241
        //     ->setConstructorArgs([$sessionData])
242
        //     ->getMock();
243
        // $sessionMock->expects($this->once())->method('set')->with($key, $this->globalDefaultLocale);
244
        // $request->setSession($sessionMock);
245
        //
246
        // $middleware->process($request, function () {
247
        //     // no-op
248
        // });
249
        //
250
        // $this->assertEquals($this->globalDefaultLocale, Cookie::get($key));
251
    }
252
}
253