Passed
Push — 4.1 ( 6d2665...02ad0f )
by
unknown
32:36 queued 24:09
created

URLConfirmationTokenTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 134
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 76
dl 0
loc 134
rs 10
c 0
b 0
f 0
wmc 12

10 Methods

Rating   Name   Duplication   Size   Complexity  
A testPrepareTokens() 0 14 1
A testValidToken() 0 10 1
A testPrepareTokensWithUrlMatchedInBackUrl() 0 11 1
A testTokenWithTrailingSlashInUrl() 0 11 1
A testTokenWithLeadingSlashInUrl() 0 11 1
A testPrepareTokensDoesntSuppressWhenNotMatched() 0 9 1
A testTokenWithUrlMatchedInBackUrl() 0 12 2
A testCurrentURLHandlesSlashes() 0 10 2
A testUrlSuppressionWhenTokenMissing() 0 8 1
A dataProviderURLs() 0 9 1
1
<?php
2
3
namespace SilverStripe\Core\Tests\Startup;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Control\Session;
8
use SilverStripe\Core\Startup\URLConfirmationToken;
9
use SilverStripe\Core\Tests\Startup\URLConfirmationTokenTest\StubToken;
10
use SilverStripe\Core\Tests\Startup\URLConfirmationTokenTest\StubValidToken;
11
use SilverStripe\Dev\SapphireTest;
12
13
class URLConfirmationTokenTest extends SapphireTest
14
{
15
    public function testValidToken()
16
    {
17
        $request = new HTTPRequest('GET', 'token/test/url', ['tokentesturltoken' => 'value']);
18
        $validToken = new StubValidToken('token/test/url', $request);
19
        $this->assertTrue($validToken->urlMatches());
20
        $this->assertFalse($validToken->urlExistsInBackURL());
21
        $this->assertTrue($validToken->tokenProvided()); // Actually forced to true for this test
22
        $this->assertFalse($validToken->reloadRequired());
23
        $this->assertFalse($validToken->reloadRequiredIfError());
24
        $this->assertStringStartsWith(Controller::join_links(BASE_URL, '/', 'token/test/url'), $validToken->redirectURL());
25
    }
26
27
    public function testTokenWithLeadingSlashInUrl()
28
    {
29
        $request = new HTTPRequest('GET', '/leading/slash/url', []);
30
        $leadingSlash = new StubToken('leading/slash/url', $request);
31
        $this->assertTrue($leadingSlash->urlMatches());
32
        $this->assertFalse($leadingSlash->urlExistsInBackURL());
33
        $this->assertFalse($leadingSlash->tokenProvided());
34
        $this->assertTrue($leadingSlash->reloadRequired());
35
        $this->assertTrue($leadingSlash->reloadRequiredIfError());
36
        $this->assertContains('leading/slash/url', $leadingSlash->redirectURL());
37
        $this->assertContains('leadingslashurltoken', $leadingSlash->redirectURL());
38
    }
39
40
    public function testTokenWithTrailingSlashInUrl()
41
    {
42
        $request = new HTTPRequest('GET', 'trailing/slash/url/', []);
43
        $trailingSlash = new StubToken('trailing/slash/url', $request);
44
        $this->assertTrue($trailingSlash->urlMatches());
45
        $this->assertFalse($trailingSlash->urlExistsInBackURL());
46
        $this->assertFalse($trailingSlash->tokenProvided());
47
        $this->assertTrue($trailingSlash->reloadRequired());
48
        $this->assertTrue($trailingSlash->reloadRequiredIfError());
49
        $this->assertContains('trailing/slash/url', $trailingSlash->redirectURL());
50
        $this->assertContains('trailingslashurltoken', $trailingSlash->redirectURL());
51
    }
52
53
    public function testTokenWithUrlMatchedInBackUrl()
54
    {
55
        $request = new HTTPRequest('GET', '/', ['BackURL' => 'back/url']);
56
        $backUrl = new StubToken('back/url', $request);
57
        $this->assertFalse($backUrl->urlMatches());
58
        $this->assertTrue($backUrl->urlExistsInBackURL());
59
        $this->assertFalse($backUrl->tokenProvided());
60
        $this->assertFalse($backUrl->reloadRequired());
61
        $this->assertTrue($backUrl->reloadRequiredIfError());
62
        $home = (BASE_URL ?: '/') . '?';
63
        $this->assertStringStartsWith($home, $backUrl->redirectURL());
64
        $this->assertContains('backurltoken', $backUrl->redirectURL());
65
    }
66
67
    public function testUrlSuppressionWhenTokenMissing()
68
    {
69
        // Check suppression
70
        $request = new HTTPRequest('GET', 'test/url', []);
71
        $token = new StubToken('test/url', $request);
72
        $this->assertEquals('test/url', $request->getURL(false));
73
        $token->suppress();
74
        $this->assertEquals('', $request->getURL(false));
75
    }
76
77
    public function testPrepareTokens()
78
    {
79
        $request = new HTTPRequest('GET', 'test/url', []);
80
        $token = URLConfirmationToken::prepare_tokens(
81
            [
82
                'test/url',
83
                'test',
84
                'url'
85
            ],
86
            $request
87
        );
88
        // Test no invalid tokens
89
        $this->assertEquals('test/url', $token->getURLToCheck());
90
        $this->assertNotEquals('test/url', $request->getURL(false), 'prepare_tokens() did not suppress URL');
91
    }
92
93
    public function testPrepareTokensDoesntSuppressWhenNotMatched()
94
    {
95
        $request = new HTTPRequest('GET', 'test/url', []);
96
        $token = URLConfirmationToken::prepare_tokens(
97
            ['another/url'],
98
            $request
99
        );
100
        $this->assertEmpty($token);
101
        $this->assertEquals('test/url', $request->getURL(false), 'prepare_tokens() incorrectly suppressed URL');
102
    }
103
104
    public function testPrepareTokensWithUrlMatchedInBackUrl()
105
    {
106
        // Test backurl token
107
        $request = new HTTPRequest('GET', '/', ['BackURL' => 'back/url']);
108
        $token = URLConfirmationToken::prepare_tokens(
109
            [ 'back/url' ],
110
            $request
111
        );
112
        $this->assertNotEmpty($token);
113
        $this->assertEquals('back/url', $token->getURLToCheck());
114
        $this->assertNotEquals('back/url', $request->getURL(false), 'prepare_tokens() did not suppress URL');
115
    }
116
117
    public function dataProviderURLs()
118
    {
119
        return [
120
            [''],
121
            ['/'],
122
            ['bar'],
123
            ['bar/'],
124
            ['/bar'],
125
            ['/bar/'],
126
        ];
127
    }
128
129
    /**
130
     * currentURL needs to handle base or url being missing, or any combination of slashes.
131
     *
132
     * There should always be exactly one slash between each part in the result, and any trailing slash
133
     * should be preserved.
134
     *
135
     * @dataProvider dataProviderURLs
136
     */
137
    public function testCurrentURLHandlesSlashes($url)
138
    {
139
        $request = new HTTPRequest('GET', $url, []);
140
141
        $token = new StubToken(
142
            'another/url',
143
            $request
144
        );
145
        $expected = rtrim(Controller::join_links(BASE_URL, '/', $url), '/') ?: '/';
146
        $this->assertEquals($expected, $token->currentURL(), "Invalid redirect for request url $url");
147
    }
148
}
149