Passed
Pull Request — 4 (#822)
by Steve
04:53
created

testHasBrokenUnbrokenDoesNotOverwriteBrokenSiteTree()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 10
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 12
rs 9.9332
1
<?php
2
3
namespace DNADesign\Elemental\Tests\Extensions;
4
5
use DNADesign\Elemental\Extensions\ElementalAreasExtension;
6
use DNADesign\Elemental\Extensions\ElementalPageExtension;
7
use DNADesign\Elemental\Models\ElementContent;
8
use DNADesign\Elemental\Tests\Src\TestElement;
9
use DNADesign\Elemental\Tests\Src\TestUnusedElement;
10
use SilverStripe\Assets\File;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\CMS\Model\SiteTree;
13
use SilverStripe\Dev\SapphireTest;
14
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
15
use SilverStripe\Forms\LiteralField;
16
17
class ElementalAreasExtensionTest extends SapphireTest
18
{
19
20
    protected $usesDatabase = true;
21
22
    protected static $required_extensions = [
23
        SiteTree::class => [
24
            ElementalPageExtension::class,
25
        ],
26
    ];
27
28
    protected static $extra_dataobjects = [
29
        TestElement::class,
30
        TestUnusedElement::class,
31
    ];
32
33
    protected function setUp()
34
    {
35
        parent::setUp();
36
37
        $this->logInWithPermission('ADMIN');
38
39
        SiteTree::config()
40
            ->set('allowed_elements', [
41
                ElementContent::class,
42
                TestElement::class,
43
                TestUnusedElement::class,
44
            ])
45
            ->set('disallowed_elements', []);
46
    }
47
48
    public function testGetElementalTypesSortsAlphabetically()
49
    {
50
        SiteTree::config()->set('sort_types_alphabetically', true);
51
52
        /** @var SiteTree|ElementalAreasExtension $page */
53
        $page = new SiteTree();
54
        $types = $page->getElementalTypes();
55
56
        $this->assertContainsInOrder(['A test element', 'Content', 'Unused Element'], array_values($types));
57
    }
58
59
    public function testGetElementalTypesAreNotSortedAlphabetically()
60
    {
61
        SiteTree::config()->set('sort_types_alphabetically', false);
62
63
        /** @var SiteTree|ElementalAreasExtension $page */
64
        $page = new SiteTree();
65
        $types = $page->getElementalTypes();
66
67
        $this->assertContainsInOrder(['Content', 'A test element', 'Unused Element'], array_values($types));
68
    }
69
70
    /**
71
     * We need to check that the order of the elements is correct, but there might be more element types installed than
72
     * we're aware of, so we first extract the elements we want from the source list and check the order afterwards.
73
     *
74
     * @param array $expected
75
     * @param array $actual
76
     */
77
    private function assertContainsInOrder(array $expected, array $actual)
78
    {
79
        $matches = array_values(array_intersect($actual, $expected));
80
81
        $this->assertSame($expected, $matches);
82
    }
83
84
    /**
85
     * @dataProvider provideContentFieldPreservationSettings
86
     */
87
    public function testContentFieldsAreRemovedByDefault($keepGlobal, $keepClass, $expectedType)
88
    {
89
        Config::inst()->set(ElementalAreasExtension::class, 'keep_content_fields', $keepGlobal);
0 ignored issues
show
Bug introduced by
The method set() does not exist on SilverStripe\Config\Coll...nfigCollectionInterface. It seems like you code against a sub-type of SilverStripe\Config\Coll...nfigCollectionInterface such as SilverStripe\Config\Coll...nfigCollectionInterface. ( Ignorable by Annotation )

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

89
        Config::inst()->/** @scrutinizer ignore-call */ set(ElementalAreasExtension::class, 'keep_content_fields', $keepGlobal);
Loading history...
90
        Config::inst()->set(SiteTree::class, 'elemental_keep_content_field', $keepClass);
91
        $page = SiteTree::create();
92
        $fields = $page->getCMSFields();
93
        $this->assertInstanceOf($expectedType, $fields->fieldByName('Root.Main.Content'));
94
    }
95
96
    /**
97
     * Provide data for testing both settings and override precedence of Content field replacement
98
     * Settings provided as:
99
     * - ElementalAreasExtension.keep_content_fields (the global setting)
100
     * - SiteTree.elemental_keep_content_field (the class level setting - should take precedence)
101
     * - The expected class of the Field in the FieldList (LiteralField OR HTMLEditorField)
102
     *
103
     * @return array
104
     */
105
    public function provideContentFieldPreservationSettings()
106
    {
107
        // Test both unset (null) and explicitly declined (false) where applicable.
108
        return [
109
            [null, null, LiteralField::class],
110
            [false, false, LiteralField::class],
111
            [true, null, HTMLEditorField::class],
112
            [true, false, LiteralField::class],
113
            [null, true, HTMLEditorField::class],
114
            [false, true, HTMLEditorField::class],
115
            [true, true, HTMLEditorField::class],
116
        ];
117
    }
118
119
    private function setupBrokenData($type)
120
    {
121
        $linkedToPage = SiteTree::create();
122
        $linkedToPage->write();
123
124
        $linkedToFile = File::create();
125
        $linkedToFile->write();
126
127
        $id = $type == 'links' ? $linkedToPage->ID : $linkedToFile->ID;
128
        $shortcode = $type == 'links' ? 'sitetree_link' : 'file_link';
129
        // class="ss-broken"
130
        $broken = '<p>Lorem <a href="[' . $shortcode . ',id=99999]">internal broken ' . $type . '</a> ip</p>';
131
        $unbroken = '<p>Lorem <a href="[' . $shortcode . ',id='. $id .']">internal ' . $type . '</a> ip</p>';
132
133
        $page = SiteTree::create();
134
        $page->Content = $unbroken;
135
        $page->write();
136
137
        $elementalArea = $page->ElementalArea();
138
        $element = ElementContent::create();
139
        $element->HTML = $unbroken;
140
        $element->ParentID = $elementalArea->ID;
141
        $element->write();
142
143
        $page->write();
144
        $this->assertFalse($page->HasBrokenLink);
145
        $this->assertFalse($page->HasBrokenFile);
146
147
        return [
148
            'page' => $page,
149
            'element' => $element,
150
            'broken' => $broken,
151
            'unbroken' => $unbroken
152
        ];
153
    }
154
155
    /**
156
     * Saving the page updates SiteTree->HasBroken from grandchild ElementContent->HasBrokenLink|HasBrokenFile
157
     */
158
    public function testHasBrokenSavingPage()
159
    {
160
        foreach (['links' => 'HasBrokenLink', 'files' => 'HasBrokenFile'] as $type => $field) {
161
            list('page' => $page, 'element' => $element, 'broken' => $broken) = $this->setupBrokenData($type);
162
            $element->HTML = $broken;
163
            $element->write();
164
            $page->write();
165
            $this->assertTrue($page->$field);
166
        }
167
    }
168
169
    /**
170
     * Saving the element does not update grandparent SiteTree->HasBrokenLink|HasBrokenFile
171
     */
172
    public function testHasBrokenSavingElementDoesNotUpdatePage()
173
    {
174
        foreach (['links' => 'HasBrokenLink', 'files' => 'HasBrokenFile'] as $type => $field) {
175
            list('page' => $page, 'element' => $element, 'broken' => $broken) = $this->setupBrokenData($type);
176
            $element->HTML = $broken;
177
            $element->write();
178
            $this->assertFalse($page->$field);
179
        }
180
    }
181
182
    /**
183
     * Fixing a broken element link sets SiteTree->HasBrokenLink|HasBrokenFile to false
184
     */
185
    public function testHasBrokenFixSetsSiteTreeToFalse()
186
    {
187
        foreach (['links' => 'HasBrokenLink', 'files' => 'HasBrokenFile'] as $type => $field) {
188
            list('page' => $page, 'element' => $element, 'broken' => $broken, 'unbroken' => $unbroken)
189
                = $this->setupBrokenData($type);
190
            $element->HTML = $broken;
191
            $element->write();
192
            $page->write();
193
            $this->assertTrue($page->$field);
194
            $element->HTML = $unbroken;
195
            $element->write();
196
            $page->write();
197
            $this->assertFalse($page->$field);
198
        }
199
    }
200
201
    /**
202
     * Unbroken element links do not overwrite SiteTree->HasBrokenLink|HasBrokenFile
203
     */
204
    public function testHasBrokenUnbrokenDoesNotOverwriteBrokenSiteTree()
205
    {
206
        foreach (['links' => 'HasBrokenLink', 'files' => 'HasBrokenFile'] as $type => $field) {
207
            list('page' => $page, 'element' => $element, 'broken' => $broken, 'unbroken' => $unbroken)
208
                = $this->setupBrokenData($type);
209
            $page->Content = $broken;
210
            $page->write();
211
            $this->assertTrue($page->$field);
212
            $element->HTML = $unbroken;
213
            $element->write();
214
            $page->write();
215
            $this->assertTrue($page->$field);
216
        }
217
    }
218
}
219