Passed
Pull Request — master (#23)
by Ingo
03:28
created

CachingPolicyTest::getVaryAsArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace SilverStripe\ControllerPolicy\Tests;
4
5
use SilverStripe\Control\Director;
6
use SilverStripe\Control\HTTP;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
9
use SilverStripe\Control\Session;
10
use SilverStripe\ControllerPolicy\ControllerPolicyMiddleware;
11
use SilverStripe\ControllerPolicy\Policies\CachingPolicy;
12
use SilverStripe\ControllerPolicy\Tests\CachingPolicyTest\CachingPolicyController;
13
use SilverStripe\ControllerPolicy\Tests\CachingPolicyTest\CallbackCachingPolicyController;
14
use SilverStripe\ControllerPolicy\Tests\CachingPolicyTest\UnrelatedController;
15
use SilverStripe\Core\Config\Config;
16
use SilverStripe\Core\Injector\Injector;
17
use SilverStripe\Dev\FunctionalTest;
18
19
class CachingPolicyTest extends FunctionalTest
20
{
21
    protected static $extra_controllers = [
22
        CachingPolicyController::class,
23
        CallbackCachingPolicyController::class,
24
        UnrelatedController::class,
25
    ];
26
27
    private $configCachingPolicy = [
28
        CachingPolicy::class => [
29
            'class' => CachingPolicy::class,
30
            'properties' => [
31
                'cacheAge' => '999',
32
                'vary' => 'X-EyeColour',
33
            ],
34
        ],
35
    ];
36
37
    protected function setUp()
38
    {
39
        parent::setUp();
40
41
        Config::modify()->set(CachingPolicy::class, 'disable_cache_age_in_dev', false);
42
43
        // Set to disabled at null forcing level, overrides dev mode defaults
44
        HTTPCacheControlMiddleware::config()
45
            ->set('defaultState', 'disabled')
46
            ->set('defaultForcingLevel', 0);
47
        HTTPCacheControlMiddleware::reset();
48
    }
49
50
    /**
51
     * Remove any policies from the middleware, since it's assigned to the Director singleton and shared between
52
     * tests.
53
     */
54
    protected function tearDown()
55
    {
56
        foreach (Director::singleton()->getMiddlewares() as $middleware) {
57
            if ($middleware instanceof ControllerPolicyMiddleware) {
58
                $middleware->clearPolicies();
59
            }
60
        }
61
62
        parent::tearDown();
63
    }
64
65
    protected function makeRequest($config, $controller, $url)
0 ignored issues
show
Unused Code introduced by
The parameter $url is not used and could be removed. ( Ignorable by Annotation )

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

65
    protected function makeRequest($config, $controller, /** @scrutinizer ignore-unused */ $url)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
66
    {
67
        Injector::inst()->load($config);
68
69
        $middleware = Injector::inst()->create(ControllerPolicyMiddleware::class);
70
71
        // Exercise the controller.
72
        $controller = Injector::inst()->create($controller);
73
        $controller->setMiddleware($middleware);
74
        $controller->doInit();
75
76
        $request = new HTTPRequest('GET', $controller->Link('test'));
77
        $request->setSession(new Session([]));
78
        $response = Director::singleton()->handleRequest($request);
79
80
        return $response;
81
    }
82
83
    public function testConfigured()
84
    {
85
        $response = $this->makeRequest(
86
            $this->configCachingPolicy,
87
            CachingPolicyController::class,
88
            'CachingPolicyController/test'
89
        );
90
91
        $directives = explode(',', $response->getHeader('Cache-Control'));
92
        $directives = array_map('trim', $directives);
93
94
        $this->assertCount(2, $directives);
95
        $this->assertContains('max-age=999', $directives);
96
        $this->assertContains('must-revalidate', $directives);
97
98
        $vary = $this->getVaryAsArray($response->getHeader('Vary'));
99
        $this->assertArraySubset(
100
            array_keys(HTTPCacheControlMiddleware::config()->get('defaultVary')),
101
            $vary,
102
            'Retains default Vary'
0 ignored issues
show
Bug introduced by
'Retains default Vary' of type string is incompatible with the type boolean expected by parameter $strict of PHPUnit_Framework_Assert::assertArraySubset(). ( Ignorable by Annotation )

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

102
            /** @scrutinizer ignore-type */ 'Retains default Vary'
Loading history...
103
        );
104
        $this->assertContains('X-EyeColour', $vary, 'Adds custom vary');
105
    }
106
107
    public function testCallbackOverride()
108
    {
109
        $response = $this->makeRequest(
110
            $this->configCachingPolicy,
111
            CallbackCachingPolicyController::class,
112
            'CallbackCachingPolicyController/test'
113
        );
114
115
        $directives = explode(',', $response->getHeader('Cache-Control'));
116
        $directives = array_map('trim', $directives);
117
118
        $this->assertCount(2, $directives);
119
        $this->assertContains('max-age=1001', $directives);
120
        $this->assertContains('must-revalidate', $directives);
121
122
        $vary = $this->getVaryAsArray($response->getHeader('Vary'));
123
        $this->assertContains('X-HeightWeight', $vary, 'Controller\'s getVary() overrides the configuration');
124
        $this->assertNotContains('X-EyeColour', $vary);
125
126
        $this->assertEquals(
127
            HTTP::gmt_date('5000'),
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Control\HTTP::gmt_date() has been deprecated: 4.2..5.0 Inline if you need this ( Ignorable by Annotation )

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

127
            /** @scrutinizer ignore-deprecated */ HTTP::gmt_date('5000'),

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
128
            $response->getHeader('Last-Modified'),
129
            'Controller\'s getModificationTimestamp overrides the HTTP::$modification_date'
130
        );
131
    }
132
133
    public function testUnrelated()
134
    {
135
        $response = $this->makeRequest(
136
            $this->configCachingPolicy,
137
            UnrelatedController::class,
138
            'UnrelatedController/test'
139
        );
140
141
        $defaultVary = array_keys(HTTPCacheControlMiddleware::config()->get('defaultVary'));
142
        $vary = $this->getVaryAsArray($response->getHeader('Vary'));
143
        $this->assertEquals($vary, $defaultVary, 'Headers on unrelated controller are unaffected');
144
    }
145
146
    /**
147
     * @param string $varyStr
148
     * @return array
149
     */
150
    protected function getVaryAsArray($varyStr)
151
    {
152
        return array_filter(preg_split("/\s*,\s*/", trim($varyStr)));
0 ignored issues
show
Bug introduced by
It seems like preg_split('/\s*,\s*/', trim($varyStr)) can also be of type false; however, parameter $input of array_filter() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

152
        return array_filter(/** @scrutinizer ignore-type */ preg_split("/\s*,\s*/", trim($varyStr)));
Loading history...
153
    }
154
}
155