Issues (144)

tests/php/SubsiteAdminFunctionalTest.php (2 issues)

1
<?php
2
3
namespace SilverStripe\Subsites\Tests;
4
5
use Page;
6
use SilverStripe\CMS\Controllers\CMSPageEditController;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\Dev\FunctionalTest;
9
use SilverStripe\Subsites\Model\Subsite;
10
11
class SubsiteAdminFunctionalTest extends FunctionalTest
12
{
13
    protected static $fixture_file = 'SubsiteTest.yml';
14
15
    protected $autoFollowRedirection = false;
16
17
    protected function setUp()
18
    {
19
        parent::setUp();
20
        // Ensure all pages are published
21
        /** @var Page $page */
22
        foreach (Page::get() as $page) {
23
            $page->publishSingle();
24
        }
25
    }
26
27
    /**
28
     * Helper: FunctionalTest is only able to follow redirection once, we want to go all the way.
29
     * @param string $url
30
     * @return \SilverStripe\Control\HTTPResponse
31
     */
32
    public function getAndFollowAll($url)
33
    {
34
        $response = $this->get($url);
35
        while ($location = $response->getHeader('Location')) {
0 ignored issues
show
The assignment to $location is dead and can be removed.
Loading history...
36
            $response = $this->mainSession->followRedirection();
37
        }
38
        echo $response->getHeader('Location');
39
40
        return $response;
41
    }
42
43
    /**
44
     * Anonymous user cannot access anything.
45
     */
46
    public function testAnonymousIsForbiddenAdminAccess()
47
    {
48
        $this->logOut();
49
50
        $response = $this->getAndFollowAll('admin/pages/?SubsiteID=0');
0 ignored issues
show
The assignment to $response is dead and can be removed.
Loading history...
51
        $this->assertContains('Security/login', $this->mainSession->lastUrl(), 'Admin is disallowed');
52
53
        $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
54
        $response = $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
55
        $this->assertContains('Security/login', $this->mainSession->lastUrl(), 'Admin is disallowed');
56
57
        $response = $this->getAndFollowAll('admin/subsite_xhr');
58
        $this->assertContains('Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is disallowed');
59
    }
60
61
    /**
62
     * Admin should be able to access all subsites and the main site
63
     */
64
    public function testAdminCanAccessAllSubsites()
65
    {
66
        $this->logInAs('admin');
67
68
        $this->getAndFollowAll('admin/pages/?SubsiteID=0');
69
        $this->assertEquals(0, $this->session()->get('SubsiteID'), 'Can access main site.');
70
        $this->assertContains('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section');
71
72
        $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
73
        $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
74
75
        // Check the session manually, since the state is unique to the request, not this test
76
        $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Can access other subsite.');
77
        $this->assertContains('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section');
78
79
        $response = $this->getAndFollowAll('admin/subsite_xhr');
80
        $this->assertNotContains('Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is reachable');
81
    }
82
83
    public function testAdminIsRedirectedToObjectsSubsite()
84
    {
85
        $this->logInAs('admin');
86
87
        $mainSubsitePage = $this->objFromFixture(Page::class, 'mainSubsitePage');
88
        $subsite1Home = $this->objFromFixture(Page::class, 'subsite1_home');
89
90
        // Requesting a page from another subsite will redirect to that subsite
91
        Config::modify()->set(CMSPageEditController::class, 'treats_subsite_0_as_global', false);
92
        $response = $this->get("admin/pages/edit/show/$subsite1Home->ID");
93
94
        $this->assertEquals(302, $response->getStatusCode());
95
        $this->assertContains(
96
            'admin/pages/edit/show/' . $subsite1Home->ID . '?SubsiteID=' . $subsite1Home->SubsiteID,
97
            $response->getHeader('Location')
98
        );
99
100
        // Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global
101
        Config::modify()->set(CMSPageEditController::class, 'treats_subsite_0_as_global', true);
102
103
        $response = $this->get("admin/pages/edit/show/$subsite1Home->ID");
104
        $this->assertEquals(302, $response->getStatusCode());
105
        $this->assertContains(
106
            'admin/pages/edit/show/' . $subsite1Home->ID . '?SubsiteID=' . $subsite1Home->SubsiteID,
107
            $response->getHeader('Location')
108
        );
109
110
        // Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global
111
        $response = $this->get("admin/pages/edit/show/$mainSubsitePage->ID");
112
        $this->assertEquals(200, $response->getStatusCode());
113
    }
114
115
    /**
116
     * User which has AccessAllSubsites set to 1 should be able to access all subsites and main site,
117
     * even though he does not have the ADMIN permission.
118
     */
119
    public function testEditorCanAccessAllSubsites()
120
    {
121
        $this->logInAs('editor');
122
123
        $this->get('admin/pages/?SubsiteID=0');
124
        $this->assertEquals(0, $this->session()->get('SubsiteID'), 'Can access main site.');
125
        $this->assertContains('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section');
126
127
        $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
128
        $this->get("admin/pages/?SubsiteID={$subsite1->ID}");
129
        $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Can access other subsite.');
130
        $this->assertContains('admin/pages', $this->mainSession->lastUrl(), 'Lands on the correct section');
131
132
        $response = $this->get('admin/subsite_xhr');
133
        $this->assertNotContains('Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is reachable');
134
    }
135
136
    /**
137
     * Test a member who only has access to one subsite (subsite1) and only some sections (pages and security).
138
     */
139
    public function testSubsiteAdmin()
140
    {
141
        $this->markTestSkipped('wip');
142
        $this->logInAs('subsite1member');
143
144
        $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
145
146
        // Check allowed URL.
147
        $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
148
        $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Can access own subsite.');
149
        $this->assertContains('admin/pages', $this->mainSession->lastUrl(), 'Can access permitted section.');
150
151
        // Check forbidden section in allowed subsite.
152
        $this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}");
153
        $this->assertEquals($subsite1->ID, $this->session()->get('SubsiteID'), 'Is redirected within subsite.');
154
        $this->assertNotContains(
155
            'admin/assets',
156
            $this->mainSession->lastUrl(),
157
            'Is redirected away from forbidden section'
158
        );
159
160
        // Check forbidden site, on a section that's allowed on another subsite
161
        $this->getAndFollowAll('admin/pages/?SubsiteID=0');
162
        $this->assertEquals(
163
            $this->session()->get('SubsiteID'),
164
            $subsite1->ID,
165
            'Is redirected to permitted subsite.'
166
        );
167
168
        // Check forbidden site, on a section that's not allowed on any other subsite
169
        $this->getAndFollowAll('admin/assets/?SubsiteID=0');
170
        $this->assertEquals(
171
            $this->session()->get('SubsiteID'),
172
            $subsite1->ID,
173
            'Is redirected to first permitted subsite.'
174
        );
175
        $this->assertNotContains('Security/login', $this->mainSession->lastUrl(), 'Is not denied access');
176
177
        // Check the standalone XHR controller.
178
        $response = $this->getAndFollowAll('admin/subsite_xhr');
179
        $this->assertNotContains('Security/login', $this->mainSession->lastUrl(), 'SubsiteXHRController is reachable');
180
    }
181
}
182