CMSMainTest::testCreationOfTopLevelPage()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 52
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 30
nc 1
nop 0
dl 0
loc 52
rs 9.44
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\CMS\Tests\Controllers;
4
5
use Psr\SimpleCache\CacheInterface;
6
use SilverStripe\Admin\CMSBatchActionHandler;
7
use SilverStripe\CMS\Controllers\CMSMain;
8
use SilverStripe\CMS\Model\RedirectorPage;
9
use SilverStripe\CMS\Model\SiteTree;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Control\HTTPRequest;
12
use SilverStripe\Control\HTTPResponse_Exception;
13
use SilverStripe\Core\ClassInfo;
14
use SilverStripe\Core\Config\Config;
15
use SilverStripe\Core\Convert;
16
use SilverStripe\Core\Injector\Injector;
17
use SilverStripe\Dev\CSSContentParser;
18
use SilverStripe\Dev\FunctionalTest;
19
use SilverStripe\Dev\TestOnly;
20
use SilverStripe\Forms\FieldList;
21
use SilverStripe\ORM\DataObject;
22
use SilverStripe\ORM\DB;
23
use SilverStripe\Security\Member;
24
use SilverStripe\Security\Security;
25
use SilverStripe\SiteConfig\SiteConfig;
26
use SilverStripe\Versioned\Versioned;
27
28
class CMSMainTest extends FunctionalTest
29
{
30
    protected static $fixture_file = 'CMSMainTest.yml';
31
32
    protected static $orig = [];
33
34
    protected function setUp() : void
35
    {
36
        parent::setUp();
37
38
        // Clear automatically created siteconfigs (in case one was created outside of the specified fixtures).
39
        $ids = $this->allFixtureIDs(SiteConfig::class);
40
        if ($ids) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ids of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
41
            foreach (SiteConfig::get()->exclude('ID', $ids) as $config) {
42
                $config->delete();
43
            }
44
        }
45
    }
46
47
    public function testSiteTreeHints()
48
    {
49
        $cache = Injector::inst()->get(CacheInterface::class . '.CMSMain_SiteTreeHints');
50
        // Login as user with root creation privileges
51
        $user = $this->objFromFixture(Member::class, 'rootedituser');
52
        Security::setCurrentUser($user);
53
        $cache->clear();
54
55
        $rawHints = singleton(CMSMain::class)->SiteTreeHints();
56
        $this->assertNotNull($rawHints);
57
58
        $rawHints = preg_replace('/^"(.*)"$/', '$1', Convert::xml2raw($rawHints));
59
        $hints = json_decode($rawHints, true);
60
61
        $this->assertArrayHasKey('Root', $hints);
62
        $this->assertArrayHasKey('Page', $hints);
63
        $this->assertArrayHasKey('All', $hints);
64
65
        $this->assertArrayHasKey(
66
            CMSMainTest_ClassA::class,
67
            $hints['All'],
68
            'Global list shows allowed classes'
69
        );
70
71
        $this->assertArrayNotHasKey(
72
            CMSMainTest_HiddenClass::class,
73
            $hints['All'],
74
            'Global list does not list hidden classes'
75
        );
76
77
        $this->assertNotContains(
78
            CMSMainTest_ClassA::class,
79
            $hints['Root']['disallowedChildren'],
80
            'Limits root classes'
81
        );
82
83
        $this->assertContains(
84
            CMSMainTest_NotRoot::class,
85
            $hints['Root']['disallowedChildren'],
86
            'Limits root classes'
87
        );
88
    }
89
90
    public function testChildFilter()
91
    {
92
        $this->logInWithPermission('ADMIN');
93
94
        // Check page A
95
        $pageA = new CMSMainTest_ClassA();
96
        $pageA->write();
97
        $pageB = new CMSMainTest_ClassB();
98
        $pageB->write();
99
100
        // Check query
101
        $response = $this->get('admin/pages/childfilter?ParentID=' . $pageA->ID);
102
        $children = json_decode($response->getBody());
103
        $this->assertFalse($response->isError());
104
105
        // Page A can't have unrelated children
106
        $this->assertContains(
107
            'Page',
108
            $children,
109
            'Limited parent lists disallowed classes'
110
        );
111
112
        // But it can create a ClassB
113
        $this->assertNotContains(
114
            CMSMainTest_ClassB::class,
115
            $children,
116
            'Limited parent omits explicitly allowed classes in disallowedChildren'
117
        );
118
    }
