CachingPolicyTest::makeRequest()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 16
rs 9.9666
cc 1
nc 1
nop 3
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('defaultForcingLevel', 0);
46
        HTTPCacheControlMiddleware::reset();
47
    }
48
49
    /**
50
     * Remove any policies from the middleware, since it's assigned to the Director singleton and shared between
51
     * tests.
52
     */
53
    protected function tearDown()
54
    {
55
        foreach (Director::singleton()->getMiddlewares() as $middleware) {
56
            if ($middleware instanceof ControllerPolicyMiddleware) {
57
                $middleware->clearPolicies();
58
            }
59
        }
60
61
        parent::tearDown();
62
    }
63
64
    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

64
    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...
65
    {
66
        Injector::inst()->load($config);
67
68
        $middleware = Injector::inst()->create(ControllerPolicyMiddleware::class);
69
70
        // Exercise the controller.
71
        $controller = Injector::inst()->create($controller);
72
        $controller->setMiddleware($middleware);
73
        $controller->doInit();
74
75
        $request = new HTTPRequest('GET', $controller->Link('test'));
76
        $request->setSession(new Session([]));
77
        $response = Director::singleton()->handleRequest($request);
78
79
        return $response;
80
    }
81
82
    public function testConfigured()
83
    {
84
        $response = $this->makeRequest(
85
            $this->configCachingPolicy,
86
            CachingPolicyController::class,
87
            'CachingPolicyController/test'
88
        );
89
90
        $directives = $this->getCsvAsArray($response->getHeader('Cache-Control'));
91
92
        $this->assertCount(2, $directives);
93
        $this->assertContains('max-age=999', $directives);
94
        $this->assertContains('must-revalidate', $directives);
95
96
        $vary = $this->getCsvAsArray($response->getHeader('Vary'));
97
        $this->assertArraySubset(
98
            array_keys(HTTPCacheControlMiddleware::config()->get('defaultVary')),
99
            $vary,
100
            '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

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

124
            /** @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...
125
            $response->getHeader('Last-Modified'),
126
            'Controller\'s getModificationTimestamp overrides the HTTP::$modification_date'
127
        );
128
    }
129
130
    public function testUnrelated()
131
    {
132
        $response = $this->makeRequest(
133
            $this->configCachingPolicy,
134
            UnrelatedController::class,
135
            'UnrelatedController/test'
136
        );
137
138
        $defaultVary = array_keys(HTTPCacheControlMiddleware::config()->get('defaultVary'));
139
        $vary = $this->getCsvAsArray($response->getHeader('Vary'));
140
        $this->assertEquals($vary, $defaultVary, 'Headers on unrelated controller are unaffected');
141
    }
142
143
    /**
144
     * @param string $str
145
     * @return array
146
     */
147
    protected function getCsvAsArray($str)
148
    {
149
        return array_filter(preg_split("/\s*,\s*/", trim($str)));
0 ignored issues
show
Bug introduced by
It seems like preg_split('/\s*,\s*/', trim($str)) 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

149
        return array_filter(/** @scrutinizer ignore-type */ preg_split("/\s*,\s*/", trim($str)));
Loading history...
150
    }
151
}
152