From c8e8a61bbaca5e505182e166df20771db904e86d Mon Sep 17 00:00:00 2001 From: Mark Anthony Adriano Date: Fri, 13 May 2022 23:23:34 +1200 Subject: [PATCH] Trying test DataObjectDocumentTest --- docs/en/configuration.md | 19 +++-- .../Subsites/IndexConfigurationExtension.php | 11 +-- tests/DataObject/DataObjectDocumentTest.php | 73 +++++++++++-------- 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/docs/en/configuration.md b/docs/en/configuration.md index 2c979ab..4fb161d 100644 --- a/docs/en/configuration.md +++ b/docs/en/configuration.md @@ -23,11 +23,11 @@ SilverStripe\SearchService\Service\IndexConfiguration: Let's look at each relevant node: * `myindex`: The name of the index. The rules on what this can be named will vary depending -on your service provider. For AppSearch, it should only contain lowercase letters, numbers, +on your service provider. For AppSearch, it should only contain lowercase letters, numbers, and hyphens. * `includedClasses`: A list of content classes to index. These are just the _source_ of the -content, so they have no contractual bind to the module. If they are dataobjects, they +content, so they have no contractual bind to the module. If they are dataobjects, they should have the `SearchServiceExtension` applied, however. This is discussed further below. * `SilverStripe\CMS\Model\SiteTree`: This class already has the necessary extension applied @@ -46,7 +46,7 @@ so when it finds that the property `$content` doesn't exist on the `SiteTree` in will use a case matching strategy as a fallback. It is important to note that the keys of `fields` can be named anything you like, so long -as it is valid in your search service provider (for AppSearch, that's all lowercase and +as it is valid in your search service provider (for AppSearch, that's all lowercase and underscores). There is no reason why `title` cannot be `document_title` for instance, in the above configuration, as we've explicitly mapped the field to `Title`. @@ -81,8 +81,8 @@ SilverStripe\SearchService\Service\IndexConfiguration: property: 'Comments.Author.Name' ``` -For DataObject content, the dot syntax allows traversal of relationships. If the final -property in the notation is on a list, it will use the `->column()` function to derive +For DataObject content, the dot syntax allows traversal of relationships. If the final +property in the notation is on a list, it will use the `->column()` function to derive the values as an array. This will roughly get indexed as a structure like this: @@ -193,7 +193,7 @@ SilverStripe\Core\Injector\Injector: constructor: index_variant: '`MY_CUSTOM_VAR`' -``` +``` This is useful if you have multiple staging environments and you don't want to overcrowd your search instance with distinct indexes for each one. @@ -201,7 +201,7 @@ your search instance with distinct indexes for each one. ## Full page indexing Page and DataObject content is eligible for full-page indexing of its content. This is -predicated upon the object having a `Link()` method defined that can be rendered in a +predicated upon the object having a `Link()` method defined that can be rendered in a controller. The content is extracted using an XPath selector. By default, this is `//main`, but it @@ -248,6 +248,9 @@ SilverStripe\SearchService\Service\IndexConfiguration: Note the syntax to reduce the need for copy-paste if you want to duplicate the same configuration across. +__Additional note__: +> In the sample above, if the data object (My\Other\Class) does not have a subsite ID, then it will be included in the indexing as it is explicitly defined in the index configuration + This is handled via `SubsiteIndexConfigurationExtension` - this logic could be replicated for other scenarios like languages if required. @@ -255,5 +258,5 @@ replicated for other scenarios like languages if required. * [Usage](usage.md) * [Implementations](implementations.md) -* [Customising and extending](customising.md) +* [Customising and extending](customising.md) * [Overview and Rationale](overview.md) diff --git a/src/Extensions/Subsites/IndexConfigurationExtension.php b/src/Extensions/Subsites/IndexConfigurationExtension.php index 1e70186..b02a686 100644 --- a/src/Extensions/Subsites/IndexConfigurationExtension.php +++ b/src/Extensions/Subsites/IndexConfigurationExtension.php @@ -29,19 +29,12 @@ public function updateIndexesForDocument(DocumentInterface $doc, array &$indexes // included in the Subsite Index configuration then // allow the dataObject to be added in. foreach ($indexes as $indexName => $data) { - $reset = true; // DataObject explicitly defined on Subsite index definition $explicitClasses = $data['includeClasses'] ?? []; - foreach ($explicitClasses as $className => $fields) { - if ($dataObj->ClassName === $className) { - $reset = false; - break; - } - } - - if ($reset) { + if (!isset($explicitClasses[$dataObj->ClassName])) { unset($indexes[$indexName]); + break; } } } else { diff --git a/tests/DataObject/DataObjectDocumentTest.php b/tests/DataObject/DataObjectDocumentTest.php index 5ad2d22..94ba079 100644 --- a/tests/DataObject/DataObjectDocumentTest.php +++ b/tests/DataObject/DataObjectDocumentTest.php @@ -3,11 +3,13 @@ namespace SilverStripe\SearchService\Tests\DataObject; use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Injector\Injector; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\FieldType\DBDatetime; use SilverStripe\ORM\RelationList; use SilverStripe\SearchService\DataObject\DataObjectDocument; use SilverStripe\SearchService\Exception\IndexConfigurationException; +use SilverStripe\SearchService\Extensions\SearchServiceExtension; use SilverStripe\SearchService\Interfaces\DocumentAddHandler; use SilverStripe\SearchService\Interfaces\DocumentRemoveHandler; use SilverStripe\SearchService\Schema\Field; @@ -91,32 +93,43 @@ public function testSubsiteShouldIndex() { $config = $this->mockConfig(); - Config::modify()->merge( - IndexConfiguration::class, + $config->set( 'indexes', [ - 'index4' => [ + 'index0' => [ + 'subsite_id' => 0, 'includeClasses' => [ VersionedDataObjectFake::class => true ] ], + 'index1' => [ + 'subsite_id' => 1, + 'includeClasses' => [ + DataObjectFake::class => true + ] + ], ] ); - $classes = $config->getSearchableBaseClasses(); - $this->assertCount(1, $classes); - $this->assertContains(VersionedDataObjectFake::class, $classes); + /** @var Versioned $dataobject */ + $dataobject1 = new VersionedDataObjectFake([ + 'ID' => 6, + 'ShowInSearch' => true, + 'SubsiteID' => 1, + ]); + $dataobject1->publishSingle(); + $doc1 = DataObjectDocument::create($dataobject1); + $this->assertFalse($doc1->shouldIndex()); /** @var Versioned $dataobject */ - $dataobject = new VersionedDataObjectFake([ - 'ID' => 5, + $dataobject2 = new VersionedDataObjectFake([ + 'ID' => 7, 'ShowInSearch' => true, 'SubsiteID' => null, ]); - $dataobject->publishSingle(); - $doc = DataObjectDocument::create($dataobject); - - $this->assertTrue($doc->shouldIndex()); + $dataobject2->publishSingle(); + $doc2 = DataObjectDocument::create($dataobject2); + $this->assertTrue($doc2->shouldIndex()); } public function testMarkIndexed() @@ -200,24 +213,24 @@ public function testToArray() // of a method, e.g. getMyArray(): array, so it isn't coerced into a DBField. -// // exceptions -// $config->set('getFieldsForClass', [ -// DataObjectFake::class => [ -// new Field('customgettermap', 'CustomGetterMap'), -// ] -// ]); -// $this->expectException(IndexConfigurationException::class); -// $this->expectExceptionMessageRegExp('/associative/'); -// $doc->toArray(); -// -// $this->expectException(IndexConfigurationException::class); -// $this->expectExceptionMessageRegExp('/non scalar/'); -// $config->set('getFieldsForClass', [ -// DataObjectFake::class => [ -// new Field('customgettermixed', 'CustomGetterMixedArray'), -// ] -// ]); -// $doc->toArray(); + // // exceptions + // $config->set('getFieldsForClass', [ + // DataObjectFake::class => [ + // new Field('customgettermap', 'CustomGetterMap'), + // ] + // ]); + // $this->expectException(IndexConfigurationException::class); + // $this->expectExceptionMessageRegExp('/associative/'); + // $doc->toArray(); + // + // $this->expectException(IndexConfigurationException::class); + // $this->expectExceptionMessageRegExp('/non scalar/'); + // $config->set('getFieldsForClass', [ + // DataObjectFake::class => [ + // new Field('customgettermixed', 'CustomGetterMixedArray'), + // ] + // ]); + // $doc->toArray(); $this->expectException(IndexConfigurationException::class); $this->expectExceptionMessageRegExp('/DataObject or RelationList/');