119
120
    /**
121
     * @todo Test the results of a publication better
122
     */
123
    public function testPublish()
124
    {
125
        $page1 = $this->objFromFixture(SiteTree::class, "page1");
126
        $page2 = $this->objFromFixture(SiteTree::class, "page2");
127
        $this->session()->set('loggedInAs', $this->idFromFixture(Member::class, 'admin'));
128
129
        $response = $this->get('admin/pages/publishall?confirm=1');
130
        $this->assertStringContainsString(
131
            'Done: Published 30 pages',
132
            $response->getBody()
133
        );
134
135
        // Some modules (e.g., cmsworkflow) will remove this action
136
        $actions = CMSBatchActionHandler::config()->batch_actions;
137
        if (isset($actions['publish'])) {
138
            $response = $this->get(
139
                'admin/pages/batchactions/publish?ajax=1&csvIDs=' . implode(',', [$page1->ID, $page2->ID])
140
            );
141
            $responseData = json_decode($response->getBody(), true);
142
            $this->assertArrayHasKey($page1->ID, $responseData['modified']);
143
            $this->assertArrayHasKey($page2->ID, $responseData['modified']);
144
        }
145
146
        // Get the latest version of the redirector page
147
        $pageID = $this->idFromFixture(RedirectorPage::class, 'page5');
148
        $latestID = DB::prepared_query(
149
            'SELECT MAX("Version") FROM "RedirectorPage_Versions" WHERE "RecordID" = ?',
150
            [$pageID]
151
        )->value();
152
        $dsCount = DB::prepared_query(
153
            'SELECT COUNT("Version") FROM "RedirectorPage_Versions" WHERE "RecordID" = ? AND "Version"= ?',
154
            [$pageID, $latestID]
155
        )->value();
156
        $this->assertEquals(
157
            1,
158
            $dsCount,
159
            "Published page has no duplicate version records: it has " . $dsCount . " for version " . $latestID
160
        );
161
162
        $this->session()->clear('loggedInAs');
163
    }
164
165
    /**
166
     * Test that getCMSFields works on each page type.
167
     * Mostly, this is just checking that the method doesn't return an error
168
     */
169
    public function testThatGetCMSFieldsWorksOnEveryPageType()
170
    {
171
        $classes = ClassInfo::subclassesFor(SiteTree::class);
172
        array_shift($classes);
173
174
        foreach ($classes as $class) {
175
            $page = new $class();
176
            if ($page instanceof TestOnly) {
177
                continue;
178
            }
179
            if (!$page->config()->get('can_be_root')) {
180
                continue;
181
            }
182
183
            $page->Title = "Test $class page";
184
            $page->write();
185
            $page->flushCache();
186
            $page = DataObject::get_by_id(SiteTree::class, $page->ID);
187
188
            $this->assertTrue($page->getCMSFields() instanceof FieldList);
189
        }
190
    }
191
192
    public function testCanPublishPageWithUnpublishedParentWithStrictHierarchyOff()
193
    {
194
        $this->logInWithPermission('ADMIN');
195
196
        Config::modify()->set(SiteTree::class, 'enforce_strict_hierarchy', true);
197
        $parentPage = $this->objFromFixture(SiteTree::class, 'page3');
198
        $childPage = $this->objFromFixture(SiteTree::class, 'page1');
199
200
        $parentPage->doUnpublish();
201
        $childPage->doUnpublish();
202
203
        $actions = $childPage->getCMSActions()->dataFields();
204
        $this->assertArrayHasKey(
205
            'action_publish',
206
            $actions,
207
            'Can publish a page with an unpublished parent with strict hierarchy off'
208
        );
209
        Config::modify()->set(SiteTree::class, 'enforce_strict_hierarchy', false);
210
    }
