Completed
Push — master ( 429519...69a4a3 )
by Damian
17s queued 11s
created

testStatusMessageUnknown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 20
rs 9.8666
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;
0 ignored issues
show
Bug introduced by
The type SilverStripe\CMS\Forms\SiteTreeURLSegmentField 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...
7
use SilverStripe\CMS\Model\SiteTree;
0 ignored issues
show
Bug introduced by
The type SilverStripe\CMS\Model\SiteTree 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...
8
use SilverStripe\Control\Director;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Dev\SapphireTest;
11
use SilverStripe\Forms\FieldList;
12
use SilverStripe\Forms\LiteralField;
13
use SilverStripe\ORM\ArrayList;
14
use SilverStripe\ORM\DataObject;
15
use TractorCow\Fluent\Extension\FluentDirectorExtension;
16
use TractorCow\Fluent\Extension\FluentSiteTreeExtension;
17
use TractorCow\Fluent\Extension\FluentVersionedExtension;
18
use TractorCow\Fluent\Model\Domain;
19
use TractorCow\Fluent\Model\Locale;
20
use TractorCow\Fluent\Model\RecordLocale;
21
use TractorCow\Fluent\State\FluentState;
22
23
// Skip if pages module not installed
24
if (!class_exists(SiteTree::class)) {
25
    return;
26
}
27
28
class FluentSiteTreeExtensionTest extends SapphireTest
29
{
30
    protected static $fixture_file = 'FluentSiteTreeExtensionTest.yml';
31
32
    protected static $required_extensions = [
33
        SiteTree::class => [
34
            FluentSiteTreeExtension::class,
35
        ],
36
    ];
37
38
    protected function setUp()
39
    {
40
        parent::setUp();
41
        Config::modify()
42
            ->set(Director::class, 'alternate_base_url', 'http://mocked')
43
            ->set(FluentDirectorExtension::class, 'disable_default_prefix', false);
44
45
        // Clear cache
46
        Locale::clearCached();
47
        Domain::clearCached();
48
        (new FluentVersionedExtension)->flushCache();
49
50
        FluentState::singleton()
51
            ->setLocale('de_DE')
52
            ->setIsDomainMode(false);
53
    }
54
55
    public function testGetLocaleInformation()
56
    {
57
        FluentState::singleton()->withState(function (FluentState $newState) {
58
            $newState
59
                ->setLocale('de_DE')
60
                ->setIsDomainMode(false);
61
62
            /** @var Page|FluentSiteTreeExtension $page */
63
            $page = $this->objFromFixture(Page::class, 'nz-page');
64
            $result = $page->LocaleInformation('en_NZ');
65
66
            $this->assertInstanceOf(RecordLocale::class, $result);
67
            $this->assertEquals('en_NZ', $result->getLocale());
68
            $this->assertEquals('en-nz', $result->getLocaleRFC1766());
69
            $this->assertEquals('en-nz', $result->getHrefLang());
70
            $this->assertEquals('English (New Zealand)', $result->getTitle());
71
            $this->assertEquals('English', $result->getLanguageNative());
72
            $this->assertEquals('en', $result->getLanguage());
73
            $this->assertEquals('/newzealand/a-page/', $result->getLink());
74
            $this->assertEquals('http://mocked/newzealand/a-page/', $result->getAbsoluteLink());
75
            $this->assertEquals('link', $result->getLinkingMode());
76
            $this->assertEquals('newzealand', $result->getURLSegment());
77
        });
78
    }
79
80
    public function testGetLocales()
81
    {
82
        FluentState::singleton()->withState(function (FluentState $newState) {
83
            $newState
84
                ->setLocale('de_DE')
85
                ->setIsDomainMode(false);
86
87
            /** @var Page|FluentSiteTreeExtension $page */
88
            $page = $this->objFromFixture(Page::class, 'nz-page');
89
            $result = $page->Locales();
90
91
            $this->assertInstanceOf(ArrayList::class, $result);
92
            $this->assertCount(5, $result);
93
            $this->assertListEquals([
94
                ['Locale' => 'en_NZ'],
95
                ['Locale' => 'de_DE'],
96
                ['Locale' => 'en_US'],
97
                ['Locale' => 'es_ES'],
98
                ['Locale' => 'zh_CN'],
99
            ], $result);
0 ignored issues
show
Bug introduced by
$result of type TractorCow\Fluent\Model\RecordLocale[] is incompatible with the type SilverStripe\ORM\SS_List expected by parameter $list of SilverStripe\Dev\SapphireTest::assertListEquals(). ( Ignorable by Annotation )

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

99
            ], /** @scrutinizer ignore-type */ $result);
Loading history...
100
        });
101
    }
102
103
    /**
104
     * Tests for url generation
105
     *
106
     * @return array list of tests with values:
107
     *  - domain (or false for non-domain mode)
108
     *  - locale
109
     *  - disable_default_prefix flag
110
     *  - page id
111
     *  - expected link
112
     */
