ENH Add tests for Hierarchy extension when applied to a subclass

This commit is contained in:
Michal Kleiner 2021-09-25 00:17:25 +12:00
parent 1e5414eac7
commit 7226d7fab6
6 changed files with 199 additions and 1 deletions

View File

@ -12,6 +12,8 @@ use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\TreeDropdownField;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestObject;
use SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject;
use SilverStripe\ORM\Tests\HierarchyTest\TestObject;
class TreeDropdownFieldTest extends SapphireTest
@ -20,7 +22,9 @@ class TreeDropdownFieldTest extends SapphireTest
protected static $fixture_file = 'TreeDropdownFieldTest.yml';
protected static $extra_dataobjects = [
TestObject::class
TestObject::class,
HierarchyOnSubclassTestObject::class,
HierarchyOnSubclassTestSubObject::class,
];
public function testSchemaStateDefaults()
@ -137,6 +141,37 @@ class TreeDropdownFieldTest extends SapphireTest
$this->assertEquals($expectedNodeIDs, $actualNodeIDs);
}
public function testTreeSearchJsonFlatlistWithLowNodeThresholdUsingSubObject()
{
// Initialise our TreeDropDownField
$field = new TreeDropdownField('TestTree', 'Test tree - Hierarchy on subclass', HierarchyOnSubclassTestSubObject::class);
$field->config()->set('node_threshold_total', 2);
// Search for all Test object matching our criteria
$request = new HTTPRequest(
'GET',
'url',
['search' => 'SubObject', 'format' => 'json', 'flatList' => '1']
);
$request->setSession(new Session([]));
$response = $field->tree($request);
$tree = json_decode($response->getBody(), true);
$actualNodeIDs = array_column($tree['children'], 'id');
// Get the list of expected node IDs from the YML Fixture
$expectedNodeIDs = array_map(
function ($key) {
return $this->objFromFixture(HierarchyOnSubclassTestSubObject::class, $key)->ID;
},
['four', 'fourB', 'fourA2'] // Those are the identifiers of the object we expect our search to find
);
sort($actualNodeIDs);
sort($expectedNodeIDs);
$this->assertEquals($expectedNodeIDs, $actualNodeIDs);
}
public function testTreeSearch()
{
$field = new TreeDropdownField('TestTree', 'Test tree', Folder::class);
@ -233,6 +268,39 @@ class TreeDropdownFieldTest extends SapphireTest
);
}
public function testTreeSearchUsingSubObject()
{
$field = new TreeDropdownField('TestTree', 'Test tree', HierarchyOnSubclassTestSubObject::class);
// case-insensitive search against keyword 'SubObject' for objects that have Hierarchy extension
// applied to a class that doesn't directly inherit from DataObject
$request = new HTTPRequest('GET', 'url', ['search' => 'SubObject']);
$request->setSession(new Session([]));
$response = $field->tree($request);
$tree = $response->getBody();
$subObject1 = $this->objFromFixture(HierarchyOnSubclassTestSubObject::class, 'four');
$subObject1ChildB = $this->objFromFixture(HierarchyOnSubclassTestSubObject::class, 'fourB');
$parser = new CSSContentParser($tree);
$cssPath = 'ul.tree li#selector-TestTree-' . $subObject1->ID . ' li#selector-TestTree-' . $subObject1ChildB->ID . ' a';
$firstResult = $parser->getBySelector($cssPath);
$this->assertEquals(
$subObject1ChildB->Name,
(string)$firstResult[0],
$subObject1ChildB->Name . ' is found, nested under ' . $subObject1->Name
);
// other objects which don't contain the keyword 'SubObject' are not returned in search results
$subObject2 = $this->objFromFixture(HierarchyOnSubclassTestSubObject::class, 'five');
$cssPath = 'ul.tree li#selector-TestTree-' . $subObject2->ID . ' a';
$noResult = $parser->getBySelector($cssPath);
$this->assertEmpty(
$noResult,
$subObject2 . ' is not found'
);
}
public function testReadonly()
{
$field = new TreeDropdownField('TestTree', 'Test tree', File::class);

View File

@ -62,3 +62,29 @@ SilverStripe\ORM\Tests\HierarchyTest\TestObject:
ParentID: =>SilverStripe\ORM\Tests\HierarchyTest\TestObject.twoA
three:
Title: Three MatchSearchCriteria
SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject:
four:
Title: Four SubObject
fourA:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.four
Title: Child A of Four
fourB:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.four
Title: Child B of Four SubObject
fourA1:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.fourA
Title: Child 1 of Child A of Four
fourA2:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.fourA
Title: Child 2 of Child A of Four SubObject
fourB1:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.fourB
Title: Child 1 of Child B of Four
fourB2:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.fourB
Title: Child 2 of Child B of Four
fourB3:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.fourB
Title: Child 3 of Child B of Four
five:
Title: Five

View File

@ -14,6 +14,8 @@ class HierarchyTest extends SapphireTest
HierarchyTest\TestObject::class,
HierarchyTest\HideTestObject::class,
HierarchyTest\HideTestSubObject::class,
HierarchyTest\HierarchyOnSubclassTestObject::class,
HierarchyTest\HierarchyOnSubclassTestSubObject::class,
];
public static function getExtraDataObjects()
@ -145,6 +147,43 @@ class HierarchyTest extends SapphireTest
);
}
public function testNumChildrenHierarchyOnSubclass()
{
/** @var HierarchyTest\HierarchyOnSubclassTestObject $obj5 */
$obj5 = $this->objFromFixture(HierarchyTest\HierarchyOnSubclassTestObject::class, 'obj5');
$this->assertFalse(
$obj5->hasMethod('numChildren'),
'numChildren() cannot be called on object without Hierarchy extension'
);
/** @var HierarchyTest\HierarchyOnSubclassTestSubObject $obj5a */
$obj5a = $this->objFromFixture(HierarchyTest\HierarchyOnSubclassTestSubObject::class, 'obj5a');
/** @var HierarchyTest\HierarchyOnSubclassTestSubObject $obj5b */
$obj5b = $this->objFromFixture(HierarchyTest\HierarchyOnSubclassTestSubObject::class, 'obj5b');
$this->assertEquals(2, $obj5a->numChildren());
$this->assertEquals(1, $obj5b->numChildren());
$obj5bChild2 = new HierarchyTest\HierarchyOnSubclassTestSubObject();
$obj5bChild2->ParentID = $obj5b->ID;
$obj5bChild2->write();
$this->assertEquals(
$obj5b->numChildren(false),
2,
'numChildren() caching can be disabled through method parameter'
);
$obj5bChild3 = new HierarchyTest\HierarchyOnSubclassTestSubObject();
$obj5bChild3->ParentID = $obj5b->ID;
$obj5bChild3->write();
$obj5b->flushCache();
$this->assertEquals(
$obj5b->numChildren(),
3,
'numChildren() caching can be disabled by flushCache()'
);
}
public function testLoadDescendantIDListIntoArray()
{
/** @var HierarchyTest\TestObject $obj2 */

View File

@ -53,3 +53,20 @@ SilverStripe\ORM\Tests\HierarchyTest\HideTestObject:
SilverStripe\ORM\Tests\HierarchyTest\HideTestSubObject:
obj4b:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HideTestObject.obj4
SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestObject:
obj5:
Title: Obj 5
SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject:
obj5a:
Title: Obj 5a
obj5b:
Title: Obj 5b
obj5aa:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.obj5a
Title: Obj 5aa
obj5ab:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.obj5a
Title: Obj 5ab
obj5ba:
Parent: =>SilverStripe\ORM\Tests\HierarchyTest\HierarchyOnSubclassTestSubObject.obj5b
Title: Obj 5ba

View File

@ -0,0 +1,30 @@
<?php
namespace SilverStripe\ORM\Tests\HierarchyTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
/**
* @mixin Versioned
*/
class HierarchyOnSubclassTestObject extends DataObject implements TestOnly
{
private static $table_name = 'HierarchyOnSubclassTest_Object';
private static $db = [
'Title' => 'Varchar'
];
private static $extensions = [
Versioned::class,
];
private static $default_sort = 'Title ASC';
public function cmstreeclasses()
{
return $this->markingClasses();
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace SilverStripe\ORM\Tests\HierarchyTest;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\Hierarchy\Hierarchy;
/**
* @mixin Hierarchy
*/
class HierarchyOnSubclassTestSubObject extends HierarchyOnSubclassTestObject implements TestOnly
{
private static $table_name = 'HierarchyOnSubclassTest_SubObject';
private static $extensions = [
Hierarchy::class,
];
}