211
212
    /**
213
     * Test that a draft-deleted page can still be opened in the CMS
214
     */
215
    public function testDraftDeletedPageCanBeOpenedInCMS()
216
    {
217
        $this->logInWithPermission('ADMIN');
218
219
        // Set up a page that is delete from live
220
        $page = $this->objFromFixture(SiteTree::class, 'page1');
221
        $pageID = $page->ID;
222
        $page->publishRecursive();
223
        $page->delete();
224
225
        $response = $this->get('admin/pages/edit/show/' . $pageID);
226
227
        $livePage = Versioned::get_one_by_stage(SiteTree::class, Versioned::LIVE, [
0 ignored issues
show
Bug introduced by
array('"SiteTree"."ID"' => $pageID) of type array<string,integer> is incompatible with the type string expected by parameter $filter of SilverStripe\Versioned\V...ned::get_one_by_stage(). ( Ignorable by Annotation )

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

227
        $livePage = Versioned::get_one_by_stage(SiteTree::class, Versioned::LIVE, /** @scrutinizer ignore-type */ [
Loading history...
228
                '"SiteTree"."ID"' => $pageID,
229
        ]);
230
        $this->assertInstanceOf(SiteTree::class, $livePage);
231
        $this->assertTrue($livePage->canDelete());
232
233
        // Check that the 'restore' button exists as a simple way of checking that the correct page is returned.
234
        $this->assertRegExp('/<button type="submit"[^>]+name="action_(restore|revert)"/i', $response->getBody());
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertRegExp() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/4086 ( Ignorable by Annotation )

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

234
        /** @scrutinizer ignore-deprecated */ $this->assertRegExp('/<button type="submit"[^>]+name="action_(restore|revert)"/i', $response->getBody());

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...
235
    }
236
237
    /**
238
     * Test CMSMain::getRecord()
239
     */
240
    public function testGetRecord()
241
    {
242
        $this->logInWithPermission('ADMIN');
243
244
        // Set up a page that is delete from live
245
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
246
        $page1ID = $page1->ID;
247
        $page1->publishRecursive();
248
        $page1->delete();
249
250
        $cmsMain = CMSMain::create();
251
        $cmsMain->setRequest(Controller::curr()->getRequest());
252
253
        // Bad calls
254
        $this->assertNull($cmsMain->getRecord('0'));
255
        $this->assertNull($cmsMain->getRecord('asdf'));
256
257
        // Pages that are on draft and aren't on draft should both work
258
        $this->assertInstanceOf(SiteTree::class, $cmsMain->getRecord($page1ID));
259
        $this->assertInstanceOf(SiteTree::class, $cmsMain->getRecord($this->idFromFixture(SiteTree::class, 'page2')));
260
261
        // This functionality isn't actually used any more.
262
        $newPage = $cmsMain->getRecord('new-Page-5');
263
        $this->assertInstanceOf(SiteTree::class, $newPage);
264
        $this->assertEquals('5', $newPage->ParentID);
265
    }
266
267
    public function testDeletedPagesSiteTreeFilter()
268
    {
269
        $id = $this->idFromFixture(SiteTree::class, 'page3');
270
        $this->logInWithPermission('ADMIN');
271
        $result = $this->get('admin/pages/getsubtree?filter=CMSSiteTreeFilter_DeletedPages&ajax=1&ID=' . $id);
272
        $this->assertEquals(200, $result->getStatusCode());
273
    }
274
275
    public function testCreationOfTopLevelPage()
276
    {
277
        $origFollow = $this->autoFollowRedirection;
278
        $this->autoFollowRedirection = false;
279
280
        $cmsUser = $this->objFromFixture(Member::class, 'allcmssectionsuser');
281
        $rootEditUser = $this->objFromFixture(Member::class, 'rootedituser');
282
283
        // with insufficient permissions
284
        Security::setCurrentUser($cmsUser);
285
        $this->get('admin/pages/add');
286
        $response = $this->post(
287
            'admin/pages/add/AddForm',
288
            [
289
                'ParentID' => '0',
290
                'PageType' => RedirectorPage::class,
291
                'Locale' => 'en_US',
292
                'action_doAdd' => 1,
293
                'ajax' => 1,
294
            ],
295
            [
296
                'X-Pjax' => 'CurrentForm,Breadcrumbs',
297
            ]
298
        );
299
        // should redirect, which is a permission error
300
        $this->assertEquals(403, $response->getStatusCode(), 'Add TopLevel page must fail for normal user');
301
302
        // with correct permissions
303
        Security::setCurrentUser($rootEditUser);
304
        $response = $this->get('admin/pages/add');
0 ignored issues
show
Unused Code introduced by
The assignment to $response is dead and can be removed.
Loading history...
305
306
        $response = $this->post(
307
            'admin/pages/add/AddForm',
308
            [
309
                'ParentID' => '0',
310
                'PageType' => RedirectorPage::class,
311
                'Locale' => 'en_US',
312
                'action_doAdd' => 1,
313
                'ajax' => 1,
314
            ],
315
            [
316
                'X-Pjax' => 'CurrentForm,Breadcrumbs',
317
            ]
318
        );
319
320
        $location = $response->getHeader('X-ControllerURL');
321
        $this->assertNotEmpty($location, 'Must be a redirect on success');
322
        $this->assertStringContainsString('/show/', $location, 'Must redirect to /show/ the new page');
323
        // TODO Logout
324
        Security::setCurrentUser(null);
325
326
        $this->autoFollowRedirection = $origFollow;
327
    }
328
329
    public function testCreationOfRestrictedPage()
330
    {
331
        $origFollow = $this->autoFollowRedirection;
332
        $this->autoFollowRedirection = false;
333
334
        $adminUser = $this->objFromFixture(Member::class, 'admin');
335
        Security::setCurrentUser($adminUser);
336
337
        // Create toplevel page
338
        $this->get('admin/pages/add');
339
        $response = $this->post(
340
            'admin/pages/add/AddForm',
341
            [
342
                'ParentID' => '0',
343
                'PageType' => CMSMainTest_ClassA::class,
344
                'Locale' => 'en_US',
345
                'action_doAdd' => 1,
346
                'ajax' => 1,
347
            ],
348
            [
349
                'X-Pjax' => 'CurrentForm,Breadcrumbs',
350
            ]
351
        );
352
        $this->assertFalse($response->isError());
353
        $ok = preg_match('/edit\/show\/(\d*)/', $response->getHeader('X-ControllerURL'), $matches);
354
        $this->assertNotEmpty($ok);
355
        $newPageId = $matches[1];
356
357
        // Create allowed child
358
        $this->get('admin/pages/add');
359
        $response = $this->post(
360
            'admin/pages/add/AddForm',
361
            [
362
                'ParentID' => $newPageId,
363
                'PageType' => CMSMainTest_ClassB::class,
364
                'Locale' => 'en_US',
365
                'action_doAdd' => 1,
366
                'ajax' => 1,
367
            ],
368
            [
369
                'X-Pjax' => 'CurrentForm,Breadcrumbs',
370
            ]
371
        );
372
        $this->assertFalse($response->isError());
373
        $this->assertEmpty($response->getBody());
374
375
        // Verify that the page was created and redirected to accurately
376
        $newerPage = SiteTree::get()->byID($newPageId)->AllChildren()->first();
377
        $this->assertNotEmpty($newerPage);
378
        $ok = preg_match('/edit\/show\/(\d*)/', $response->getHeader('X-ControllerURL'), $matches);
379
        $this->assertNotEmpty($ok);
380
        $newerPageID = $matches[1];
381
        $this->assertEquals($newerPage->ID, $newerPageID);
382
383
        // Create disallowed child
384
        $this->get('admin/pages/add');
385
        $response = $this->post(
386
            'admin/pages/add/AddForm',
387
            [
388
                'ParentID' => $newPageId,
389
                'PageType' => RedirectorPage::class,
390
                'Locale' => 'en_US',
391
                'action_doAdd' => 1,
392
                'ajax' => 1,
393
            ],
394
            [
395
                'X-Pjax' => 'CurrentForm,Breadcrumbs',
396
            ]
397
        );
398
        $this->assertEquals(403, $response->getStatusCode(), 'Add disallowed child should fail');
399
400
        Security::setCurrentUser(null);
401
402
        $this->autoFollowRedirection = $origFollow;
403
    }
404
405
    public function testBreadcrumbs()
406
    {
407
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
0 ignored issues
show
Unused Code introduced by
The assignment to $page3 is dead and can be removed.
Loading history...
408
        $page31 = $this->objFromFixture(SiteTree::class, 'page31');
409
        $adminuser = $this->objFromFixture(Member::class, 'admin');
410
        Security::setCurrentUser($adminuser);
411
412
        $response = $this->get('admin/pages/edit/show/' . $page31->ID);
413
        $parser = new CSSContentParser($response->getBody());
414
        $crumbs = $parser->getBySelector('.breadcrumbs-wrapper .crumb');
415
416
        $this->assertNotNull($crumbs);
417
        $this->assertEquals(2, count($crumbs));
418
        $this->assertEquals('Page 3', (string)$crumbs[0]);
419
        $this->assertEquals('Page 3.1', (string)$crumbs[1]);
420
421
        Security::setCurrentUser(null);
422
    }
423
424
    public function testGetNewItem()
425
    {
426
        $controller = CMSMain::create();
427
        $controller->setRequest(Controller::curr()->getRequest());
428
        $id = 'new-Page-0';
429
430
        // Test success
431
        $page = $controller->getNewItem($id, false);
432
433
        $this->assertEquals($page->Title, 'New Page');
434
        $this->assertNotEquals($page->Sort, 0);
435
        $this->assertInstanceOf(SiteTree::class, $page);
436
437
        // Test failure
438
        try {
439
            $id = 'new-Member-0';
440
            $member = $controller->getNewItem($id, false);
0 ignored issues
show
Unused Code introduced by
The assignment to $member is dead and can be removed.
Loading history...
441
            $this->fail('Should not be able to create a Member object');
442
        } catch (HTTPResponse_Exception $e) {
443
            $this->assertEquals($controller->getResponse()->getStatusCode(), 302);
444
        }
445
    }
446
447
    /**
448
     * Tests filtering in {@see CMSMain::getList()}
449
     */
450
    public function testGetList()
451
    {
452
        $controller = CMSMain::create();
453
        $controller->setRequest(Controller::curr()->getRequest());
454
455
        // Test all pages (stage)
456
        $pages = $controller->getList()->sort('Title');
457
        $this->assertEquals(28, $pages->count());
458
        $this->assertEquals(
459
            ['Home', 'Page 1', 'Page 10', 'Page 11', 'Page 12'],
460
            $pages->Limit(5)->column('Title')
461
        );
462
463
        // Change state of tree
464
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
465
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
466
        $page11 = $this->objFromFixture(SiteTree::class, 'page11');
467
        $page12 = $this->objFromFixture(SiteTree::class, 'page12');
468
        // Deleted
469
        $page1->doUnpublish();
470
        $page1->delete();
471
        // Live and draft
472
        $page11->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
473
        // Live only
474
        $page12->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
475
        $page12->delete();
476
477
        // Re-test all pages (stage)
478
        $pages = $controller->getList()->sort('Title');
479
        $this->assertEquals(26, $pages->count());
480
        $this->assertEquals(
481
            ['Home', 'Page 10', 'Page 11', 'Page 13', 'Page 14'],
482
            $pages->Limit(5)->column('Title')
483
        );
484
485
        // Test deleted page filter
486
        $params = [
487
                'FilterClass' => 'SilverStripe\\CMS\\Controllers\\CMSSiteTreeFilter_StatusDeletedPages',
488
        ];
489
        $pages = $controller->getList($params);
490
        $this->assertEquals(1, $pages->count());
491
        $this->assertEquals(
492
            ['Page 1'],
493
            $pages->column('Title')
494
        );
495
496
        // Test live, but not on draft filter
497
        $params = [
498
            'FilterClass' => 'SilverStripe\\CMS\\Controllers\\CMSSiteTreeFilter_StatusRemovedFromDraftPages',
499
        ];
500
        $pages = $controller->getList($params);
501
        $this->assertEquals(1, $pages->count());
502
        $this->assertEquals(
503
            ['Page 12'],
504
            $pages->column('Title')
505
        );
506
507
        // Test live pages filter
508
        $params = [
509
            'FilterClass' => 'SilverStripe\\CMS\\Controllers\\CMSSiteTreeFilter_PublishedPages',
510
        ];
511
        $pages = $controller->getList($params);
512
        $this->assertEquals(2, $pages->count());
513
        $this->assertEquals(
514
            ['Page 11', 'Page 12'],
515
            $pages->column('Title')
516
        );
517
518
        // Test that parentID is ignored when filtering
519
        $pages = $controller->getList($params, $page3->ID);
520
        $this->assertEquals(2, $pages->count());
521
        $this->assertEquals(
522
            ['Page 11', 'Page 12'],
523
            $pages->column('Title')
524
        );
525
526
        // Test that parentID is respected when not filtering
527
        $pages = $controller->getList([], $page3->ID);
528
        $this->assertEquals(2, $pages->count());
529
        $this->assertEquals(
530
            ['Page 3.1', 'Page 3.2'],
531
            $pages->column('Title')
532
        );
533
    }
534
535
    /**
536
     * Testing retrieval and type of CMS edit form.
537
     */
538
    public function testGetEditForm()
539
    {
540
        // Login is required prior to accessing a CMS form.
541
        $this->loginWithPermission('ADMIN');
542
543
        // Get a associated with a fixture page.
544
        $page = $this->objFromFixture(SiteTree::class, 'page1');
545
        $controller = CMSMain::create();
546
        $controller->setRequest(Controller::curr()->getRequest());
547
        $form = $controller->getEditForm($page->ID);
548
        $this->assertInstanceOf("SilverStripe\\Forms\\Form", $form);
549
550
        // Ensure that the form will not "validate" on delete or "unpublish" actions.
551
        $exemptActions = $form->getValidationExemptActions();
552
        $this->assertContains("delete", $exemptActions);
553
        $this->assertContains("unpublish", $exemptActions);
554
    }
555
556
    /**
557
     * Test that changed classes save with the correct class name
558
     */
559
    public function testChangeClass()
560
    {
561
        $this->logInWithPermission('ADMIN');
562
        $cms = CMSMain::create();
563
        $cms->setRequest(Controller::curr()->getRequest());
564
        $page = new CMSMainTest_ClassA();
565
        $page->Title = 'Class A';
566
        $page->write();
567
568
        $form = $cms->getEditForm($page->ID);
569
        $form->loadDataFrom(['ClassName' => CMSMainTest_ClassB::class]);
570
        $result = $cms->save([
571
            'ID' => $page->ID,
572
            'ClassName' => CMSMainTest_ClassB::class,
573
        ], $form);
574
        $this->assertEquals(200, $result->getStatusCode());
575
576
        $newPage = SiteTree::get()->byID($page->ID);
577
578
        $this->assertInstanceOf(CMSMainTest_ClassB::class, $newPage);
579
        $this->assertEquals(CMSMainTest_ClassB::class, $newPage->ClassName);
580
        $this->assertEquals('Class A', $newPage->Title);
581
    }
582
583
    public function testSiteTreeHintsCache()
584
    {
585
        $cms = CMSMain::create();
586
        /** @var Member $user */
587
        $user = $this->objFromFixture(Member::class, 'rootedituser');
588
        Security::setCurrentUser($user);
589
        $pageClass = array_values(SiteTree::page_type_classes())[0];
590
        $mockPageMissesCache = $this->getMockBuilder($pageClass)
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated: https://github.com/sebastianbergmann/phpunit/pull/3687 ( Ignorable by Annotation )

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

590
        $mockPageMissesCache = /** @scrutinizer ignore-deprecated */ $this->getMockBuilder($pageClass)

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...
591
            ->setMethods(['canCreate'])
592
            ->getMock();
593
        $mockPageMissesCache
594
            ->expects($this->exactly(3))
595
            ->method('canCreate');
596
597
        $mockPageHitsCache = $this->getMockBuilder($pageClass)
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated: https://github.com/sebastianbergmann/phpunit/pull/3687 ( Ignorable by Annotation )

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

597
        $mockPageHitsCache = /** @scrutinizer ignore-deprecated */ $this->getMockBuilder($pageClass)

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...
598
            ->setMethods(['canCreate'])
599
            ->getMock();
600
        $mockPageHitsCache
601
            ->expects($this->never())
602
            ->method('canCreate');
603
604
605
        // Initially, cache misses (1)
606
        Injector::inst()->registerService($mockPageMissesCache, $pageClass);
607
        $hints = $cms->SiteTreeHints();
608
        $this->assertNotNull($hints);
609
610
        // Now it hits
611
        Injector::inst()->registerService($mockPageHitsCache, $pageClass);
612
        $hints = $cms->SiteTreeHints();
613
        $this->assertNotNull($hints);
614
615
        // Mutating member record invalidates cache. Misses (2)
616
        $user->FirstName = 'changed';
617
        $user->write();
618
        Injector::inst()->registerService($mockPageMissesCache, $pageClass);
619
        $hints = $cms->SiteTreeHints();
620
        $this->assertNotNull($hints);
621
622
        // Now it hits again
623
        Injector::inst()->registerService($mockPageHitsCache, $pageClass);
624
        $hints = $cms->SiteTreeHints();
625
        $this->assertNotNull($hints);
626
627
        // Different user. Misses. (3)
628
        $user = $this->objFromFixture(Member::class, 'allcmssectionsuser');
629
        Security::setCurrentUser($user);
630
        Injector::inst()->registerService($mockPageMissesCache, $pageClass);
631
        $hints = $cms->SiteTreeHints();
632
        $this->assertNotNull($hints);
633
    }
634
635
    public function testSearchField()
636
    {
637
        $cms = CMSMain::create();
638
        $searchSchema = $cms->getSearchFieldSchema();
639
640
        $this->assertJsonStringEqualsJsonString(
641
            json_encode([
642
                'formSchemaUrl' => 'admin/pages/schema/SearchForm',
643
                'name' => 'Term',
644
                'placeholder' => 'Search "Pages"',
645
                'filters' => new \stdClass()
646
            ]),
647
            $searchSchema
648
        );
649
650
        $request = new HTTPRequest(
651
            'GET',
652
            'admin/pages/schema/SearchForm',
653
            ['q' => [
654
                'Term' => 'test',
655
                'FilterClass' => 'SilverStripe\CMS\Controllers\CMSSiteTreeFilter_Search'
656
            ]]
657
        );
658
        $cms->setRequest($request);
659
        $searchSchema = $cms->getSearchFieldSchema();
660
661
        $this->assertJsonStringEqualsJsonString(
662
            json_encode([
663
                'formSchemaUrl' => 'admin/pages/schema/SearchForm',
664
                'name' => 'Term',
665
                'placeholder' => 'Search "Pages"',
666
                'filters' => [
667
                    'Search__Term' => 'test',
668
                    'Search__FilterClass' => 'SilverStripe\CMS\Controllers\CMSSiteTreeFilter_Search'
669
                ]
670
            ]),
671
            $searchSchema
672
        );
673
    }
674
675
    public function testCanOrganiseSitetree()
676
    {
677
        $cms = CMSMain::create();
678
679
        $this->assertFalse($cms->CanOrganiseSitetree());
680
681
        $this->logInWithPermission('CMS_ACCESS_CMSMain');
682
        $this->assertFalse($cms->CanOrganiseSitetree());
683
684
        $this->logOut();
685
        $this->logInWithPermission('SITETREE_REORGANISE');
686
        $this->assertTrue($cms->CanOrganiseSitetree());
687
688
        $this->logOut();
689
        $this->logInWithPermission('ADMIN');
690
        $this->assertTrue($cms->CanOrganiseSitetree());
691
    }
692
}
693