Source of file SearchFormTest.php
Size: 16,677 Bytes - Last Modified: 2021-12-23T10:28:18+00:00
/var/www/docs.ssmods.com/process/src/tests/php/Search/SearchFormTest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 | <?php namespace SilverStripe\CMS\Tests\Search; use Page; use SilverStripe\Assets\File; use SilverStripe\CMS\Controllers\ContentController; use SilverStripe\CMS\Controllers\ModelAsController; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Search\SearchForm; use SilverStripe\Control\HTTPRequest; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\FunctionalTest; use SilverStripe\MSSQL\MSSQLDatabase; use SilverStripe\ORM\DB; use SilverStripe\ORM\Search\FulltextSearchable; use SilverStripe\PostgreSQL\PostgreSQLDatabase; use SilverStripe\Security\Member; use SilverStripe\Security\Security; use SilverStripe\Subsites\Extensions\SiteTreeSubsites; use SilverStripe\Versioned\Versioned; use TractorCow\Fluent\Extension\FluentSiteTreeExtension; /** * @todo Fix unpublished pages check in testPublishedPagesMatchedByTitle() * @todo All tests run on unpublished pages at the moment, due to the searchform not distinguishing between them * * Because this manipulates the test database in severe ways, I've renamed the test to force it to run last... */ class ZZZSearchFormTest extends FunctionalTest { protected static $fixture_file = 'SearchFormTest.yml'; protected static $illegal_extensions = [ SiteTree::class => [ SiteTreeSubsites::class, FluentSiteTreeExtension::class, ], ]; /** * @var ContentController */ protected $mockController; /** * @var bool InnoDB doesn't update indexes until transactions are committed */ protected $usesTransactions = false; public function waitUntilIndexingFinished() { $schema = DB::get_schema(); if (method_exists($schema, 'waitUntilIndexingFinished')) { $schema->waitUntilIndexingFinished(); } } public static function setUpBeforeClass(): void { // HACK Postgres doesn't refresh TSearch indexes when the schema changes after CREATE TABLE // MySQL will need a different table type static::$tempDB->kill(); Config::modify(); FulltextSearchable::enable(); static::$tempDB->build(); static::resetDBSchema(true); parent::setUpBeforeClass(); } protected function setUp(): void { parent::setUp(); /** @var Page $holderPage */ $holderPage = $this->objFromFixture(SiteTree::class, 'searchformholder'); $this->mockController = ModelAsController::controller_for($holderPage); $this->waitUntilIndexingFinished(); } /** * @return Boolean */ protected function checkFulltextSupport() { $conn = DB::get_conn(); if (class_exists(MSSQLDatabase::class) && $conn instanceof MSSQLDatabase) { $supports = $conn->fullTextEnabled(); } else { $supports = true; } if (!$supports) { $this->markTestSkipped('Fulltext not supported by DB driver or setup'); } return $supports; } /** * @skipUpgrade */ public function testSearchFormTemplateCanBeChanged() { if (!$this->checkFulltextSupport()) { return; } $sf = new SearchForm($this->mockController); $sf->setTemplate('BlankPage'); $this->assertStringContainsString( '<body class="SearchForm Form BlankPage">', $sf->forTemplate() ); } /** * @skipUpgrade */ public function testPublishedPagesMatchedByTitle() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'publicPublishedPage']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var SiteTree $publishedPage */ $publishedPage = $this->objFromFixture(SiteTree::class, 'publicPublishedPage'); $publishedPage->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); $this->waitUntilIndexingFinished(); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertContains( $publishedPage->ID, $results->column('ID'), 'Published pages are found by searchform' ); } /** * @skipUpgrade */ public function testDoubleQuotesPublishedPagesMatchedByTitle() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'"finding butterflies"']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var SiteTree $publishedPage */ $publishedPage = $this->objFromFixture(SiteTree::class, 'publicPublishedPage'); $publishedPage->Title = "finding butterflies"; $publishedPage->write(); $publishedPage->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); $this->waitUntilIndexingFinished(); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertContains( $publishedPage->ID, $results->column('ID'), 'Published pages are found by searchform' ); } /** * @skipUpgrade */ public function testUnpublishedPagesNotIncluded() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'publicUnpublishedPage']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $unpublishedPage = $this->objFromFixture(SiteTree::class, 'publicUnpublishedPage'); $this->assertNotContains( $unpublishedPage->ID, $results->column('ID'), 'Unpublished pages are not found by searchform' ); } public function testPagesRestrictedToLoggedinUsersNotIncluded() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'restrictedViewLoggedInUsers']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var SiteTree $page */ $page = $this->objFromFixture(SiteTree::class, 'restrictedViewLoggedInUsers'); $page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertNotContains( $page->ID, $results->column('ID'), 'Page with "Restrict to logged in users" doesnt show without valid login' ); $member = $this->objFromFixture(Member::class, 'randomuser'); Security::setCurrentUser($member); $results = $sf->getResults(); $this->assertContains( $page->ID, $results->column('ID'), 'Page with "Restrict to logged in users" shows if login is present' ); Security::setCurrentUser(null); } public function testPagesRestrictedToSpecificGroupNotIncluded() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'restrictedViewOnlyWebsiteUsers']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var SiteTree $page */ $page = $this->objFromFixture(SiteTree::class, 'restrictedViewOnlyWebsiteUsers'); $page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertNotContains( $page->ID, $results->column('ID'), 'Page with "Restrict to these users" doesnt show without valid login' ); $member = $this->objFromFixture(Member::class, 'randomuser'); Security::setCurrentUser($member); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertNotContains( $page->ID, $results->column('ID'), 'Page with "Restrict to these users" doesnt show if logged in user is not in the right group' ); Security::setCurrentUser(null); $member = $this->objFromFixture(Member::class, 'websiteuser'); Security::setCurrentUser($member); $results = $sf->getResults(); $this->assertContains( $page->ID, $results->column('ID'), 'Page with "Restrict to these users" shows if user in this group is logged in' ); Security::setCurrentUser(null); } /** * */ public function testInheritedRestrictedPagesNotIncluded() { $request = new HTTPRequest('GET', 'search', ['Search'=>'inheritRestrictedView']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var SiteTree $parent */ $parent = $this->objFromFixture(SiteTree::class, 'restrictedViewLoggedInUsers'); $parent->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); /** @var SiteTree $page */ $page = $this->objFromFixture(SiteTree::class, 'inheritRestrictedView'); $page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertNotContains( $page->ID, $results->column('ID'), 'Page inheriting "Restrict to loggedin users" doesnt show without valid login' ); $member = $this->objFromFixture(Member::class, 'websiteuser'); Security::setCurrentUser($member); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertContains( $page->ID, $results->column('ID'), 'Page inheriting "Restrict to loggedin users" shows if user in this group is logged in' ); Security::setCurrentUser(null); } public function testDisabledShowInSearchFlagNotIncludedForSiteTree() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'dontShowInSearchPage']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); $page = $this->objFromFixture(SiteTree::class, 'dontShowInSearchPage'); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertNotContains( $page->ID, $results->column('ID'), 'Page with "Show in Search" disabled does not show' ); } public function testDisabledShowInSearchFlagNotIncludedForFiles() { if (!$this->checkFulltextSupport()) { return; } $request = new HTTPRequest('GET', 'search', ['Search'=>'dontShowInSearchFile']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var File $dontShowInSearchFile */ $dontShowInSearchFile = $this->objFromFixture(File::class, 'dontShowInSearchFile'); $dontShowInSearchFile->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); /** @var File $showInSearchFile */ $showInSearchFile = $this->objFromFixture(File::class, 'showInSearchFile'); $showInSearchFile->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertNotContains( $dontShowInSearchFile->ID, $results->column('ID'), 'File with "Show in Search" disabled doesnt show' ); // Check ShowInSearch=1 can be found $request = new HTTPRequest('GET', 'search', ['Search'=>'showInSearchFile']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertContains( $showInSearchFile->ID, $results->column('ID'), 'File with "Show in Search" enabled can be found' ); } public function testSearchTitleAndContentWithSpecialCharacters() { if (!$this->checkFulltextSupport()) { return; } if (class_exists(PostgreSQLDatabase::class) && DB::get_conn() instanceof PostgreSQLDatabase) { $this->markTestSkipped("PostgreSQLDatabase doesn't support entity-encoded searches"); } $request = new HTTPRequest('GET', 'search', ['Search'=>'Brötchen']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); /** @var SiteTree $pageWithSpecialChars */ $pageWithSpecialChars = $this->objFromFixture(SiteTree::class, 'pageWithSpecialChars'); $pageWithSpecialChars->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertContains( $pageWithSpecialChars->ID, $results->column('ID'), 'Published pages with umlauts in title are found' ); // Check another word $request = new HTTPRequest('GET', 'search', ['Search'=>'Bäcker']); $request->setSession($this->session()); $this->mockController->setRequest($request); $sf = new SearchForm($this->mockController); // Generate results on the Live stage for an accurate outcome $results = Versioned::withVersionedMode(function () use ($sf) { Versioned::set_stage(Versioned::LIVE); return $sf->getResults(); }); $this->assertContains( $pageWithSpecialChars->ID, $results->column('ID'), 'Published pages with htmlencoded umlauts in content are found' ); } } |