security update core+modules
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
* the template.
|
||||
*
|
||||
* Default keys within $info_split:
|
||||
* - $info_split['type']: Node type (or item type string supplied by module).
|
||||
* - $info_split['module']: The module that implemented the search query.
|
||||
* - $info_split['user']: Author of the node linked to users profile. Depends
|
||||
* on permission.
|
||||
* - $info_split['date']: Last update of the node. Short formatted.
|
||||
|
@@ -30,15 +30,11 @@
|
||||
*
|
||||
* @return
|
||||
* Array with optional keys:
|
||||
* - 'title': Title for the tab on the search page for this module. Defaults
|
||||
* - title: Title for the tab on the search page for this module. Defaults
|
||||
* to the module name if not given.
|
||||
* - 'path': Path component after 'search/' for searching with this module.
|
||||
* - path: Path component after 'search/' for searching with this module.
|
||||
* Defaults to the module name if not given.
|
||||
* - 'conditions_callback': Name of a callback function that is invoked by
|
||||
* search_view() to get an array of additional search conditions to pass to
|
||||
* search_data(). For example, a search module may get additional keywords,
|
||||
* filters, or modifiers for the search from the query string. Sample
|
||||
* callback function: sample_search_conditions_callback().
|
||||
* - conditions_callback: An implementation of callback_search_conditions().
|
||||
*
|
||||
* @ingroup search
|
||||
*/
|
||||
@@ -46,35 +42,10 @@ function hook_search_info() {
|
||||
return array(
|
||||
'title' => 'Content',
|
||||
'path' => 'node',
|
||||
'conditions_callback' => 'sample_search_conditions_callback',
|
||||
'conditions_callback' => 'callback_search_conditions',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* An example conditions callback function for search.
|
||||
*
|
||||
* This example pulls additional search keywords out of the $_REQUEST variable,
|
||||
* (i.e. from the query string of the request). The conditions may also be
|
||||
* generated internally - for example based on a module's settings.
|
||||
*
|
||||
* @see hook_search_info()
|
||||
* @ingroup search
|
||||
*/
|
||||
function sample_search_conditions_callback($keys) {
|
||||
$conditions = array();
|
||||
|
||||
if (!empty($_REQUEST['keys'])) {
|
||||
$conditions['keys'] = $_REQUEST['keys'];
|
||||
}
|
||||
if (!empty($_REQUEST['sample_search_keys'])) {
|
||||
$conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
|
||||
}
|
||||
if ($force_keys = variable_get('sample_search_force_keywords', '')) {
|
||||
$conditions['sample_search_force_keywords'] = $force_keys;
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define access to a custom search routine.
|
||||
*
|
||||
@@ -252,22 +223,23 @@ function hook_search_execute($keys = NULL, $conditions = NULL) {
|
||||
/**
|
||||
* Override the rendering of search results.
|
||||
*
|
||||
* A module that implements hook_search_info() to define a type of search
|
||||
* may implement this hook in order to override the default theming of
|
||||
* its search results, which is otherwise themed using theme('search_results').
|
||||
* A module that implements hook_search_info() to define a type of search may
|
||||
* implement this hook in order to override the default theming of its search
|
||||
* results, which is otherwise themed using theme('search_results').
|
||||
*
|
||||
* Note that by default, theme('search_results') and theme('search_result')
|
||||
* work together to create an ordered list (OL). So your hook_search_page()
|
||||
* implementation should probably do this as well.
|
||||
*
|
||||
* @see search-result.tpl.php, search-results.tpl.php
|
||||
*
|
||||
* @param $results
|
||||
* An array of search results.
|
||||
*
|
||||
* @return
|
||||
* A renderable array, which will render the formatted search results with
|
||||
* a pager included.
|
||||
* A renderable array, which will render the formatted search results with a
|
||||
* pager included.
|
||||
*
|
||||
* @see search-result.tpl.php
|
||||
* @see search-results.tpl.php
|
||||
*/
|
||||
function hook_search_page($results) {
|
||||
$output['prefix']['#markup'] = '<ol class="search-results">';
|
||||
@@ -364,3 +336,41 @@ function hook_update_index() {
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provide search query conditions.
|
||||
*
|
||||
* Callback for hook_search_info().
|
||||
*
|
||||
* This callback is invoked by search_view() to get an array of additional
|
||||
* search conditions to pass to search_data(). For example, a search module
|
||||
* may get additional keywords, filters, or modifiers for the search from
|
||||
* the query string.
|
||||
*
|
||||
* This example pulls additional search keywords out of the $_REQUEST variable,
|
||||
* (i.e. from the query string of the request). The conditions may also be
|
||||
* generated internally - for example based on a module's settings.
|
||||
*
|
||||
* @param $keys
|
||||
* The search keywords string.
|
||||
*
|
||||
* @return
|
||||
* An array of additional conditions, such as filters.
|
||||
*
|
||||
* @ingroup callbacks
|
||||
* @ingroup search
|
||||
*/
|
||||
function callback_search_conditions($keys) {
|
||||
$conditions = array();
|
||||
|
||||
if (!empty($_REQUEST['keys'])) {
|
||||
$conditions['keys'] = $_REQUEST['keys'];
|
||||
}
|
||||
if (!empty($_REQUEST['sample_search_keys'])) {
|
||||
$conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
|
||||
}
|
||||
if ($force_keys = config('sample_search.settings')->get('force_keywords')) {
|
||||
$conditions['sample_search_force_keywords'] = $force_keys;
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
@@ -105,6 +105,8 @@ class SearchQuery extends SelectQueryExtender {
|
||||
* Stores score expressions.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @see addScore()
|
||||
*/
|
||||
protected $scores = array();
|
||||
|
||||
@@ -116,7 +118,7 @@ class SearchQuery extends SelectQueryExtender {
|
||||
protected $scoresArguments = array();
|
||||
|
||||
/**
|
||||
* Total value of all the multipliers.
|
||||
* Stores multipliers for score expressions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -147,6 +149,17 @@ class SearchQuery extends SelectQueryExtender {
|
||||
$this->searchExpression = $expression;
|
||||
$this->type = $module;
|
||||
|
||||
// Add a search_* tag. This needs to be added before any preExecute methods
|
||||
// for decorated queries are called, as $this->prepared will be set to TRUE
|
||||
// and tags added in the execute method will never get used. For example,
|
||||
// if $query is extended by 'SearchQuery' then 'PagerDefault', the
|
||||
// search-specific tag will be added too late (when preExecute() has
|
||||
// already been called from the PagerDefault extender), and as a
|
||||
// consequence will not be available to hook_query_alter() implementations,
|
||||
// nor will the correct hook_query_TAG_alter() implementations get invoked.
|
||||
// See node_search_execute().
|
||||
$this->addTag('search_' . $module);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -391,21 +404,39 @@ class SearchQuery extends SelectQueryExtender {
|
||||
/**
|
||||
* Adds a custom score expression to the search query.
|
||||
*
|
||||
* Each score expression can optionally use a multiplier, and multiple
|
||||
* expressions are combined.
|
||||
* Score expressions are used to order search results. If no calls to
|
||||
* addScore() have taken place, a default keyword relevance score will be
|
||||
* used. However, if at least one call to addScore() has taken place, the
|
||||
* keyword relevance score is not automatically added.
|
||||
*
|
||||
* Also note that if you call orderBy() directly on the query, search scores
|
||||
* will not automatically be used to order search results. Your orderBy()
|
||||
* expression can reference 'calculated_score', which will be the total
|
||||
* calculated score value.
|
||||
*
|
||||
* @param $score
|
||||
* The score expression.
|
||||
* The score expression, which should evaluate to a number between 0 and 1.
|
||||
* The string 'i.relevance' in a score expression will be replaced by a
|
||||
* measure of keyword relevance between 0 and 1.
|
||||
* @param $arguments
|
||||
* Custom query arguments for that expression.
|
||||
* Query arguments needed to provide values to the score expression.
|
||||
* @param $multiply
|
||||
* If set, the score is multiplied with that value. Search query ensures
|
||||
* that the search scores are still normalized.
|
||||
* If set, the score is multiplied with this value. However, all scores
|
||||
* with multipliers are then divided by the total of all multipliers, so
|
||||
* that overall, the normalization is maintained.
|
||||
*
|
||||
* @return object
|
||||
* The updated query object.
|
||||
*/
|
||||
public function addScore($score, $arguments = array(), $multiply = FALSE) {
|
||||
if ($multiply) {
|
||||
$i = count($this->multiply);
|
||||
// Modify the score expression so it is multiplied by the multiplier,
|
||||
// with a divisor to renormalize.
|
||||
$score = "CAST(:multiply_$i AS DECIMAL) * COALESCE(( " . $score . "), 0) / CAST(:total_$i AS DECIMAL)";
|
||||
// Add an argument for the multiplier. The :total_$i argument is taken
|
||||
// care of in the execute() method, which is when the total divisor is
|
||||
// calculated.
|
||||
$arguments[':multiply_' . $i] = $multiply;
|
||||
$this->multiply[] = $multiply;
|
||||
}
|
||||
@@ -446,8 +477,9 @@ class SearchQuery extends SelectQueryExtender {
|
||||
}
|
||||
|
||||
if (count($this->multiply)) {
|
||||
// Add the total multiplicator as many times as requested to maintain
|
||||
// normalization as far as possible.
|
||||
// Re-normalize scores with multipliers by dividing by the total of all
|
||||
// multipliers. The expressions were altered in addScore(), so here just
|
||||
// add the arguments for the total.
|
||||
$i = 0;
|
||||
$sum = array_sum($this->multiply);
|
||||
foreach ($this->multiply as $total) {
|
||||
@@ -456,19 +488,25 @@ class SearchQuery extends SelectQueryExtender {
|
||||
}
|
||||
}
|
||||
|
||||
// Replace i.relevance pseudo-field with the actual, normalized value.
|
||||
$this->scores = str_replace('i.relevance', '(' . (1.0 / $this->normalize) . ' * i.score * t.count)', $this->scores);
|
||||
// Convert scores to an expression.
|
||||
// Replace the pseudo-expression 'i.relevance' with a measure of keyword
|
||||
// relevance in all score expressions, using string replacement. Careful
|
||||
// though! If you just print out a float, some locales use ',' as the
|
||||
// decimal separator in PHP, while SQL always uses '.'. So, make sure to
|
||||
// set the number format correctly.
|
||||
$relevance = number_format((1.0 / $this->normalize), 10, '.', '');
|
||||
$this->scores = str_replace('i.relevance', '(' . $relevance . ' * i.score * t.count)', $this->scores);
|
||||
|
||||
// Add all scores together to form a query field.
|
||||
$this->addExpression('SUM(' . implode(' + ', $this->scores) . ')', 'calculated_score', $this->scoresArguments);
|
||||
|
||||
// If an order has not yet been set for this query, add a default order
|
||||
// that sorts by the calculated sum of scores.
|
||||
if (count($this->getOrderBy()) == 0) {
|
||||
// Add default order after adding the expression.
|
||||
$this->orderBy('calculated_score', 'DESC');
|
||||
}
|
||||
|
||||
// Add tag and useful metadata.
|
||||
// Add useful metadata.
|
||||
$this
|
||||
->addTag('search_' . $this->type)
|
||||
->addMetaData('normalize', $this->normalize)
|
||||
->fields('i', array('type', 'sid'));
|
||||
|
||||
|
@@ -7,3 +7,9 @@ files[] = search.extender.inc
|
||||
files[] = search.test
|
||||
configure = admin/config/search/settings
|
||||
stylesheets[all][] = search.css
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-04-02
|
||||
version = "7.36"
|
||||
project = "drupal"
|
||||
datestamp = "1427943826"
|
||||
|
||||
|
@@ -1067,7 +1067,7 @@ function template_preprocess_search_block_form(&$variables) {
|
||||
$hidden = array();
|
||||
// Provide variables named after form keys so themers can print each element independently.
|
||||
foreach (element_children($variables['form']) as $key) {
|
||||
$type = $variables['form'][$key]['#type'];
|
||||
$type = isset($variables['form'][$key]['#type']) ? $variables['form'][$key]['#type'] : '';
|
||||
if ($type == 'hidden' || $type == 'token') {
|
||||
$hidden[] = drupal_render($variables['form'][$key]);
|
||||
}
|
||||
|
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
function search_view($module = NULL, $keys = '') {
|
||||
$info = FALSE;
|
||||
$redirect = FALSE;
|
||||
$keys = trim($keys);
|
||||
// Also try to pull search keywords out of the $_REQUEST variable to
|
||||
// support old GET format of searches for existing links.
|
||||
|
@@ -11,6 +11,9 @@ define('SEARCH_TYPE', '_test_');
|
||||
define('SEARCH_TYPE_2', '_test2_');
|
||||
define('SEARCH_TYPE_JPN', '_test3_');
|
||||
|
||||
/**
|
||||
* Indexes content and queries it.
|
||||
*/
|
||||
class SearchMatchTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
@@ -275,7 +278,7 @@ class SearchPageText extends DrupalWebTestCase {
|
||||
$edit = array();
|
||||
$edit['keys'] = 'bike shed ' . $this->randomName();
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
$this->assertText(t('Consider loosening your query with OR. bike OR shed will often show more results than bike shed.'), t('Help text is displayed when search returns no results.'));
|
||||
$this->assertText(t('Consider loosening your query with OR. bike OR shed will often show more results than bike shed.'), 'Help text is displayed when search returns no results.');
|
||||
$this->assertText(t('Search'));
|
||||
$this->assertTitle($title, 'Search page title is correct');
|
||||
|
||||
@@ -307,6 +310,9 @@ class SearchPageText extends DrupalWebTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes content and tests the advanced search form.
|
||||
*/
|
||||
class SearchAdvancedSearchForm extends DrupalWebTestCase {
|
||||
protected $node;
|
||||
|
||||
@@ -342,34 +348,37 @@ class SearchAdvancedSearchForm extends DrupalWebTestCase {
|
||||
* Test using the advanced search form to limit search to nodes of type "Basic page".
|
||||
*/
|
||||
function testNodeType() {
|
||||
$this->assertTrue($this->node->type == 'page', t('Node type is Basic page.'));
|
||||
$this->assertTrue($this->node->type == 'page', 'Node type is Basic page.');
|
||||
|
||||
// Assert that the dummy title doesn't equal the real title.
|
||||
$dummy_title = 'Lorem ipsum';
|
||||
$this->assertNotEqual($dummy_title, $this->node->title, t("Dummy title doesn't equal node title"));
|
||||
$this->assertNotEqual($dummy_title, $this->node->title, "Dummy title doesn't equal node title");
|
||||
|
||||
// Search for the dummy title with a GET query.
|
||||
$this->drupalGet('search/node/' . $dummy_title);
|
||||
$this->assertNoText($this->node->title, t('Basic page node is not found with dummy title.'));
|
||||
$this->assertNoText($this->node->title, 'Basic page node is not found with dummy title.');
|
||||
|
||||
// Search for the title of the node with a GET query.
|
||||
$this->drupalGet('search/node/' . $this->node->title);
|
||||
$this->assertText($this->node->title, t('Basic page node is found with GET query.'));
|
||||
$this->assertText($this->node->title, 'Basic page node is found with GET query.');
|
||||
|
||||
// Search for the title of the node with a POST query.
|
||||
$edit = array('or' => $this->node->title);
|
||||
$this->drupalPost('search/node', $edit, t('Advanced search'));
|
||||
$this->assertText($this->node->title, t('Basic page node is found with POST query.'));
|
||||
$this->assertText($this->node->title, 'Basic page node is found with POST query.');
|
||||
|
||||
// Advanced search type option.
|
||||
$this->drupalPost('search/node', array_merge($edit, array('type[page]' => 'page')), t('Advanced search'));
|
||||
$this->assertText($this->node->title, t('Basic page node is found with POST query and type:page.'));
|
||||
$this->assertText($this->node->title, 'Basic page node is found with POST query and type:page.');
|
||||
|
||||
$this->drupalPost('search/node', array_merge($edit, array('type[article]' => 'article')), t('Advanced search'));
|
||||
$this->assertText('bike shed', t('Article node is not found with POST query and type:article.'));
|
||||
$this->assertText('bike shed', 'Article node is not found with POST query and type:article.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes content and tests ranking factors.
|
||||
*/
|
||||
class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
@@ -464,7 +473,7 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
function testHTMLRankings() {
|
||||
// Login with sufficient privileges.
|
||||
$this->drupalLogin($this->drupalCreateUser(array('create page content')));
|
||||
|
||||
|
||||
// Test HTML tags with different weights.
|
||||
$sorted_tags = array('h1', 'h2', 'h3', 'h4', 'a', 'h5', 'h6', 'notag');
|
||||
$shuffled_tags = $sorted_tags;
|
||||
@@ -496,7 +505,7 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Refresh variables after the treatment.
|
||||
$this->refreshVariables();
|
||||
|
||||
|
||||
// Disable all other rankings.
|
||||
$node_ranks = array('sticky', 'promote', 'recent', 'comments', 'views');
|
||||
foreach ($node_ranks as $node_rank) {
|
||||
@@ -534,7 +543,7 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Assert the results.
|
||||
$this->assertEqual($set[0]['node']->nid, $node->nid, 'Search tag ranking for "<' . $tag . '>" order.');
|
||||
|
||||
|
||||
// Delete node so it doesn't show up in subsequent search results.
|
||||
node_delete($node->nid);
|
||||
}
|
||||
@@ -580,6 +589,9 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the rendering of the search block.
|
||||
*/
|
||||
class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
@@ -600,13 +612,13 @@ class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
function testSearchFormBlock() {
|
||||
// Set block title to confirm that the interface is available.
|
||||
$this->drupalPost('admin/structure/block/manage/search/form/configure', array('title' => $this->randomName(8)), t('Save block'));
|
||||
$this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
|
||||
$this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
|
||||
|
||||
// Set the block to a region to confirm block is available.
|
||||
$edit = array();
|
||||
$edit['blocks[search_form][region]'] = 'footer';
|
||||
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
||||
$this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.'));
|
||||
$this->assertText(t('The block settings have been updated.'), 'Block successfully move to footer region.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -640,7 +652,7 @@ class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
$this->assertEqual(
|
||||
$this->getUrl(),
|
||||
url('search/node/' . $terms['search_block_form'], array('absolute' => TRUE)),
|
||||
t('Redirected to correct url.')
|
||||
'Redirected to correct url.'
|
||||
);
|
||||
|
||||
// Test an empty search via the block form, from the front page.
|
||||
@@ -652,7 +664,7 @@ class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
$this->assertEqual(
|
||||
$this->getUrl(),
|
||||
url('search/node/', array('absolute' => TRUE)),
|
||||
t('Redirected to correct url.')
|
||||
'Redirected to correct url.'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -727,7 +739,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Comment Search tests',
|
||||
'description' => 'Verify text formats and filters used elsewhere.',
|
||||
'description' => 'Test integration searching comments.',
|
||||
'group' => 'Search',
|
||||
);
|
||||
}
|
||||
@@ -790,20 +802,20 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
'search_block_form' => "'" . $edit_comment['subject'] . "'",
|
||||
);
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertText($node->title, t('Node found in search results.'));
|
||||
$this->assertText($edit_comment['subject'], t('Comment subject found in search results.'));
|
||||
$this->assertText($node->title, 'Node found in search results.');
|
||||
$this->assertText($edit_comment['subject'], 'Comment subject found in search results.');
|
||||
|
||||
// Search for the comment body.
|
||||
$edit = array(
|
||||
'search_block_form' => "'" . $comment_body . "'",
|
||||
);
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertText($node->title, t('Node found in search results.'));
|
||||
$this->assertText($node->title, 'Node found in search results.');
|
||||
|
||||
// Verify that comment is rendered using proper format.
|
||||
$this->assertText($comment_body, t('Comment body text found in search results.'));
|
||||
$this->assertNoRaw(t('n/a'), t('HTML in comment body is not hidden.'));
|
||||
$this->assertNoRaw(check_plain($edit_comment['comment_body[' . LANGUAGE_NONE . '][0][value]']), t('HTML in comment body is not escaped.'));
|
||||
$this->assertText($comment_body, 'Comment body text found in search results.');
|
||||
$this->assertNoRaw(t('n/a'), 'HTML in comment body is not hidden.');
|
||||
$this->assertNoRaw(check_plain($edit_comment['comment_body[' . LANGUAGE_NONE . '][0][value]']), 'HTML in comment body is not escaped.');
|
||||
|
||||
// Hide comments.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
@@ -816,7 +828,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Search for $title.
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertNoText($comment_body, t('Comment body text not found in search results.'));
|
||||
$this->assertNoText($comment_body, 'Comment body text not found in search results.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -875,7 +887,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
$this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE, TRUE);
|
||||
$this->setRolePermissions($this->admin_role, TRUE, FALSE);
|
||||
$this->checkCommentAccess('Admin user has access comments permission and no search permission, but comments should be indexed because admin user inherits authenticated user\'s permission to search', TRUE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -926,7 +938,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
// Verify that if you view the node on its own page, 'add new comment'
|
||||
// is there.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->assertText(t('Add new comment'), t('Add new comment appears on node page'));
|
||||
$this->assertText(t('Add new comment'), 'Add new comment appears on node page');
|
||||
|
||||
// Run cron to index this page.
|
||||
$this->drupalLogout();
|
||||
@@ -935,13 +947,13 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
// Search for 'comment'. Should be no results.
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalPost('search/node', array('keys' => 'comment'), t('Search'));
|
||||
$this->assertText(t('Your search yielded no results'), t('No results searching for the word comment'));
|
||||
$this->assertText(t('Your search yielded no results'), 'No results searching for the word comment');
|
||||
|
||||
// Search for the node title. Should be found, and 'Add new comment' should
|
||||
// not be part of the search snippet.
|
||||
$this->drupalPost('search/node', array('keys' => 'short'), t('Search'));
|
||||
$this->assertText($node->title, t('Search for keyword worked'));
|
||||
$this->assertNoText(t('Add new comment'), t('Add new comment does not appear on search results page'));
|
||||
$this->assertText($node->title, 'Search for keyword worked');
|
||||
$this->assertNoText(t('Add new comment'), 'Add new comment does not appear on search results page');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1074,8 +1086,8 @@ class SearchCommentCountToggleTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Test comment count display for nodes with comment status set to Open
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertText(t('0 comments'), t('Empty comment count displays for nodes with comment status set to Open'));
|
||||
$this->assertText(t('1 comment'), t('Non-empty comment count displays for nodes with comment status set to Open'));
|
||||
$this->assertText(t('0 comments'), 'Empty comment count displays for nodes with comment status set to Open');
|
||||
$this->assertText(t('1 comment'), 'Non-empty comment count displays for nodes with comment status set to Open');
|
||||
|
||||
// Test comment count display for nodes with comment status set to Closed
|
||||
$this->searchable_nodes['0 comments']->comment = COMMENT_NODE_CLOSED;
|
||||
@@ -1084,8 +1096,8 @@ class SearchCommentCountToggleTestCase extends DrupalWebTestCase {
|
||||
node_save($this->searchable_nodes['1 comment']);
|
||||
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertNoText(t('0 comments'), t('Empty comment count does not display for nodes with comment status set to Closed'));
|
||||
$this->assertText(t('1 comment'), t('Non-empty comment count displays for nodes with comment status set to Closed'));
|
||||
$this->assertNoText(t('0 comments'), 'Empty comment count does not display for nodes with comment status set to Closed');
|
||||
$this->assertText(t('1 comment'), 'Non-empty comment count displays for nodes with comment status set to Closed');
|
||||
|
||||
// Test comment count display for nodes with comment status set to Hidden
|
||||
$this->searchable_nodes['0 comments']->comment = COMMENT_NODE_HIDDEN;
|
||||
@@ -1094,8 +1106,8 @@ class SearchCommentCountToggleTestCase extends DrupalWebTestCase {
|
||||
node_save($this->searchable_nodes['1 comment']);
|
||||
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertNoText(t('0 comments'), t('Empty comment count does not display for nodes with comment status set to Hidden'));
|
||||
$this->assertNoText(t('1 comment'), t('Non-empty comment count does not display for nodes with comment status set to Hidden'));
|
||||
$this->assertNoText(t('0 comments'), 'Empty comment count does not display for nodes with comment status set to Hidden');
|
||||
$this->assertNoText(t('1 comment'), 'Non-empty comment count does not display for nodes with comment status set to Hidden');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,7 +1172,7 @@ class SearchSimplifyTestCase extends DrupalWebTestCase {
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$string .= chr($i);
|
||||
}
|
||||
$this->assertIdentical(' ', search_simplify($string), t('Search simplify works for ASCII control characters.'));
|
||||
$this->assertIdentical(' ', search_simplify($string), 'Search simplify works for ASCII control characters.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1316,7 +1328,7 @@ class SearchNumbersTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('search/node',
|
||||
array('keys' => $number),
|
||||
t('Search'));
|
||||
$this->assertText($node->title, $type . ': node title shown (search found the node) in search for number ' . $number);
|
||||
$this->assertText($node->title, format_string('%type: node title shown (search found the node) in search for number %number.', array('%type' => $type, '%number' => $number)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1384,7 +1396,7 @@ class SearchNumberMatchingTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('search/node',
|
||||
array('keys' => 'foo'),
|
||||
t('Search'));
|
||||
$this->assertNoText($node->title, $i . ': node title not shown in dummy search');
|
||||
$this->assertNoText($node->title, format_string('%number: node title not shown in dummy search', array('%number' => $i)));
|
||||
|
||||
// Now verify that we can find node i by searching for any of the
|
||||
// numbers.
|
||||
@@ -1397,7 +1409,7 @@ class SearchNumberMatchingTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('search/node',
|
||||
array('keys' => $number),
|
||||
t('Search'));
|
||||
$this->assertText($node->title, $i . ': node title shown (search found the node) in search for number ' . $number);
|
||||
$this->assertText($node->title, format_string('%i: node title shown (search found the node) in search for number %number', array('%i' => $i, '%number' => $number)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1558,7 +1570,7 @@ class SearchConfigSettingsForm extends DrupalWebTestCase {
|
||||
$this->drupalGet($path);
|
||||
foreach ($modules as $module) {
|
||||
$title = $module_info[$module]['title'];
|
||||
$this->assertText($title, $title . ' search tab is shown');
|
||||
$this->assertText($title, format_string('%title search tab is shown', array('%title' => $title)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1567,7 +1579,7 @@ class SearchConfigSettingsForm extends DrupalWebTestCase {
|
||||
/**
|
||||
* Tests the search_excerpt() function.
|
||||
*/
|
||||
class SearchExcerptTestCase extends DrupalUnitTestCase {
|
||||
class SearchExcerptTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Search excerpt extraction',
|
||||
@@ -1577,8 +1589,7 @@ class SearchExcerptTestCase extends DrupalUnitTestCase {
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
drupal_load('module', 'search');
|
||||
parent::setUp();
|
||||
parent::setUp('search');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1603,7 +1614,7 @@ class SearchExcerptTestCase extends DrupalUnitTestCase {
|
||||
$this->assertEqual($result, 'The quick brown <strong>fox</strong> & jumps over the lazy dog ...', 'Found keyword is highlighted');
|
||||
|
||||
$longtext = str_repeat($text . ' ', 10);
|
||||
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $text));
|
||||
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $longtext));
|
||||
$this->assertTrue(strpos($result, $expected) === 0, 'When keyword is not found in long string, return value starts as expected');
|
||||
|
||||
$entities = str_repeat('készítése ', 20);
|
||||
@@ -1955,42 +1966,42 @@ class SearchLanguageTestCase extends DrupalWebTestCase {
|
||||
function testLanguages() {
|
||||
// Check that there are initially no languages displayed.
|
||||
$this->drupalGet('search/node');
|
||||
$this->assertNoText(t('Languages'), t('No languages to choose from.'));
|
||||
$this->assertNoText(t('Languages'), 'No languages to choose from.');
|
||||
|
||||
// Add predefined language.
|
||||
$edit = array('langcode' => 'fr');
|
||||
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$this->assertText('fr', t('Language added successfully.'));
|
||||
$this->assertText('fr', 'Language added successfully.');
|
||||
|
||||
// Now we should have languages displayed.
|
||||
$this->drupalGet('search/node');
|
||||
$this->assertText(t('Languages'), t('Languages displayed to choose from.'));
|
||||
$this->assertText(t('English'), t('English is a possible choice.'));
|
||||
$this->assertText(t('French'), t('French is a possible choice.'));
|
||||
$this->assertText(t('Languages'), 'Languages displayed to choose from.');
|
||||
$this->assertText(t('English'), 'English is a possible choice.');
|
||||
$this->assertText(t('French'), 'French is a possible choice.');
|
||||
|
||||
// Ensure selecting no language does not make the query different.
|
||||
$this->drupalPost('search/node', array(), t('Advanced search'));
|
||||
$this->assertEqual($this->getUrl(), url('search/node/', array('absolute' => TRUE)), t('Correct page redirection, no language filtering.'));
|
||||
$this->assertEqual($this->getUrl(), url('search/node/', array('absolute' => TRUE)), 'Correct page redirection, no language filtering.');
|
||||
|
||||
// Pick French and ensure it is selected.
|
||||
$edit = array('language[fr]' => TRUE);
|
||||
$this->drupalPost('search/node', $edit, t('Advanced search'));
|
||||
$this->assertFieldByXPath('//input[@name="keys"]', 'language:fr', t('Language filter added to query.'));
|
||||
$this->assertFieldByXPath('//input[@name="keys"]', 'language:fr', 'Language filter added to query.');
|
||||
|
||||
// Change the default language and disable English.
|
||||
$path = 'admin/config/regional/language';
|
||||
$this->drupalGet($path);
|
||||
$this->assertFieldChecked('edit-site-default-en', t('English is the default language.'));
|
||||
$this->assertFieldChecked('edit-site-default-en', 'English is the default language.');
|
||||
$edit = array('site_default' => 'fr');
|
||||
$this->drupalPost(NULL, $edit, t('Save configuration'));
|
||||
$this->assertNoFieldChecked('edit-site-default-en', t('Default language updated.'));
|
||||
$this->assertNoFieldChecked('edit-site-default-en', 'Default language updated.');
|
||||
$edit = array('enabled[en]' => FALSE);
|
||||
$this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
|
||||
$this->assertNoFieldChecked('edit-enabled-en', t('Language disabled.'));
|
||||
$this->assertNoFieldChecked('edit-enabled-en', 'Language disabled.');
|
||||
|
||||
// Check that there are again no languages displayed.
|
||||
$this->drupalGet('search/node');
|
||||
$this->assertNoText(t('Languages'), t('No languages to choose from.'));
|
||||
$this->assertNoText(t('Languages'), 'No languages to choose from.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2036,3 +2047,86 @@ class SearchNodeAccessTest extends DrupalWebTestCase {
|
||||
$this->assertText($node->title);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node search with query tags.
|
||||
*/
|
||||
class SearchNodeTagTest extends DrupalWebTestCase {
|
||||
public $test_user;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node search query tags',
|
||||
'description' => 'Tests Node search tags functionality.',
|
||||
'group' => 'Search',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('search', 'search_node_tags');
|
||||
node_access_rebuild();
|
||||
|
||||
// Create a test user and log in.
|
||||
$this->test_user = $this->drupalCreateUser(array('search content'));
|
||||
$this->drupalLogin($this->test_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct tags are available and hooks invoked.
|
||||
*/
|
||||
function testNodeSearchQueryTags() {
|
||||
$this->drupalCreateNode(array('body' => array(LANGUAGE_NONE => array(array('value' => 'testing testing testing.')))));
|
||||
|
||||
// Update the search index.
|
||||
module_invoke_all('update_index');
|
||||
search_update_totals();
|
||||
|
||||
$edit = array('keys' => 'testing');
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
|
||||
$this->assertTrue(variable_get('search_node_tags_test_query_tag', FALSE), 'hook_query_alter() was invoked and the query contained the "search_node" tag.');
|
||||
$this->assertTrue(variable_get('search_node_tags_test_query_tag_hook', FALSE), 'hook_query_search_node_alter() was invoked.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests searching with locale values set.
|
||||
*/
|
||||
class SearchSetLocaleTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Search with numeric locale set',
|
||||
'description' => 'Check that search works with numeric locale settings',
|
||||
'group' => 'Search',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('search');
|
||||
|
||||
// Create a simple node so something will be put in the index.
|
||||
$info = array(
|
||||
'body' => array(LANGUAGE_NONE => array(array('value' => 'Tapir'))),
|
||||
);
|
||||
$this->drupalCreateNode($info);
|
||||
|
||||
// Run cron to index.
|
||||
$this->cronRun();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that search works with a numeric locale set.
|
||||
*/
|
||||
public function testSearchWithNumericLocale() {
|
||||
// French decimal point is comma.
|
||||
setlocale(LC_NUMERIC, 'fr_FR');
|
||||
|
||||
// An exception will be thrown if a float in the wrong format occurs in the
|
||||
// query to the database, so an assertion is not necessary here.
|
||||
db_select('search_index', 'i')
|
||||
->extend('searchquery')
|
||||
->searchexpression('tapir', 'node')
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
@@ -4,3 +4,9 @@ package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-04-02
|
||||
version = "7.36"
|
||||
project = "drupal"
|
||||
datestamp = "1427943826"
|
||||
|
||||
|
@@ -4,3 +4,9 @@ package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-04-02
|
||||
version = "7.36"
|
||||
project = "drupal"
|
||||
datestamp = "1427943826"
|
||||
|
||||
|
12
modules/search/tests/search_node_tags.info
Normal file
12
modules/search/tests/search_node_tags.info
Normal file
@@ -0,0 +1,12 @@
|
||||
name = "Test search node tags"
|
||||
description = "Support module for Node search tags testing."
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2015-04-02
|
||||
version = "7.36"
|
||||
project = "drupal"
|
||||
datestamp = "1427943826"
|
||||
|
23
modules/search/tests/search_node_tags.module
Normal file
23
modules/search/tests/search_node_tags.module
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Dummy module implementing a node search hooks for search module testing.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_query_alter().
|
||||
*/
|
||||
function search_node_tags_query_alter(QueryAlterableInterface $query) {
|
||||
if ($query->hasTag('search_node')) {
|
||||
variable_set('search_node_tags_test_query_tag', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter().
|
||||
*/
|
||||
function search_node_tags_query_search_node_alter(QueryAlterableInterface $query) {
|
||||
variable_set('search_node_tags_test_query_tag_hook', TRUE);
|
||||
}
|
Reference in New Issue
Block a user