SiteTreeBacklinksTest   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 348
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 181
dl 0
loc 348
rs 10
c 0
b 0
f 0
wmc 9

9 Methods

Rating   Name   Duplication   Size   Complexity  
A testSavingPageWithLinkAddsBacklink() 0 22 1
A testRemovingLinkFromPageRemovesBacklink() 0 21 1
A testPublishingPageWithModifiedUrlRewritesLink() 0 45 1
A testLinkTrackingOnExtraContentFields() 0 62 1
A testLinkTrackingWithUntitledObjectsDisplaysAReadableIdentifier() 0 22 1
A testChangingUrlOnDraftSiteRewritesLink() 0 30 1
A setUp() 0 15 1
A testPublishingPageWithModifiedLinksRewritesLinks() 0 54 1
A testChangingUrlOnLiveSiteRewritesLink() 0 41 1
1
<?php
2
3
namespace SilverStripe\CMS\Tests\Model;
4
5
use SilverStripe\CMS\Model\SiteTree;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Control\HTTP;
8
use SilverStripe\Dev\SapphireTest;
9
use SilverStripe\Forms\GridField\GridField;
10
use SilverStripe\Versioned\Versioned;
11
12
/**
13
 * Tests {@see SiteTreeLinkTracking} broken links feature: LinkTracking
14
 */
