silverstripe /
silverstripe-elemental
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace DNADesign\Elemental\Tests\TopPage; |
||||
| 4 | |||||
| 5 | use DNADesign\Elemental\Extensions\ElementalAreasExtension; |
||||
| 6 | use DNADesign\Elemental\Extensions\ElementalPageExtension; |
||||
| 7 | use DNADesign\Elemental\Models\BaseElement; |
||||
| 8 | use DNADesign\Elemental\Models\ElementalArea; |
||||
| 9 | use DNADesign\Elemental\TopPage; |
||||
| 10 | use Page; |
||||
| 11 | use SilverStripe\Dev\SapphireTest; |
||||
| 12 | use SilverStripe\ORM\DataObject; |
||||
| 13 | |||||
| 14 | class TopPageTest extends SapphireTest |
||||
| 15 | { |
||||
| 16 | /** |
||||
| 17 | * @var string |
||||
| 18 | */ |
||||
| 19 | protected static $fixture_file = 'TopPageTest.yml'; |
||||
| 20 | |||||
| 21 | /** |
||||
| 22 | * @var array |
||||
| 23 | */ |
||||
| 24 | protected static $required_extensions = [ |
||||
| 25 | TestBlockPage::class => [ |
||||
| 26 | ElementalPageExtension::class, |
||||
| 27 | ], |
||||
| 28 | TestChildPage::class => [ |
||||
| 29 | ElementalPageExtension::class, |
||||
| 30 | ], |
||||
| 31 | Page::class => [ |
||||
| 32 | TopPage\SiteTreeExtension::class, |
||||
| 33 | ], |
||||
| 34 | ElementalArea::class => [ |
||||
| 35 | TopPage\DataExtension::class, |
||||
| 36 | ], |
||||
| 37 | BaseElement::class => [ |
||||
| 38 | TopPage\DataExtension::class, |
||||
| 39 | ], |
||||
| 40 | TestList::class => [ |
||||
| 41 | ElementalAreasExtension::class, |
||||
| 42 | ], |
||||
| 43 | ]; |
||||
| 44 | |||||
| 45 | /** |
||||
| 46 | * @var array |
||||
| 47 | */ |
||||
| 48 | protected static $extra_dataobjects = [ |
||||
| 49 | TestContent::class, |
||||
| 50 | TestList::class, |
||||
| 51 | TestBlockPage::class, |
||||
| 52 | TestChildPage::class, |
||||
| 53 | ]; |
||||
| 54 | |||||
| 55 | /** |
||||
| 56 | * @param string $pageIdentifier |
||||
| 57 | * @param string $pageClass |
||||
| 58 | * @param string $objectIdentifier |
||||
| 59 | * @param string $objectClass |
||||
| 60 | * @dataProvider objectsProvider |
||||
| 61 | */ |
||||
| 62 | public function testTestGetTopPage( |
||||
| 63 | string $pageIdentifier, |
||||
| 64 | string $pageClass, |
||||
| 65 | string $objectIdentifier, |
||||
| 66 | string $objectClass |
||||
| 67 | ): void { |
||||
| 68 | /** @var Page|TopPage\SiteTreeExtension $content */ |
||||
| 69 | $page = $this->objFromFixture($pageClass, $pageIdentifier); |
||||
| 70 | |||||
| 71 | /** @var DataObject|TopPage\DataExtension $object */ |
||||
| 72 | $object = $this->objFromFixture($objectClass, $objectIdentifier); |
||||
| 73 | |||||
| 74 | $topPage = $object->getTopPage(); |
||||
| 75 | |||||
| 76 | $this->assertNotNull($topPage); |
||||
| 77 | $this->assertEquals((int) $page->ID, (int) $topPage->ID); |
||||
| 78 | } |
||||
| 79 | |||||
| 80 | /** |
||||
| 81 | * @param string $pageIdentifier |
||||
| 82 | * @param string $pageClass |
||||
| 83 | * @param string $objectIdentifier |
||||
| 84 | * @param string $objectClass |
||||
| 85 | * @dataProvider objectsProvider |
||||
| 86 | */ |
||||
| 87 | public function testTestUpdateTopPageEmptyCache( |
||||
| 88 | string $pageIdentifier, |
||||
| 89 | string $pageClass, |
||||
| 90 | string $objectIdentifier, |
||||
| 91 | string $objectClass |
||||
| 92 | ): void { |
||||
| 93 | /** @var TopPage\DataExtension $extension */ |
||||
| 94 | $extension = singleton(TopPage\DataExtension::class); |
||||
| 95 | $extension->withTopPageUpdate( |
||||
| 96 | true, |
||||
| 97 | function () use ($pageIdentifier, $pageClass, $objectIdentifier, $objectClass): void { |
||||
| 98 | /** @var Page|TopPage\SiteTreeExtension $content */ |
||||
| 99 | $page = $this->objFromFixture($pageClass, $pageIdentifier); |
||||
| 100 | |||||
| 101 | /** @var DataObject|TopPage\DataExtension $object */ |
||||
| 102 | $object = $this->objFromFixture($objectClass, $objectIdentifier); |
||||
| 103 | |||||
| 104 | $this->assertEquals(0, (int) $object->TopPageID); |
||||
| 105 | |||||
| 106 | $object->forceChange(); |
||||
| 107 | $id = $object->write(); |
||||
| 108 | $object = DataObject::get($object->ClassName)->byID($id); |
||||
| 109 | |||||
| 110 | $this->assertEquals((int) $page->ID, (int) $object->TopPageID); |
||||
| 111 | |||||
| 112 | // do a second write to make sure that we won't override existing top page |
||||
| 113 | $object->forceChange(); |
||||
| 114 | $id = $object->write(); |
||||
| 115 | $object = DataObject::get($object->ClassName)->byID($id); |
||||
| 116 | |||||
| 117 | $this->assertEquals((int) $page->ID, (int) $object->TopPageID); |
||||
| 118 | } |
||||
| 119 | ); |
||||
| 120 | } |
||||
| 121 | |||||
| 122 | public function testNewPage(): void |
||||
| 123 | { |
||||
| 124 | /** @var TopPage\DataExtension $extension */ |
||||
| 125 | $extension = singleton(TopPage\DataExtension::class); |
||||
| 126 | $extension->withTopPageUpdate( |
||||
| 127 | true, |
||||
| 128 | function (): void { |
||||
| 129 | $page = TestBlockPage::create(); |
||||
| 130 | $page->Title = 'New page test'; |
||||
| 131 | $page->write(); |
||||
| 132 | |||||
| 133 | /** @var ElementalArea|TopPage\DataExtension $area */ |
||||
| 134 | $area = $page->ElementalArea(); |
||||
| 135 | $this->assertEquals((int) $page->ID, (int) $area->TopPageID); |
||||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||
| 136 | } |
||||
| 137 | ); |
||||
| 138 | } |
||||
| 139 | |||||
| 140 | /** |
||||
| 141 | * @param bool $populateTopPage |
||||
| 142 | * @dataProvider populateTopPageProvider |
||||
| 143 | */ |
||||
| 144 | public function testNewBlock(bool $populateTopPage): void |
||||
| 145 | { |
||||
| 146 | /** @var TopPage\DataExtension $extension */ |
||||
| 147 | $extension = singleton(TopPage\DataExtension::class); |
||||
| 148 | $extension->withTopPageUpdate( |
||||
| 149 | true, |
||||
| 150 | function () use ($populateTopPage): void { |
||||
| 151 | if ($populateTopPage) { |
||||
| 152 | $this->populateTopPageForAllObjects(); |
||||
| 153 | } |
||||
| 154 | |||||
| 155 | /** @var TestBlockPage $page */ |
||||
| 156 | $page = $this->objFromFixture(TestBlockPage::class, 'block-page1'); |
||||
| 157 | |||||
| 158 | /** @var ElementalArea $area */ |
||||
| 159 | $area = $this->objFromFixture(ElementalArea::class, 'area3'); |
||||
| 160 | |||||
| 161 | /** @var TestContent|TopPage\DataExtension $content */ |
||||
| 162 | $content = TestContent::create(); |
||||
| 163 | $content->Title = 'Fresh block'; |
||||
|
0 ignored issues
–
show
|
|||||
| 164 | |||||
| 165 | $area->Elements()->add($content); |
||||
|
0 ignored issues
–
show
It seems like
$content can also be of type DNADesign\Elemental\TopPage\DataExtension; however, parameter $item of SilverStripe\ORM\HasManyList::add() does only seem to accept SilverStripe\ORM\DataObject|integer, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 166 | $content = DataObject::get($content->ClassName)->byID($content->ID); |
||||
|
0 ignored issues
–
show
|
|||||
| 167 | |||||
| 168 | $this->assertEquals((int) $page->ID, (int) $content->TopPageID); |
||||
| 169 | } |
||||
| 170 | ); |
||||
| 171 | } |
||||
| 172 | |||||
| 173 | /** |
||||
| 174 | * This test is checking for page duplication in two cases |
||||
| 175 | * Case 1: standard duplication |
||||
| 176 | * Case 2: duplication with a fixed page setting |
||||
| 177 | * The seconds case shows that it's possible to use the withFixedTopPage to set the top page to arbitrary value |
||||
| 178 | * and completely bypass page determination logic |
||||
| 179 | * This is needed in some edge cases were automatic determination is not possible due to the object not being |
||||
| 180 | * assigned to the parent object at the time of duplication but rather later |
||||
| 181 | * |
||||
| 182 | * @param int $fixedPageID |
||||
| 183 | * @dataProvider fixedPagesProvider |
||||
| 184 | */ |
||||
| 185 | public function testPageDuplication(int $fixedPageID): void |
||||
| 186 | { |
||||
| 187 | /** @var TopPage\DataExtension $extension */ |
||||
| 188 | $extension = singleton(TopPage\DataExtension::class); |
||||
| 189 | $extension->withFixedTopPage($fixedPageID, function () use ($extension, $fixedPageID) { |
||||
| 190 | $extension->withTopPageUpdate( |
||||
| 191 | true, |
||||
| 192 | function () use ($fixedPageID): void { |
||||
| 193 | $this->populateTopPageForAllObjects(); |
||||
| 194 | |||||
| 195 | /** @var TestBlockPage $page */ |
||||
| 196 | $page = $this->objFromFixture(TestBlockPage::class, 'block-page1'); |
||||
| 197 | |||||
| 198 | /** @var TestChildPage $childPage */ |
||||
| 199 | $childPage = $this->objFromFixture(TestChildPage::class, 'child-page1'); |
||||
| 200 | |||||
| 201 | $page->duplicate(); |
||||
| 202 | $pages = TestBlockPage::get()->filter(['Title' => 'BlockPage1'])->sort('ID', 'DESC'); |
||||
| 203 | |||||
| 204 | $this->assertCount(2, $pages); |
||||
| 205 | |||||
| 206 | $pageClone = $pages->first(); |
||||
| 207 | $childPages = TestChildPage::get()->filter(['Title' => 'ChildPage1'])->sort('ID', 'DESC'); |
||||
| 208 | |||||
| 209 | $this->assertCount(2, $childPages); |
||||
| 210 | |||||
| 211 | $childClone = $childPages->first(); |
||||
| 212 | |||||
| 213 | $this->assertNotEquals((int) $childPage->ID, (int) $childClone->ID); |
||||
| 214 | |||||
| 215 | $objects = [ |
||||
| 216 | [TestList::class, 'List1', $pageClone], |
||||
| 217 | [TestContent::class, 'Content1', $pageClone], |
||||
| 218 | [TestList::class, 'List2', $childClone], |
||||
| 219 | [TestContent::class, 'Content2', $childClone], |
||||
| 220 | ]; |
||||
| 221 | |||||
| 222 | foreach ($objects as $objectData) { |
||||
| 223 | $class = array_shift($objectData); |
||||
| 224 | $title = array_shift($objectData); |
||||
| 225 | $page = array_shift($objectData); |
||||
| 226 | |||||
| 227 | $items = DataObject::get($class)->filter(['Title' => $title])->sort('ID', 'DESC'); |
||||
| 228 | |||||
| 229 | $this->assertCount(2, $items); |
||||
| 230 | |||||
| 231 | /** @var DataObject|TopPage\DataExtension $objectClone */ |
||||
| 232 | $objectClone = $items->first(); |
||||
| 233 | |||||
| 234 | $expected = $fixedPageID ?: (int) $page->ID; |
||||
| 235 | $this->assertEquals($expected, (int) $objectClone->TopPageID); |
||||
| 236 | |||||
| 237 | /** @var ElementalArea|TopPage\DataExtension $area */ |
||||
| 238 | $area = $objectClone->Parent(); |
||||
| 239 | |||||
| 240 | $this->assertEquals($expected, (int) $area->TopPageID); |
||||
|
0 ignored issues
–
show
The property
TopPageID does not exist on DNADesign\Elemental\Models\ElementalArea. Since you implemented __get, consider adding a @property annotation.
Loading history...
|
|||||
| 241 | } |
||||
| 242 | } |
||||
| 243 | ); |
||||
| 244 | }); |
||||
| 245 | } |
||||
| 246 | |||||
| 247 | public function objectsProvider(): array |
||||
| 248 | { |
||||
| 249 | return [ |
||||
| 250 | [ |
||||
| 251 | 'block-page1', |
||||
| 252 | TestBlockPage::class, |
||||
| 253 | 'content1', |
||||
| 254 | TestContent::class, |
||||
| 255 | ], |
||||
| 256 | [ |
||||
| 257 | 'block-page1', |
||||
| 258 | TestBlockPage::class, |
||||
| 259 | 'list1', |
||||
| 260 | TestList::class, |
||||
| 261 | ], |
||||
| 262 | [ |
||||
| 263 | 'block-page1', |
||||
| 264 | TestBlockPage::class, |
||||
| 265 | 'area1', |
||||
| 266 | ElementalArea::class, |
||||
| 267 | ], |
||||
| 268 | [ |
||||
| 269 | 'block-page1', |
||||
| 270 | TestBlockPage::class, |
||||
| 271 | 'area3', |
||||
| 272 | ElementalArea::class, |
||||
| 273 | ], |
||||
| 274 | [ |
||||
| 275 | 'child-page1', |
||||
| 276 | TestChildPage::class, |
||||
| 277 | 'content2', |
||||
| 278 | TestContent::class, |
||||
| 279 | ], |
||||
| 280 | [ |
||||
| 281 | 'child-page1', |
||||
| 282 | TestChildPage::class, |
||||
| 283 | 'list2', |
||||
| 284 | TestList::class, |
||||
| 285 | ], |
||||
| 286 | [ |
||||
| 287 | 'child-page1', |
||||
| 288 | TestChildPage::class, |
||||
| 289 | 'area2', |
||||
| 290 | ElementalArea::class, |
||||
| 291 | ], |
||||
| 292 | [ |
||||
| 293 | 'child-page1', |
||||
| 294 | TestChildPage::class, |
||||
| 295 | 'area4', |
||||
| 296 | ElementalArea::class, |
||||
| 297 | ], |
||||
| 298 | ]; |
||||
| 299 | } |
||||
| 300 | |||||
| 301 | public function populateTopPageProvider(): array |
||||
| 302 | { |
||||
| 303 | return [ |
||||
| 304 | [true], |
||||
| 305 | [false], |
||||
| 306 | ]; |
||||
| 307 | } |
||||
| 308 | |||||
| 309 | public function fixedPagesProvider(): array |
||||
| 310 | { |
||||
| 311 | return [ |
||||
| 312 | [0], // feature is disabled |
||||
| 313 | [99], // obviously non-existent page |
||||
| 314 | ]; |
||||
| 315 | } |
||||
| 316 | |||||
| 317 | private function populateTopPageForAllObjects(): void |
||||
| 318 | { |
||||
| 319 | $list = $this->objectsProvider(); |
||||
| 320 | |||||
| 321 | foreach ($list as $objects) { |
||||
| 322 | array_shift($objects); |
||||
| 323 | array_shift($objects); |
||||
| 324 | $identifier = array_shift($objects); |
||||
| 325 | $class = array_shift($objects); |
||||
| 326 | |||||
| 327 | $object = $this->objFromFixture($class, $identifier); |
||||
| 328 | $object->forceChange(); |
||||
| 329 | $object->write(); |
||||
| 330 | } |
||||
| 331 | } |
||||
| 332 | } |
||||
| 333 |