113
    public function provideURLTests()
114
    {
115
        return [
116
            // Non-domain tests
117
            [null, 'de_DE', false, 'home', '/german/'],
118
            [null, 'de_DE', false, 'about', '/german/about-us/'],
119
            [null, 'de_DE', false, 'staff', '/german/about-us/my-staff/'],
120
            // Since de_DE is the only locale on the www.example.de domain, ensure that the locale
121
            // isn't unnecessarily added to the link.
122
            // In this case disable_default_prefix is ignored
123
            // See https://github.com/tractorcow/silverstripe-fluent/issues/75
124
            ['www.example.de', 'de_DE', false, 'home', '/'],
125
            ['www.example.de', 'de_DE', false, 'about', '/about-us/'],
126
            ['www.example.de', 'de_DE', false, 'staff', '/about-us/my-staff/'],
127
128
            // Test domains with multiple locales
129
            //  - es_ES non default locale
130
            ['www.example.com', 'es_ES', false, 'home', '/es_ES/'],
131
            ['www.example.com', 'es_ES', false, 'about', '/es_ES/about-us/'],
132
            ['www.example.com', 'es_ES', false, 'staff', '/es_ES/about-us/my-staff/'],
133
            //  - en_US default locale
134
            ['www.example.com', 'en_US', false, 'home', '/usa/'],
135
            ['www.example.com', 'en_US', false, 'about', '/usa/about-us/'],
136
            ['www.example.com', 'en_US', false, 'staff', '/usa/about-us/my-staff/'],
137
            //  - en_US default locale, but with disable_default_prefix on
138
            ['www.example.com', 'en_US', true, 'home', '/'],
139
            ['www.example.com', 'en_US', true, 'about', '/about-us/'],
140
            ['www.example.com', 'en_US', true, 'staff', '/about-us/my-staff/'],
141
142
            // Test cross-domain links include the opposing domain
143
            // - to default locale
144
            ['www.example.de', 'en_US', true, 'home', 'http://www.example.com/'],
145
            ['www.example.de', 'en_US', true, 'staff', 'http://www.example.com/about-us/my-staff/'],
146
            // - to non defalut locale
147
            ['www.example.de', 'es_ES', true, 'home', 'http://www.example.com/es_ES/'],
148
            ['www.example.de', 'es_ES', true, 'staff', 'http://www.example.com/es_ES/about-us/my-staff/'],
149
        ];
150
    }
151
152
    /**
153
     * Test that URLS for pages are generated correctly
154
     *
155
     * @dataProvider provideURLTests
156
     * @param string $domain
157
     * @param string $locale
158
     * @param bool $prefixDisabled
159
     * @param string $pageName
160
     * @param string $url
161
     */
162
    public function testFluentURLs($domain, $locale, $prefixDisabled, $pageName, $url)
163
    {
164
        FluentState::singleton()->withState(
165
            function (FluentState $newState) use ($domain, $locale, $prefixDisabled, $pageName, $url) {
166
                $newState
167
                    ->setLocale($locale)
168
                    ->setDomain($domain)
169
                    ->setIsDomainMode(!empty($domain));
170
171
                // Set url generation option
172
                Config::modify()
173
                    ->set(FluentDirectorExtension::class, 'disable_default_prefix', $prefixDisabled);
174
175
                /** @var Page|FluentSiteTreeExtension $page */
176
                $page = $this->objFromFixture(Page::class, $pageName);
177
                $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

177
                $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...
178
            }
179
        );
180
    }
181
182
    public function testUpdateStatusFlagsFluentInvisible()
183
    {
184
        /** @var Page|FluentSiteTreeExtension $page */
185
        $page = $this->objFromFixture(Page::class, 'home');
186
        $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

186
        /** @scrutinizer ignore-call */ 
187
        $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...
187
188
        $this->assertArrayHasKey('fluentinvisible', $flags);
189
    }
190
191
    public function testStatusMessageNotVisible()
192
    {
193
        FluentState::singleton()->withState(function (FluentState $newState) {
194
            $newState
195
                ->setLocale('en_NZ')
196
                ->setIsDomainMode(false);
197
198
            /** @var Page|FluentSiteTreeExtension $page */
199
            $page = $this->objFromFixture(Page::class, 'staff');
200
            $page->config()
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

200
            $page->/** @scrutinizer ignore-call */ 
201
                   config()

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...
201
                ->set('locale_published_status_message', true)
202
                ->set('frontend_publish_required', true);
203
204
            $fields = $page->getCMSFields();
0 ignored issues
show
Bug introduced by
The method getCMSFields() 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

204
            /** @scrutinizer ignore-call */ 
205
            $fields = $page->getCMSFields();

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...
205
206
            /** @var LiteralField $statusMessage */
207
            $statusMessage = $fields->fieldByName('LocaleStatusMessage');
208
209
            $this->assertNotNull($statusMessage, 'Locale message was not added');
210
            $this->assertContains('This page will not be visible', $statusMessage->getContent());
211
        });
212
    }