15
class SiteTreeBacklinksTest extends SapphireTest
16
{
17
    protected static $fixture_file = "SiteTreeBacklinksTest.yml";
18
19
    protected static $required_extensions = [
20
        SiteTree::class => [
21
            SiteTreeBacklinksTest_DOD::class,
22
        ],
23
    ];
24
25
    protected static $extra_dataobjects = [
26
        SiteTreeBacklinksTestContentObject::class,
27
    ];
28
29
    protected function setUp() : void
30
    {
31
        parent::setUp();
32
33
        // Log in as admin so that we don't run into permission issues.  That's not what we're
34
        // testing here.
35
        $this->logInWithPermission('ADMIN');
36
37
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
38
        $page3->Content = str_replace(
39
            '$page1.ID',
40
            $this->objFromFixture(SiteTree::class, 'page1')->ID,
41
            $page3->Content
42
        );
43
        $page3->write();
44
    }
45
46
    public function testSavingPageWithLinkAddsBacklink()
47
    {
48
        // load page 1
49
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
50
51
        // assert backlink to page 2 doesn't exist
52
        $page2 = $this->objFromFixture(SiteTree::class, 'page2');
53
        $this->assertNotContains(
54
            $page2->ID,
55
            $page1->BackLinkTracking()->column('ID'),
56
            'Assert backlink to page 2 doesn\'t exist'
57
        );
58
59
        // add hyperlink to page 1 on page 2
60
        $page2->Content .= '<p><a href="[sitetree_link,id=' . $page1->ID . ']">Testing page 1 link</a></p>';
61
        $page2->write();
62
63
        // load page 1
64
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
65
66
        // assert backlink to page 2 exists
67
        $this->assertContains($page2->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 2 exists');
68
    }
69
70
    public function testRemovingLinkFromPageRemovesBacklink()
71
    {
72
        // load page 1
73
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
74
75
        // assert backlink to page 3 exits
76
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
77
        $this->assertContains($page3->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 3 exists');
78
79
        // remove hyperlink to page 1
80
        $page3->Content = '<p>No links anymore!</p>';
81
        $page3->write();
82
83
        // load page 1
84
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
85
86
        // assert backlink to page 3 exists
87
        $this->assertNotContains(
88
            $page3->ID,
89
            $page1->BackLinkTracking()->column('ID'),
90
            'Assert backlink to page 3 doesn\'t exist'
91
        );
92
    }
93
94
    public function testChangingUrlOnDraftSiteRewritesLink()
95
    {
96
        // load page 1
97
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
98
99
        // assert backlink to page 3 exists
100
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
101
        $this->assertContains($page3->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 3 exists');
102
103
        // assert hyperlink to page 1's current url exists on page 3
104
        $links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
105
        $this->assertContains(
106
            Director::baseURL() . 'page1/',
107
            $links,
108
            'Assert hyperlink to page 1\'s current url exists on page 3'
109
        );
110
111
        // change url of page 1
112
        $page1->URLSegment = 'new-url-segment';
113
        $page1->write();
114
115
        // load page 3
116
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
117
118
        // assert hyperlink to page 1's new url exists
119
        $links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
120
        $this->assertContains(
121
            Director::baseURL() . 'new-url-segment/',
122
            $links,
123
            'Assert hyperlink to page 1\'s new url exists on page 3'
124
        );
125
    }
126
127
    public function testChangingUrlOnLiveSiteRewritesLink()
128
    {
129
        // publish page 1 & 3
130
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
131
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
132
        $this->assertTrue($page1->publishRecursive());
133
        $this->assertTrue($page3->publishRecursive());
134
135
        // load pages from live
136
        $page1live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page1->ID);
137
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
138
139
        // assert backlink to page 3 exists
140
        $this->assertContains(
141
            $page3live->ID,
142
            $page1live->BackLinkTracking()->column('ID'),
143
            'Assert backlink to page 3 exists'
144
        );
145
146
        // assert hyperlink to page 1's current url exists on page 3
147
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
148
        $this->assertContains(
149
            Director::baseURL() . 'page1/',
150
            $links,
151
            'Assert hyperlink to page 1\'s current url exists on page 3'
152
        );
153
154
        // change url of page 1
155
        $page1live->URLSegment = 'new-url-segment';
156
        $page1live->writeToStage('Live');
157
158
        // load page 3 from live
159
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
160
161
        // assert hyperlink to page 1's new url exists
162
        Versioned::set_stage(Versioned::LIVE);
163
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
164
        $this->assertContains(
165
            Director::baseURL() . 'new-url-segment/',
166
            $links,
167
            'Assert hyperlink to page 1\'s new url exists on page 3'
168
        );
169
    }
170
171
    public function testPublishingPageWithModifiedUrlRewritesLink()
172
    {
173
        // publish page 1 & 3
174
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
175
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
176
177
        $this->assertTrue($page1->publishRecursive());
178
        $this->assertTrue($page3->publishRecursive());
179
180
        // load page 3 from live
181
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
182
183
        // assert hyperlink to page 1's current url exists
184
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
185
        $this->assertContains(
186
            Director::baseURL() . 'page1/',
187
            $links,
188
            'Assert hyperlink to page 1\'s current url exists on page 3'
189
        );
190
191
        // rename url of page 1 on stage
192
        $page1->URLSegment = 'new-url-segment';
193
        $page1->write();
194
195
        // assert hyperlink to page 1's current publish url exists
196
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
197
        Versioned::set_stage(Versioned::LIVE);
198
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
199
        $this->assertContains(
200
            Director::baseURL() . 'page1/',
201
            $links,
202
            'Assert hyperlink to page 1\'s current published url exists on page 3'
203
        );
204
205
206
        // publish page 1
207
        $this->assertTrue($page1->publishRecursive());
208
209
        // assert hyperlink to page 1's new published url exists
210
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
211
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
212
        $this->assertContains(
213
            Director::baseURL() . 'new-url-segment/',
214
            $links,
215
            'Assert hyperlink to page 1\'s new published url exists on page 3'
216
        );
217
    }
218
219
    public function testPublishingPageWithModifiedLinksRewritesLinks()
220
    {
221
        // publish page 1 & 3
222
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
223
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
224
        $this->assertTrue($page1->publishRecursive());
225
        $this->assertTrue($page3->publishRecursive());
226
227
        // assert hyperlink to page 1's current url exists
228
        $links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
229
        $this->assertContains(
230
            Director::baseURL() . 'page1/',
231
            $links,
232
            'Assert hyperlink to page 1\'s current published url exists on page 3'
233
        );
234
235
        // change page 1 url on draft
236
        $page1->URLSegment = 'new-url-segment';
237
238
        // save page 1
239
        $page1->write();
240
241
        // assert page 3 on draft contains new page 1 url
242
        $page3 = $this->objFromFixture(SiteTree::class, 'page3');
243
        $links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
244
        $this->assertContains(
245
            Director::baseURL() . 'new-url-segment/',
246
            $links,
247
            'Assert hyperlink to page 1\'s current draft url exists on page 3'
248
        );
249
250
        // publish page 3
251
        $this->assertTrue($page3->publishRecursive());
252
253
        // assert page 3 on published site contains old page 1 url
254
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
255
        Versioned::set_stage(Versioned::LIVE);
256
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
257
        $this->assertContains(
258
            Director::baseURL() . 'page1/',
259
            $links,
260
            'Assert hyperlink to page 1\'s current published url exists on page 3'
261
        );
262
263
        // publish page 1
264
        $this->assertTrue($page1->publishRecursive());
265
266
        // assert page 3 on published site contains new page 1 url
267
        $page3live = Versioned::get_one_by_stage(SiteTree::class, 'Live', '"SiteTree"."ID" = ' . $page3->ID);
268
        $links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
269
        $this->assertContains(
270
            Director::baseURL() . 'new-url-segment/',
271
            $links,
272
            'Assert hyperlink to page 1\'s current published url exists on page 3'
273
        );
274
    }
275
276
    public function testLinkTrackingOnExtraContentFields()
277
    {
278
        /** @var SiteTree $page1 */
279
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
280
        /** @var SiteTree $page2 */
281
        $page2 = $this->objFromFixture(SiteTree::class, 'page2');
282
        $page1->publishRecursive();
283
        $page2->publishRecursive();
284
285
        // assert backlink to page 2 doesn't exist
286
        $this->assertNotContains(
287
            $page2->ID,
288
            $page1->BackLinkTracking()->column('ID'),
289
            'Assert backlink to page 2 doesn\'t exist'
290
        );
291
292
        // add hyperlink to page 1 on page 2
293
        $page2->ExtraContent .= '<p><a href="[sitetree_link,id=' . $page1->ID . ']">Testing page 1 link</a></p>';
294
        $page2->write();
295
        $page2->publishRecursive();
296
297
        // assert backlink to page 2 exists
298
        $this->assertContains($page2->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 2 exists');
299
300
        // update page1 url
301
        $page1 = $this->objFromFixture(SiteTree::class, 'page1');
302
        $page1->URLSegment = "page1-new-url";
303
        $page1->write();
304
305
        // confirm that draft link on page2 has been rewritten
306
        $page2 = $this->objFromFixture(SiteTree::class, 'page2');
307
        $this->assertEquals(
308
            '<p><a href="' . Director::baseURL() . 'page1-new-url/">Testing page 1 link</a></p>',
309
            $page2->obj('ExtraContent')->forTemplate()
310
        );
311
312
        // confirm that published link hasn't
313
        $page2Live = Versioned::get_one_by_stage(SiteTree::class, "Live", "\"SiteTree\".\"ID\" = $page2->ID");
314
        Versioned::set_stage(Versioned::LIVE);
315
        $this->assertEquals(
316
            '<p><a href="' . Director::baseURL() . 'page1/">Testing page 1 link</a></p>',
317
            $page2Live->obj('ExtraContent')->forTemplate()
318
        );
319
320
        // publish page1 and confirm that the link on the published page2 has now been updated
321
        $page1->publishRecursive();
322
        $page2Live = Versioned::get_one_by_stage(SiteTree::class, "Live", "\"SiteTree\".\"ID\" = $page2->ID");
323
        $this->assertEquals(
324
            '<p><a href="' . Director::baseURL() . 'page1-new-url/">Testing page 1 link</a></p>',
325
            $page2Live->obj('ExtraContent')->forTemplate()
326
        );
327
328
        // Edit draft again
329
        Versioned::set_stage(Versioned::DRAFT);
330
        $page2->ExtraContent = '<p>No links anymore!</p>';
331
        $page2->write();
332
333
        // assert backlink to page 2 no longer exists
334
        $this->assertNotContains(
335
            $page2->ID,
336
            $page1->BackLinkTracking()->column('ID'),
337
            'Assert backlink to page 2 has been removed'
338
        );
339
    }
340
341
    public function testLinkTrackingWithUntitledObjectsDisplaysAReadableIdentifier()
342
    {
343
        $page = $this->objFromFixture(SiteTree::class, 'page2');
344
345
        $referencingObject = new SiteTreeBacklinksTestContentObject();
346
        $referencingObject->Content = '<p><a href="[sitetree_link,id='
0 ignored issues
show
Bug Best Practice introduced by
The property Content does not exist on SilverStripe\CMS\Tests\M...klinksTestContentObject. Since you implemented __set, consider adding a @property annotation.
Loading history...
347
            . $page->ID
348
            . ']">Page 2</a></p>';
349
        // Title purposely not set - this is the coverage case for this test
350
        $referencingObject->write();
351
352
        /** @var GridField $gridField */
353
        $gridField = $page->getCMSFields()->dataFieldByName('DependentPages');
354
355
        // Prepare and sanity check
356
        $this->assertNotNull($gridField);
357
        $list = $gridField->getList();
358
        $this->assertEquals(1, $list->count());
359
360
        $content = $gridField->getColumnContent($list->first(), 'Title');
361
362
        $this->assertStringContainsString('Untitled Backlink test content object', $content);
363
    }
364
}
365