Completed
Push — master ( f38bd7...5457f6 )
by Robbie
16s
created

testHomeVisibleOnFrontendBothConfigFalse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TractorCow\Fluent\Tests\Extension;
4
5
use Page;
0 ignored issues
show
Bug introduced by
The type Page was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\CMS\Forms\SiteTreeURLSegmentField;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Dev\Debug;
11
use SilverStripe\Dev\SapphireTest;
12
use SilverStripe\Forms\FieldList;
13
use SilverStripe\Forms\LiteralField;
14
use SilverStripe\ORM\ArrayList;
15
use SilverStripe\ORM\DataObject;
16
use SilverStripe\View\ArrayData;
17
use TractorCow\Fluent\Extension\FluentDirectorExtension;
18
use TractorCow\Fluent\Extension\FluentSiteTreeExtension;
19
use TractorCow\Fluent\Model\Domain;
20
use TractorCow\Fluent\Model\Locale;
21
use TractorCow\Fluent\State\FluentState;
22
23
class FluentSiteTreeExtensionTest extends SapphireTest
24
{
25
    protected static $fixture_file = 'FluentSiteTreeExtensionTest.yml';
26
27
    protected static $required_extensions = [
28
        SiteTree::class => [
29
            FluentSiteTreeExtension::class,
30
        ],
31
    ];
32
33
    protected function setUp()
34
    {
35
        parent::setUp();
36
        Config::modify()
37
            ->set(Director::class, 'alternate_base_url', 'http://mocked')
38
            ->set(FluentDirectorExtension::class, 'disable_default_prefix', false);
39
40
        // Clear cache
41
        Locale::clearCached();
42
        Domain::clearCached();
43
        FluentState::singleton()
44
            ->setLocale('de_DE')
45
            ->setIsDomainMode(false);
46
    }
47
48
    public function testGetLocaleInformation()
49
    {
50
        /** @var Page|FluentSiteTreeExtension $page */
51
        $page = $this->objFromFixture(Page::class, 'nz-page');
52
        $result = $page->LocaleInformation('en_NZ');
53
54
        $this->assertInstanceOf(ArrayData::class, $result);
55
        $this->assertEquals([
56
            'Locale' => 'en_NZ',
57
            'LocaleRFC1766' => 'en-NZ',
58
            'Title' => 'English (New Zealand)',
59
            'LanguageNative' => 'English',
60
            'Language' => 'en',
61
            'Link' => '/newzealand/a-page/',
62
            'AbsoluteLink' => 'http://mocked/newzealand/a-page/',
63
            'LinkingMode' => 'link',
64
            'URLSegment' => 'newzealand'
65
        ], $result->toMap());
66
    }
67
68
    public function testGetLocales()
69
    {
70
        /** @var Page|FluentSiteTreeExtension $page */
71
        $page = $this->objFromFixture(Page::class, 'nz-page');
72
        $result = $page->Locales();
73
74
        $this->assertInstanceOf(ArrayList::class, $result);
75
        $this->assertCount(5, $result);
76
        $this->assertListEquals([
77
            ['Locale' => 'en_NZ'],
78
            ['Locale' => 'de_DE'],
79
            ['Locale' => 'en_US'],
80
            ['Locale' => 'es_ES'],
81
            ['Locale' => 'zh_CN'],
82
        ], $result);
83
    }
84
85
    /**
86
     * Tests for url generation
87
     *
88
     * @return array list of tests with values:
89
     *  - domain (or false for non-domain mode)
90
     *  - locale
91
     *  - disable_default_prefix flag
92
     *  - page id
93
     *  - expected link
94
     */
95
    public function provideURLTests()
96
    {
97
        return [
98
            // Non-domain tests
99
            [null, 'de_DE', false, 'home', '/'],
100
            [null, 'de_DE', false, 'about', '/german/about-us/'],
101
            [null, 'de_DE', false, 'staff', '/german/about-us/my-staff/'],
102
            // Since de_DE is the only locale on the www.example.de domain, ensure that the locale
103
            // isn't unnecessarily added to the link.
104
            // In this case disable_default_prefix is ignored
105
            // See https://github.com/tractorcow/silverstripe-fluent/issues/75
106
            ['www.example.de', 'de_DE', false, 'home', '/'],
107
            ['www.example.de', 'de_DE', false, 'about', '/about-us/'],
108
            ['www.example.de', 'de_DE', false, 'staff', '/about-us/my-staff/'],
109
110
            // Test domains with multiple locales
111
            //  - es_ES non default locale
112
            ['www.example.com', 'es_ES', false, 'home', '/es_ES/'],
113
            ['www.example.com', 'es_ES', false, 'about', '/es_ES/about-us/'],
114
            ['www.example.com', 'es_ES', false, 'staff', '/es_ES/about-us/my-staff/'],
115
            //  - en_US default locale
116
            ['www.example.com', 'en_US', false, 'home', '/'],
117
            ['www.example.com', 'en_US', false, 'about', '/usa/about-us/'],
118
            ['www.example.com', 'en_US', false, 'staff', '/usa/about-us/my-staff/'],
119
            //  - en_US default locale, but with disable_default_prefix on
120
            ['www.example.com', 'en_US', true, 'home', '/'],
121
            ['www.example.com', 'en_US', true, 'about', '/about-us/'],
122
            ['www.example.com', 'en_US', true, 'staff', '/about-us/my-staff/'],
123
124
            // Test cross-domain links include the opposing domain
125
            // - to default locale
126
            ['www.example.de', 'en_US', true, 'home', 'http://www.example.com/'],
127
            ['www.example.de', 'en_US', true, 'staff', 'http://www.example.com/about-us/my-staff/'],
128
            // - to non defalut locale
129
            ['www.example.de', 'es_ES', true, 'home', 'http://www.example.com/es_ES/'],
130
            ['www.example.de', 'es_ES', true, 'staff', 'http://www.example.com/es_ES/about-us/my-staff/'],
131
        ];
132
    }
133
134
    /**
135
     * Test that URLS for pages are generated correctly
136
     *
137
     * @dataProvider provideURLTests
138
     * @param string $domain
139
     * @param string $locale
140
     * @param bool $prefixDisabled
141
     * @param string $pageName
142
     * @param string $url
143
     */
144
    public function testFluentURLs($domain, $locale, $prefixDisabled, $pageName, $url)
145
    {
146
        // Set state
147
        FluentState::singleton()
148
            ->setLocale($locale)
149
            ->setDomain($domain)
150
            ->setIsDomainMode(!empty($domain));
151
        // Set url generation option
152
        Config::modify()
153
            ->set(FluentDirectorExtension::class, 'disable_default_prefix', $prefixDisabled);
154
155
        /** @var Page|FluentSiteTreeExtension $page */
156
        $page = $this->objFromFixture('Page', $pageName);
157
        $this->assertEquals($url, $page->Link());
0 ignored issues
show
Bug introduced by
The method Link() does not exist on TractorCow\Fluent\Extens...FluentSiteTreeExtension. ( Ignorable by Annotation )

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

157
        $this->assertEquals($url, $page->/** @scrutinizer ignore-call */ Link());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
158
    }
159
160
    public function testUpdateStatusFlagsFluentInivisible()
161
    {
162
        /** @var Page|FluentSiteTreeExtension $page */
163
        $page = $this->objFromFixture('Page', 'home');
164
        $flags = $page->getStatusFlags();
0 ignored issues
show
Bug introduced by
The method getStatusFlags() does not exist on TractorCow\Fluent\Extens...FluentSiteTreeExtension. ( Ignorable by Annotation )

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

164
        /** @scrutinizer ignore-call */ 
165
        $flags = $page->getStatusFlags();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
165
166
        $this->assertTrue(array_key_exists('fluentinvisible', $flags));
167
    }
168
169
    public function testStatusMessageNotVisibile()
170
    {
171
        /** @var Page|FluentSiteTreeExtension $page */
172
        $page = $this->objFromFixture('Page', 'home');
173
        $fields = new FieldList();
174
175
        $page->updateCMSFields($fields);
176
177
        /** @var LiteralField $statusMessage */
178
        $statusMessage = $fields->fieldByName('LocaleStatusMessage');
179
180
        $this->assertNotNull($fields->fieldByName('LocaleStatusMessage'));
181
        $this->assertContains('This page is not visible', $statusMessage->getContent());
182
    }
183
184
    public function testStatusMessageInherited()
185
    {
186
        /** @var Page|FluentSiteTreeExtension $page */
187
        $page = $this->objFromFixture('Page', 'home');
188
        $page->config()->update('frontend_publish_required', false);
0 ignored issues
show
Bug introduced by
The method config() does not exist on TractorCow\Fluent\Extens...FluentSiteTreeExtension. ( Ignorable by Annotation )

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

188
        $page->/** @scrutinizer ignore-call */ 
189
               config()->update('frontend_publish_required', false);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
189
        $fields = new FieldList();
190
191
        $page->updateCMSFields($fields);
192
193
        /** @var LiteralField $statusMessage */
194
        $statusMessage = $fields->fieldByName('LocaleStatusMessage');
195
196
        $this->assertNotNull($fields->fieldByName('LocaleStatusMessage'));
197
        $this->assertContains('Content for this page may be inherited', $statusMessage->getContent());
198
    }
199
200
    public function testStatusMessageDrafted()
201
    {
202
        FluentState::singleton()->setLocale('en_NZ');
203
204
        /** @var Page|FluentSiteTreeExtension $page */
205
        $page = $this->objFromFixture('Page', 'home');
206
        $page->config()->update('frontend_publish_required', false);
207
        $page->write();
0 ignored issues
show
Bug introduced by
The method write() does not exist on TractorCow\Fluent\Extens...FluentSiteTreeExtension. ( Ignorable by Annotation )

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

207
        $page->/** @scrutinizer ignore-call */ 
208
               write();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
208
        $fields = new FieldList();
209
210
        $page->updateCMSFields($fields);
211
212
        /** @var LiteralField $statusMessage */
213
        $statusMessage = $fields->fieldByName('LocaleStatusMessage');
214
215
        $this->assertNotNull($fields->fieldByName('LocaleStatusMessage'));
216
        $this->assertContains('A draft has been created for this locale', $statusMessage->getContent());
217
    }
218
219
    public function testUpdateCMSActionsInherited()
220
    {
221
        /** @var Page|FluentSiteTreeExtension $page */
222
        $page = $this->objFromFixture('Page', 'home');
223
        $actions = $page->getCMSActions();
0 ignored issues
show
Bug introduced by
The method getCMSActions() does not exist on TractorCow\Fluent\Extens...FluentSiteTreeExtension. ( Ignorable by Annotation )

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

223
        /** @scrutinizer ignore-call */ 
224
        $actions = $page->getCMSActions();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
224
225
        /** @var \SilverStripe\Forms\CompositeField $majorActions */
226
        $majorActions = $actions->fieldByName('MajorActions');
227
228
        $this->assertNotNull($majorActions);
229
230
        if ($majorActions === null) {
231
            return;
232
        }
233
234
        $actionSave = $majorActions->getChildren()->fieldByName('action_save');
235
        $actionPublish = $majorActions->getChildren()->fieldByName('action_publish');
236
237
        $this->assertNotNull($actionSave);
238
        $this->assertNotNull($actionPublish);
239
240
        if ($actionSave === null || $actionPublish === null) {
241
            return;
242
        }
243
244
        $this->assertEquals('Copy to draft', $actionSave->Title());
245
        $this->assertEquals('Copy & publish', $actionPublish->Title());
246
    }
247
248
    public function testUpdateCMSActionsDrafted()
249
    {
250
        /** @var Page|FluentSiteTreeExtension $page */
251
        $page = $this->objFromFixture('Page', 'about');
252
        $actions = $page->getCMSActions();
253
254
        /** @var \SilverStripe\Forms\CompositeField $majorActions */
255
        $majorActions = $actions->fieldByName('MajorActions');
256
257
        $this->assertNotNull($majorActions);
258
259
        if ($majorActions === null) {
260
            return;
261
        }
262
263
        $actionSave = $majorActions->getChildren()->fieldByName('action_save');
264
        $actionPublish = $majorActions->getChildren()->fieldByName('action_publish');
265
266
        $this->assertNotNull($actionSave);
267
        $this->assertNotNull($actionPublish);
268
269
        if ($actionSave === null || $actionPublish === null) {
270
            return;
271
        }
272
273
        $this->assertEquals('Saved', $actionSave->Title());
274
        // The default value changed between SS 4.0 and 4.1 - assert it contains Publish instead of exact matching
275
        $this->assertContains('publish', strtolower($actionPublish->Title()));
276
    }
277
278
    /**
279
     * @param string $localeCode
280
     * @param string $fixture
281
     * @param string $expected
282
     * @dataProvider localePrefixUrlProvider
283
     */
284
    public function testAddLocalePrefixToUrlSegment($localeCode, $fixture, $expected)
285
    {
286
        FluentState::singleton()
287
            ->setLocale($localeCode)
288
            ->setIsDomainMode(true);
289
290
        /** @var FieldList $fields */
291
        $fields = $this->objFromFixture(Page::class, $fixture)->getCMSFields();
292
293
        /** @var SiteTreeURLSegmentField $segmentField */
294
        $segmentField = $fields->fieldByName('Root.Main.URLSegment');
295
        $this->assertInstanceOf(SiteTreeURLSegmentField::class, $segmentField);
296
297
        $this->assertSame($expected, $segmentField->getURLPrefix());
298
    }
299
300
    public function testHomeVisibleOnFrontendBothConfigFalse()
301
    {
302
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
303
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
304
        FluentState::singleton()->setIsFrontend(true);
305
306
        $page = Page::get()->filter('URLSegment', 'home')->first();
307
308
        $this->assertNotNull($page);
309
    }
310
311
    public function testHomeVisibleOnFrontendOneConfigFalse()
312
    {
313
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
314
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
315
        FluentState::singleton()->setIsFrontend(true);
316
317
        $page = Page::get()->filter('URLSegment', 'home')->first();
318
319
        $this->assertNotNull($page);
320
    }
321
322
    public function testHomeNotVisibleOnFrontendBothConfigTrue()
323
    {
324
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
325
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
326
        FluentState::singleton()->setIsFrontend(true);
327
328
        $page = Page::get()->filter('URLSegment', 'home')->first();
329
330
        $this->assertNull($page);
331
    }
332
333
    public function testHomeNotVisibleOnFrontendOneConfigTrue()
334
    {
335
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
336
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
337
        FluentState::singleton()->setIsFrontend(true);
338
339
        $page = Page::get()->filter('URLSegment', 'home')->first();
340
341
        $this->assertNull($page);
342
    }
343
344
    public function testHomeVisibleInCMSBothConfigFalse()
345
    {
346
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
347
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
348
        FluentState::singleton()->setIsFrontend(false);
349
350
        $page = Page::get()->filter('URLSegment', 'home')->first();
351
352
        $this->assertNotNull($page);
353
    }
354
355
    public function testHomeVisibleInCMSOneConfigFalse()
356
    {
357
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
358
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
359
        FluentState::singleton()->setIsFrontend(false);
360
361
        $page = Page::get()->filter('URLSegment', 'home')->first();
362
363
        $this->assertNotNull($page);
364
    }
365
366
    public function testHomeNotVisibleInCMSBothConfigTrue()
367
    {
368
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
369
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
370
        FluentState::singleton()->setIsFrontend(false);
371
372
        $page = Page::get()->filter('URLSegment', 'home')->first();
373
374
        $this->assertNull($page);
375
    }
376
377
    public function testHomeNotVisibleInCMSOneConfigTrue()
378
    {
379
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
380
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
381
        FluentState::singleton()->setIsFrontend(false);
382
383
        $page = Page::get()->filter('URLSegment', 'home')->first();
384
385
        $this->assertNull($page);
386
    }
387
388
    /**
389
     * @return array[]
390
     */
391
    public function localePrefixUrlProvider()
392
    {
393
        return [
394
            'locale_with_domain' => ['en_US', 'about', 'http://www.example.com/usa/'],
395
            'locale_without_domain' => ['zh_CN', 'about', 'http://mocked/zh_CN/'],
396
            'locale_alone_on_domain_nested' => ['de_DE', 'staff', 'http://www.example.de/about-us/'],
397
        ];
398
    }
399
}
400