213
214
    public function testStatusMessageUnknown()
215
    {
216
        FluentState::singleton()->withState(function (FluentState $newState) {
217
            $newState
218
                ->setLocale('en_NZ')
219
                ->setIsDomainMode(false);
220
221
            /** @var Page|FluentSiteTreeExtension $page */
222
            $page = $this->objFromFixture(Page::class, 'home');
223
            $page->config()
224
                ->set('locale_published_status_message', true)
225
                ->set('frontend_publish_required', false);
226
227
            $fields = $page->getCMSFields();
228
229
            /** @var LiteralField $statusMessage */
230
            $statusMessage = $fields->fieldByName('LocaleStatusMessage');
231
232
            $this->assertNotNull($fields->fieldByName('LocaleStatusMessage'));
233
            $this->assertContains('No content is available for this page', $statusMessage->getContent());
234
        });
235
    }
236
237
    public function testStatusMessageDrafted()
238
    {
239
        FluentState::singleton()->withState(function (FluentState $newState) {
240
            $newState
241
                ->setLocale('en_NZ')
242
                ->setIsDomainMode(false);
243
244
            /** @var Page|FluentSiteTreeExtension $page */
245
            $page = $this->objFromFixture(Page::class, 'home');
246
            $page->config()
247
                ->set('locale_published_status_message', true)
248
                ->set('frontend_publish_required', false);
249
            $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

249
            $page->/** @scrutinizer ignore-call */ 
250
                   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...
250
251
            $fields = $page->getCMSFields();
252
253
            /** @var LiteralField $statusMessage */
254
            $statusMessage = $fields->fieldByName('LocaleStatusMessage');
255
256
            $this->assertNotNull($fields->fieldByName('LocaleStatusMessage'));
257
            $this->assertContains('A draft has been created for this locale', $statusMessage->getContent());
258
        });
259
    }
260
261
    public function testUpdateCMSActionsInherited()
262
    {
263
        /** @var Page|FluentSiteTreeExtension $page */
264
        $page = $this->objFromFixture(Page::class, 'home');
265
        $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

265
        /** @scrutinizer ignore-call */ 
266
        $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...
266
267
        /** @var \SilverStripe\Forms\CompositeField $majorActions */
268
        $majorActions = $actions->fieldByName('MajorActions');
269
270
        $this->assertNotNull($majorActions);
271
272
        $actionSave = $majorActions->getChildren()->fieldByName('action_save');
273
        $actionPublish = $majorActions->getChildren()->fieldByName('action_publish');
274
275
        $this->assertNotNull($actionSave);
276
        $this->assertNotNull($actionPublish);
277
278
        $this->assertEquals('Copy to draft', $actionSave->Title());
279
        $this->assertEquals('Copy & publish', $actionPublish->Title());
280
    }
281
282
    public function testUpdateCMSActionsDrafted()
283
    {
284
        /** @var Page|FluentSiteTreeExtension $page */
285
        $page = $this->objFromFixture(Page::class, 'about');
286
        $actions = $page->getCMSActions();
287
288
        /** @var \SilverStripe\Forms\CompositeField $majorActions */
289
        $majorActions = $actions->fieldByName('MajorActions');
290
291
        $this->assertNotNull($majorActions);
292
293
        $actionSave = $majorActions->getChildren()->fieldByName('action_save');
294
        $actionPublish = $majorActions->getChildren()->fieldByName('action_publish');
295
296
        $this->assertNotNull($actionSave);
297
        $this->assertNotNull($actionPublish);
298
299
        $this->assertEquals('Saved', $actionSave->Title());
300
        // The default value changed between SS 4.0 and 4.1 - assert it contains Publish instead of exact matching
301
        $this->assertContains('publish', strtolower($actionPublish->Title()));
302
    }
303
304
    /**
305
     * @param string $localeCode
306
     * @param string $fixture
307
     * @param string $expected
308
     * @dataProvider localePrefixUrlProvider
309
     */
310
    public function testAddLocalePrefixToUrlSegment($localeCode, $fixture, $expected)
311
    {
312
        FluentState::singleton()->withState(
313
            function (FluentState $newState) use ($localeCode, $fixture, $expected) {
314
                $newState
315
                    ->setLocale($localeCode)
316
                    ->setIsDomainMode(true);
317
318
                /** @var FieldList $fields */
319
                $fields = $this->objFromFixture(Page::class, $fixture)->getCMSFields();
320
321
                /** @var SiteTreeURLSegmentField $segmentField */
322
                $segmentField = $fields->fieldByName('Root.Main.URLSegment');
323
                $this->assertInstanceOf(SiteTreeURLSegmentField::class, $segmentField);
324
325
                $this->assertSame($expected, $segmentField->getURLPrefix());
326
            }
327
        );
328
    }
