security update core+modules

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-26 18:38:56 +02:00
parent 2f45ea820a
commit 7c96373038
1022 changed files with 30319 additions and 11259 deletions

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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'));

View File

@@ -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"

View File

@@ -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]);
}

View File

@@ -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.

View File

@@ -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 "&lt;' . $tag . '&gt;" 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> &amp; 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&eacute;sz&iacute;t&eacute;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();
}
}

View File

@@ -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"

View File

@@ -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"

View 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"

View 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);
}