silverstripe-cms/tests/search/SearchFormTest.php

372 lines
12 KiB
PHP
Raw Normal View History

<?php
use SilverStripe\Assets\File;
2017-03-12 23:11:56 +01:00
use SilverStripe\CMS\Controllers\ModelAsController;
use SilverStripe\CMS\Model\SiteTree;
2017-03-12 23:11:56 +01:00
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Config\Config;
use SilverStripe\ORM\DB;
use SilverStripe\Security\Security;
use SilverStripe\Versioned\Versioned;
use SilverStripe\MSSQL\MSSQLDatabase;
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
2016-07-22 01:32:32 +02:00
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\CMS\Search\SearchForm;
use SilverStripe\ORM\Search\FulltextSearchable;
use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Security\Member;
/**
* @package cms
* @subpackage testing
*
* @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...
*/
2017-01-25 21:59:25 +01:00
class ZZZSearchFormTest extends FunctionalTest
{
protected static $fixture_file = 'SearchFormTest.yml';
2017-03-30 00:07:04 +02:00
protected static $illegal_extensions = array(
SiteTree::class => array('SiteTreeSubsites', 'Translatable')
2017-01-25 21:59:25 +01:00
);
2017-03-12 23:11:56 +01:00
/**
* @var ContentController
*/
2017-01-25 21:59:25 +01:00
protected $mockController;
public function waitUntilIndexingFinished()
{
$schema = DB::get_schema();
if (method_exists($schema, 'waitUntilIndexingFinished')) {
$schema->waitUntilIndexingFinished();
}
}
2017-03-30 00:07:04 +02:00
public static function setUpBeforeClass()
2017-01-25 21:59:25 +01:00
{
// HACK Postgres doesn't refresh TSearch indexes when the schema changes after CREATE TABLE
// MySQL will need a different table type
2017-03-30 00:07:04 +02:00
static::kill_temp_db();
2017-03-12 23:11:56 +01:00
Config::modify();
2017-01-25 21:59:25 +01:00
FulltextSearchable::enable();
2017-03-30 00:07:04 +02:00
static::create_temp_db();
static::resetDBSchema(true);
parent::setUpBeforeClass();
2017-01-25 21:59:25 +01:00
}
public function setUp()
{
parent::setUp();
2017-03-12 23:11:56 +01:00
/** @var Page $holderPage */
$holderPage = $this->objFromFixture(SiteTree::class, 'searchformholder');
2017-03-12 23:11:56 +01:00
$this->mockController = ModelAsController::controller_for($holderPage);
2017-01-25 21:59:25 +01:00
$this->waitUntilIndexingFinished();
}
/**
* @return Boolean
*/
protected function checkFulltextSupport()
{
$conn = DB::get_conn();
if (class_exists(MSSQLDatabase::class) && $conn instanceof MSSQLDatabase) {
2017-01-25 21:59:25 +01:00
$supports = $conn->fullTextEnabled();
} else {
$supports = true;
}
if (!$supports) {
$this->markTestSkipped('Fulltext not supported by DB driver or setup');
}
return $supports;
}
/**
* @skipUpgrade
*/
2017-01-25 21:59:25 +01:00
public function testSearchFormTemplateCanBeChanged()
{
if (!$this->checkFulltextSupport()) {
return;
}
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$sf->setTemplate('BlankPage');
$this->assertContains(
'<body class="SearchForm Form BlankPage">',
2017-01-25 21:59:25 +01:00
$sf->forTemplate()
);
}
/**
* @skipUpgrade
*/
2017-01-25 21:59:25 +01:00
public function testPublishedPagesMatchedByTitle()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'publicPublishedPage']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$publishedPage = $this->objFromFixture(SiteTree::class, 'publicPublishedPage');
2017-01-25 21:59:25 +01:00
$publishedPage->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
$this->waitUntilIndexingFinished();
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertContains(
$publishedPage->ID,
$results->column('ID'),
'Published pages are found by searchform'
);
}
/**
* @skipUpgrade
*/
2017-01-25 21:59:25 +01:00
public function testDoubleQuotesPublishedPagesMatchedByTitle()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'"finding butterflies"']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$publishedPage = $this->objFromFixture(SiteTree::class, 'publicPublishedPage');
2017-01-25 21:59:25 +01:00
$publishedPage->Title = "finding butterflies";
$publishedPage->write();
$publishedPage->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
$this->waitUntilIndexingFinished();
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertContains(
$publishedPage->ID,
$results->column('ID'),
'Published pages are found by searchform'
);
}
/**
* @skipUpgrade
*/
2017-01-25 21:59:25 +01:00
public function testUnpublishedPagesNotIncluded()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'publicUnpublishedPage']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
$unpublishedPage = $this->objFromFixture(SiteTree::class, 'publicUnpublishedPage');
2017-01-25 21:59:25 +01:00
$this->assertNotContains(
$unpublishedPage->ID,
$results->column('ID'),
'Unpublished pages are not found by searchform'
);
}
public function testPagesRestrictedToLoggedinUsersNotIncluded()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'restrictedViewLoggedInUsers']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$page = $this->objFromFixture(SiteTree::class, 'restrictedViewLoggedInUsers');
2017-01-25 21:59:25 +01:00
$page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertContains(
$page->ID,
$results->column('ID'),
'Page with "Restrict to logged in users" shows if login is present'
);
Security::setCurrentUser(null);
2017-01-25 21:59:25 +01:00
}
public function testPagesRestrictedToSpecificGroupNotIncluded()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'restrictedViewOnlyWebsiteUsers']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$page = $this->objFromFixture(SiteTree::class, 'restrictedViewOnlyWebsiteUsers');
2017-01-25 21:59:25 +01:00
$page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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);
2017-01-25 21:59:25 +01:00
$member = $this->objFromFixture(Member::class, 'websiteuser');
Security::setCurrentUser($member);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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);
2017-01-25 21:59:25 +01:00
}
public function testInheritedRestrictedPagesNotIncluded()
{
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'inheritRestrictedView']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$parent = $this->objFromFixture(SiteTree::class, 'restrictedViewLoggedInUsers');
2017-01-25 21:59:25 +01:00
$parent->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
$page = $this->objFromFixture(SiteTree::class, 'inheritRestrictedView');
2017-01-25 21:59:25 +01:00
$page->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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);
2017-01-25 21:59:25 +01:00
}
public function testDisabledShowInSearchFlagNotIncludedForSiteTree()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'dontShowInSearchPage']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$page = $this->objFromFixture(SiteTree::class, 'dontShowInSearchPage');
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertNotContains(
$page->ID,
$results->column('ID'),
2017-03-12 23:11:56 +01:00
'Page with "Show in Search" disabled does not show'
2017-01-25 21:59:25 +01:00
);
}
public function testDisabledShowInSearchFlagNotIncludedForFiles()
{
if (!$this->checkFulltextSupport()) {
return;
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'dontShowInSearchFile']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$dontShowInSearchFile = $this->objFromFixture(File::class, 'dontShowInSearchFile');
2017-01-25 21:59:25 +01:00
$dontShowInSearchFile->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
$showInSearchFile = $this->objFromFixture(File::class, 'showInSearchFile');
2017-01-25 21:59:25 +01:00
$showInSearchFile->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertNotContains(
$dontShowInSearchFile->ID,
$results->column('ID'),
'File with "Show in Search" disabled doesnt show'
);
2017-03-12 23:11:56 +01:00
// Check ShowInSearch=1 can be found
$request = new HTTPRequest('GET', 'search', ['Search'=>'showInSearchFile']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$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) {
2017-01-25 21:59:25 +01:00
$this->markTestSkipped("PostgreSQLDatabase doesn't support entity-encoded searches");
}
2017-03-12 23:11:56 +01:00
$request = new HTTPRequest('GET', 'search', ['Search'=>'Brötchen']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
2017-01-25 21:59:25 +01:00
$pageWithSpecialChars = $this->objFromFixture(SiteTree::class, 'pageWithSpecialChars');
2017-01-25 21:59:25 +01:00
$pageWithSpecialChars->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
2017-03-12 23:11:56 +01:00
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertContains(
$pageWithSpecialChars->ID,
$results->column('ID'),
'Published pages with umlauts in title are found'
);
2017-03-12 23:11:56 +01:00
// Check another word
$request = new HTTPRequest('GET', 'search', ['Search'=>'Bäcker']);
$this->mockController->setRequest($request);
$sf = new SearchForm($this->mockController);
$results = $sf->getResults();
2017-01-25 21:59:25 +01:00
$this->assertContains(
$pageWithSpecialChars->ID,
$results->column('ID'),
'Published pages with htmlencoded umlauts in content are found'
);
}
}