329
330
    public function testHomeVisibleOnFrontendBothConfigFalse()
331
    {
332
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
333
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
334
335
        FluentState::singleton()->withState(function (FluentState $newState) {
336
            $newState
337
                ->setLocale('de_DE')
338
                ->setIsDomainMode(false)
339
                ->setIsFrontend(true);
340
341
            $page = Page::get()->filter('URLSegment', 'home')->first();
342
343
            $this->assertNotNull($page);
344
        });
345
    }
346
347
    public function testHomeVisibleOnFrontendOneConfigFalse()
348
    {
349
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
350
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
351
352
        FluentState::singleton()->withState(function (FluentState $newState) {
353
            $newState
354
                ->setLocale('de_DE')
355
                ->setIsDomainMode(false)
356
                ->setIsFrontend(true);
357
358
            $page = Page::get()->filter('URLSegment', 'home')->first();
359
360
            $this->assertNotNull($page);
361
        });
362
    }
363
364
    public function testHomeNotVisibleOnFrontendBothConfigTrue()
365
    {
366
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
367
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
368
369
        FluentState::singleton()->withState(function (FluentState $newState) {
370
            $newState
371
                ->setLocale('de_DE')
372
                ->setIsDomainMode(false)
373
                ->setIsFrontend(true);
374
375
            $page = Page::get()->filter('URLSegment', 'home')->first();
376
377
            $this->assertNull($page);
378
        });
379
    }
380
381
    public function testHomeNotVisibleOnFrontendOneConfigTrue()
382
    {
383
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
384
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
385
386
        FluentState::singleton()->withState(function (FluentState $newState) {
387
            $newState
388
                ->setLocale('de_DE')
389
                ->setIsDomainMode(false)
390
                ->setIsFrontend(true);
391
392
            $page = Page::get()->filter('URLSegment', 'home')->first();
393
394
            $this->assertNull($page);
395
        });
396
    }
397
398
    public function testHomeVisibleInCMSBothConfigFalse()
399
    {
400
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
401
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
402
403
        FluentState::singleton()->withState(function (FluentState $newState) {
404
            $newState
405
                ->setLocale('de_DE')
406
                ->setIsDomainMode(false)
407
                ->setIsFrontend(false);
408
409
            $page = Page::get()->filter('URLSegment', 'home')->first();
410
411
            $this->assertNotNull($page);
412
        });
413
    }
414
415
    public function testHomeVisibleInCMSOneConfigFalse()
416
    {
417
        Config::modify()->set(DataObject::class, 'cms_publish_required', false);
418
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
419
420
        FluentState::singleton()->withState(function (FluentState $newState) {
421
            $newState
422
                ->setLocale('de_DE')
423
                ->setIsDomainMode(false)
424
                ->setIsFrontend(false);
425
426
            $page = Page::get()->filter('URLSegment', 'home')->first();
427
428
            $this->assertNotNull($page);
429
        });
430
    }
431
432
    public function testHomeNotVisibleInCMSBothConfigTrue()
433
    {
434
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
435
        Config::modify()->set(DataObject::class, 'frontend_publish_required', true);
436
437
        FluentState::singleton()->withState(function (FluentState $newState) {
438
            $newState
439
                ->setLocale('de_DE')
440
                ->setIsDomainMode(false)
441
                ->setIsFrontend(false);
442
443
            $page = Page::get()->filter('URLSegment', 'home')->first();
444
445
            $this->assertNull($page);
446
        });
447
    }
448
449
    public function testHomeNotVisibleInCMSOneConfigTrue()
450
    {
451
        Config::modify()->set(DataObject::class, 'cms_publish_required', true);
452
        Config::modify()->set(DataObject::class, 'frontend_publish_required', false);
453
454
        FluentState::singleton()->withState(function (FluentState $newState) {
455
            $newState
456
                ->setLocale('de_DE')
457
                ->setIsDomainMode(false)
458
                ->setIsFrontend(false);
459
460
            $page = Page::get()->filter('URLSegment', 'home')->first();
461
462
            $this->assertNull($page);
463
        });
464
    }
465
466
    /**
467
     * @return array[]
468
     */
469
    public function localePrefixUrlProvider()
470
    {
471
        return [
472
            'locale_with_domain'            => ['en_US', 'about', 'http://www.example.com/usa/'],
473
            'locale_without_domain'         => ['zh_CN', 'about', 'http://mocked/zh_CN/'],
474
            'locale_alone_on_domain_nested' => ['de_DE', 'staff', 'http://www.example.de/about-us/'],
475
        ];
476
    }
477
}
478