acquia_search.test in Acquia Connector 7.2
Same filename and directory in other branches
Tests for the Acquia Search module.
File
acquia_search/tests/acquia_search.testView source
<?php
/**
* @file
* Tests for the Acquia Search module.
*/
use Drupal\acquia_search\PreferredSearchCoreService;
/**
* Unit tests of the functionality of the Acquia Search module.
*/
class AcquiaSearchUnitTestCase extends DrupalUnitTestCase {
protected $id;
protected $key;
protected $salt;
protected $derivedKey;
public static function getInfo() {
return array(
'name' => 'Acquia Search unit tests',
'description' => 'Tests the low level Acquia Search functions.',
'group' => 'Acquia',
);
}
/**
* Overrides DrupalTestCase::setUp().
*/
public function setUp() {
parent::setUp();
require_once dirname(dirname(__FILE__)) . '/acquia_search.module';
// Generate and store a random set of credentials.
// Make them as close to the production values as possible
// Something like AAAA-1234
$this->id = $this
->randomName(10);
// Most of the keys and salts have a 32char lenght
$this->key = $this
->randomName(32);
$this->salt = $this
->randomName(32);
// Create a derived key from these values
$this->derivedKey = _acquia_search_create_derived_key($this->salt, $this->id, $this->key);
}
/**
* Tests derived key generation.
*/
public function testDerivedKey() {
// Mimic the hashing code in the API function.
$derivation_string = $this->id . 'solr' . $this->salt;
// str_pad extends the string with the same string in this case
// until it has filled 80 chars.
$derived_key = hash_hmac('sha1', str_pad($derivation_string, 80, $derivation_string), $this->key);
// $this->derivedKey is generated from the API function.
// @see setUp()
$this
->assertEqual($this->derivedKey, $derived_key, t('Derived key API function generates the expected hash.'), 'Acquia Search');
}
/**
* Tests HMAC generation.
*/
public function testHMACCookie() {
// Generate the expected hash.
$time = time();
$nonce = $this
->randomName(32);
$string = $time . $nonce . $this
->randomName();
$hmac = hash_hmac('sha1', $time . $nonce . $string, $this->derivedKey);
// @todo Make the API function more testable.
$authenticator = acquia_search_authenticator($string, $nonce, $this->derivedKey, $time);
preg_match('/acquia_solr_hmac=([a-zA-Z0-9]{40});/', $authenticator, $matches);
$this
->assertEqual($hmac, $matches[1], t('HMAC API function generates the expected hmac hash.'), 'Acquia Search');
preg_match('/acquia_solr_time=([0-9]{10});/', $authenticator, $matches);
$this
->assertNotNull($matches, t('HMAC API function generates a timestamp.'), 'Acquia Search');
preg_match('/acquia_solr_nonce=([a-zA-Z0-9]{32});/', $authenticator, $matches);
$this
->assertEqual($nonce, $matches[1], t('HMAC API function generates the expected nonce.'), 'Acquia Search');
}
/**
* Tests validating a response via the API functions.
*/
public function testValidResponse() {
// Generate the expected hash.
$nonce = $this
->randomName(32);
$string = $this
->randomName(32);
$hmac = hash_hmac('sha1', $nonce . $string, $this->derivedKey);
// Pass the expected hmac digest, API function should return TRUE.
$valid = acquia_search_valid_response($hmac, $nonce, $string, $this->derivedKey);
$this
->assertTrue($valid, t('Response flagged as valid when the expected hash is passed.'), 'Acquia Search');
// Invalidate the hmac digest, API function should return FALSE.
$bad_hmac = $hmac . 'invalidateHash';
$invalid_hmac = acquia_search_valid_response($bad_hmac, $nonce, $string, $this->derivedKey);
$this
->assertFalse($invalid_hmac, t('Response flagged as invalid when a malformed hash is passed.'), 'Acquia Search');
// Invalidate the nonce, API function should return FALSE.
$bad_nonce = $nonce . 'invalidateString';
$invalid_nonce = acquia_search_valid_response($hmac, $bad_nonce, $bad_nonce, $this->derivedKey);
$this
->assertFalse($invalid_nonce, t('Response flagged as invalid when a malformed nonce is passed.'), 'Acquia Search');
// Invalidate the string, API function should return FALSE.
$bad_string = $string . 'invalidateString';
$invalid_string = acquia_search_valid_response($hmac, $nonce, $bad_string, $this->derivedKey);
$this
->assertFalse($invalid_string, t('Response flagged as invalid when a malformed string is passed.'), 'Acquia Search');
// Invalidate the derived key, API function should return FALSE.
$bad_key = $this->derivedKey . 'invalidateKey';
$invalid_key = acquia_search_valid_response($hmac, $nonce, $string, $bad_key);
$this
->assertFalse($invalid_key, t('Response flagged as invalid when a malformed derived key is passed.'), 'Acquia Search');
}
/**
* Tests extracting the hmac digest from the response header.
*/
public function testExtractHMACHeader() {
// Generate the expected hash.
$nonce = $this
->randomName(32);
$string = $this
->randomName(32);
$hmac = hash_hmac('sha1', $nonce . $string, $this->derivedKey);
// Pass header with an expected pragma.
$header = array(
'pragma' => 'hmac_digest=' . $hmac . ';',
);
$extracted = acquia_search_extract_hmac($header);
$this
->assertEqual($hmac, $extracted, t('The HMAC digest was extracted from the response header.'), 'Acquia Search');
// Pass header with a bad pragma.
$bad_header1 = array(
'pragma' => $this
->randomName(),
);
$bad_extracted1 = acquia_search_extract_hmac($bad_header1);
$this
->assertEqual('', $bad_extracted1, t('Empty string returned by HMAC extraction function when an invalid pragma is passed.'), 'Acquia Search');
// Pass in junk as the header.
$bad_extracted2 = acquia_search_extract_hmac($this
->randomName());
$this
->assertEqual('', $bad_extracted2, t('Empty string returned by HMAC extraction function when an invalid header is passed.'), 'Acquia Search');
}
/**
* Tests that Acquia Search properly overrides the Apachesolr connection
* details to avoid unintended writing to a wrong search index.
*/
public function testApacheSolrOverride() {
global $conf;
$acquia_identifier = $this->id;
$site_folder = $this
->randomName(32);
$solr_hostname = $this
->randomName(10) . '.acquia-search.com';
$available_cores = array(
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}.dev.{$site_folder}",
),
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}.dev.testdbname",
),
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}",
),
);
$environments = $this
->getMockedEnvironments();
// No Acquia hosting and DB detected - should override into Readonly.
unset($conf['apachesolr_environments']);
$ah_env = NULL;
$ah_db_name = '';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
// Acquia Dev hosting environment detected - configs point to the index on the Dev environment.
unset($conf['apachesolr_environments']);
$ah_env = 'dev';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']));
$this
->assertTrue(!empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA']['url'], "http://{$solr_hostname}/solr/{$acquia_identifier}.dev.{$site_folder}");
// Acquia dev environment and a DB name.
unset($conf['apachesolr_environments']);
$ah_env = 'dev';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']));
$this
->assertTrue(!empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA']['url'], "http://{$solr_hostname}/solr/{$acquia_identifier}.dev.{$ah_db_name}");
// Acquia Test environment and a DB name. According to the mock, no cores available for the Test environment so it is read only.
unset($conf['apachesolr_environments']);
$ah_env = 'test';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['url']));
// Acquia Prod environment and a DB name but AH_PRODUCTION isn't set - so read only.
unset($conf['apachesolr_environments']);
$ah_env = 'prod';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['url']));
// Acquia Prod environment and a DB name and AH_PRODUCTION is set - so it should override to connect to the prod index.
unset($conf['apachesolr_environments']);
$_SERVER['AH_PRODUCTION'] = 1;
$ah_env = 'prod';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']));
$this
->assertTrue(!empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA']['url'], "http://{$solr_hostname}/solr/{$acquia_identifier}");
// Trying to override already overridden settings should not succeed.
unset($_SERVER['AH_PRODUCTION']);
$ah_env = 'dev';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$this
->assertTrue(empty($conf['apachesolr_environments']['ACQUIA']['conf']['apachesolr_read_only']));
$this
->assertTrue(!empty($conf['apachesolr_environments']['ACQUIA']['conf']['acquia_search_key']));
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA']['url'], "http://{$solr_hostname}/solr/{$acquia_identifier}");
}
/**
* Tests that it selects the correct preferred search core ID for the
* override URL when limited number of core ID is available.
*/
public function testApacheSolrOverrideWhenCoreWithDbNameNotAvailable() {
// When the core ID with the DB name in it is not available, it should
// override the URL value with the core ID that has the site folder name
// in it.
global $conf;
unset($conf['apachesolr_environments']);
$acquia_identifier = $this->id;
$site_folder = $this
->randomName(32);
$solr_hostname = $this
->randomName(10) . '.acquia-search.com';
$available_cores = array(
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}.dev.{$site_folder}",
),
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}",
),
);
$environments = $this
->getMockedEnvironments();
$ah_env = 'dev';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$expected_url = "http://{$solr_hostname}/solr/{$acquia_identifier}.dev.{$site_folder}";
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA']['url'], $expected_url);
}
/**
* Tests that all existing Acquia Search environments for apachesolr get
* overridden.
*/
public function testApacheSolrOverrideAllAcquiaEnvironments() {
global $conf;
unset($conf['apachesolr_environments']);
$acquia_identifier = $this->id;
$site_folder = $this
->randomName(32);
$solr_hostname = $this
->randomName(10) . '.acquia-search.com';
$available_cores = array(
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}.dev.{$site_folder}",
),
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}.dev.testdbname",
),
array(
'balancer' => $solr_hostname,
'core_id' => "{$acquia_identifier}",
),
);
$environments = $this
->getMockedEnvironments();
$ah_env = 'dev';
$ah_db_name = 'testdbname';
$core_service = new PreferredSearchCoreService($acquia_identifier, $ah_env, $site_folder, $ah_db_name, $available_cores);
acquia_search_add_apachesolr_overrides($core_service, $environments);
$expected_url = "http://{$solr_hostname}/solr/{$acquia_identifier}.dev.{$ah_db_name}";
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA']['url'], $expected_url);
$this
->assertIdentical($conf['apachesolr_environments']['ACQUIA_2']['url'], $expected_url);
$this
->assertTrue(empty($conf['apachesolr_environments']['NON-ACQUIA']['url']));
}
/**
* Returns mocked apachesolr environments.
*/
public function getMockedEnvironments() {
return array(
'ACQUIA' => array(
'env_id' => 'acquia_search_server_1',
'name' => 'Acquia Search',
'url' => 'http://mock.acquia-search.com/solr/ABCD-12345',
'service_class' => 'AcquiaSearchService',
'table' => 'apachesolr_environment',
'type' => 'Normal',
'export_type' => 1,
'index_bundles' => array(
'node' => array(
0 => 'article',
1 => 'page',
),
),
),
'ACQUIA_2' => array(
'env_id' => 'acquia_search_server_2',
'name' => 'Acquia Search 2',
'url' => 'http://mock.acquia-search.com/solr/XYZW-12345',
'service_class' => 'AcquiaSearchService',
'table' => 'apachesolr_environment',
'type' => 'Normal',
'export_type' => 1,
'index_bundles' => array(
'node' => array(
0 => 'article',
1 => 'page',
),
),
),
'NON-ACQUIA' => array(
'env_id' => 'solr',
'name' => 'localhost server',
'url' => 'http://localhost:8983/solr',
'service_class' => '',
'table' => 'apachesolr_environment',
'type' => 'Normal',
'export_type' => 1,
'index_bundles' => array(
'node' => array(
0 => 'article',
1 => 'page',
),
),
'conf' => array(
'apachesolr_index_last' => array(),
),
),
);
}
}
/**
* Tests the functionality of the Acquia Search module.
*/
class AcquiaSearchWebTestCase extends DrupalWebTestCase {
protected $id;
protected $key;
protected $salt;
protected $derivedKey;
protected $url;
public static function getInfo() {
return array(
'name' => 'Acquia Search UI tests',
'description' => 'Tests the Acquia Search user interface and functionality.',
'group' => 'Acquia',
);
}
/**
* Overrides DrupalTestCase::setUp().
*/
public function setUp() {
parent::setUp('acquia_agent', 'acquia_connector_test', 'search', 'apachesolr', 'apachesolr_search', 'acquia_search');
// Generate and store a random set of credentials.
$this->id = $this
->randomName(10);
$this->key = $this
->randomName(32);
$this->salt = $this
->randomName(32);
$this->derivedKey = _acquia_search_create_derived_key($this->salt, $this->id, $this->key);
$subscription = array(
'timestamp' => REQUEST_TIME - 60,
'active' => '1',
);
variable_set('acquia_identifier', $this->id);
variable_set('acquia_key', $this->key);
variable_set('acquia_subscription_data', $subscription);
$environment = acquia_search_get_environment();
$this->url = $environment['url'];
}
/**
* Creates an admin user.
*/
public function createAdminUser() {
$permissions = array(
'access content',
'search content',
'administer nodes',
'administer search',
);
return $this
->drupalCreateUser($permissions);
}
/**
* Creates an authenticated user that has access to search content.
*
* @return stdClass
* The user object of the authenticated user.
*
* @see DrupalWebTestCase::drupalCreateUser()
*/
public function createAuthenticatedUser() {
$permissions = array(
'search content',
);
return $this
->drupalCreateUser($permissions);
}
/**
* Method to clear static caches that could interrupt with the
* simpletest procedures for Acquia Search.
*/
public function clearStaticCache() {
// Reset the static to test for bug where default environment was only set
// on the current page load. We want to ensure the setting persists.
// @see http://drupal.org/node/1784804
drupal_static_reset('apachesolr_load_all_environments');
drupal_static_reset('apachesolr_default_environment');
}
/**
* Enables the environment of Acquia Search and clears the static caches so
* that the change is reflected in the API functions.
*/
public function enableAcquiaSearchEnvironment() {
// API function that creates the environemnt if it doesn't exist yet.
acquia_search_enable_acquia_solr_environment();
$this
->clearStaticCache();
}
/**
* Tests Acquia Search environment creation.
*
* Tests executed:
* - Acquia Search environment is saved and loaded.
* - Acquia Search environment is set as the default environment when created.
* - The service class is set to AcquiaSearchService.
* - The environment's URL is built as expected.
*/
public function testEnvironment() {
$this
->enableAcquiaSearchEnvironment();
// Load the newly enabled environment
$environment = apachesolr_environment_load(ACQUIA_SEARCH_ENVIRONMENT_ID);
// Load the default environment variable
$default_environment = apachesolr_default_environment();
// Test all the things!
// Check if the environment is a valid variable
$this
->assertTrue($environment, t('Acquia Search environment saved.'), 'Acquia Search');
// Check if the default environment is Acquia Search
$this
->assertEqual(ACQUIA_SEARCH_ENVIRONMENT_ID, $default_environment, t('Acquia Search is set to the default environment.'), 'Acquia Search');
// Check if the service class is actually the Acquia Search Service Class
$class = isset($environment['service_class']) ? $environment['service_class'] : '';
$this
->assertEqual('AcquiaSearchService', $class, t('Acquia Search is using the AcquiaSearchService service class.'), 'Acquia Search');
// Check if the url is the same as the one we wanted to save.
$this
->assertEqual($this->url, $environment['url'], t('Acquia Search is connected to the expected URL.'), 'Acquia Search');
}
/**
* Tests that the Acquia Search environment shows up in the interface and that
* administrators cannot delete it.
*
* Tests executed:
* - Acquia Search environment is present in the UI.
* - Acquia Search is reflected as the default environment in the UI.
* - Admin user receives 403 when attempting to delete the environment.
*/
public function testEnvironmentUI() {
$this
->enableAcquiaSearchEnvironment();
$admin_user = $this
->createAdminUser();
$this
->drupalLogin($admin_user);
$settings_path = 'admin/config/search/apachesolr/settings';
$this
->drupalGet($settings_path);
$this
->assertText('Acquia Search', t('The Acquia Search environment is displayed in the UI.'), 'Acquia Search');
$path = 'admin/config/search/apachesolr/settings/' . ACQUIA_SEARCH_ENVIRONMENT_ID . '/edit';
$options = array(
'query' => array(
'destination' => $settings_path,
),
);
$link = l('Acquia Search', $path, $options);
$raw = t('!environment <em>(Default)</em>', array(
'!environment' => $link,
));
$this
->assertRaw($raw, t('The Acquia Search environment is reflected as the default in the UI.'), 'Acquia Search');
$this
->drupalGet('admin/config/search/apachesolr/settings/' . ACQUIA_SEARCH_ENVIRONMENT_ID . '/delete');
$this
->assertResponse(403, t('The Acquia Search environment cannot be deleted via the UI.'));
}
/**
* Tests that Apache Solr search is set as the default search when the Acquia
* Search environment is enabled.
*
* Tests executed:
* - The "search_default_module" variable is set to "apachesolr_search".
* - Executing a search via the core search block redirects to search/site.
*/
public function testDefaultSearch() {
$this
->enableAcquiaSearchEnvironment();
// Test that the default search variable is set to the expected value.
$default_search = variable_get('search_default_module', 'node');
$this
->assertEqual('apachesolr_search', $default_search, t('The default search is set to Apache Solr search when the Acquia Search environment is created.'), 'Acquia Search');
// Visit the homepage and execute a search through the core search block. It
// should redirect to "search/site/test" if working properly.
$authenticated_user = $this
->createAuthenticatedUser();
$this
->drupalLogin($authenticated_user);
$edit = array(
'search_block_form' => 'test',
);
$this
->drupalPost('', $edit, t('Search'));
$this
->assertUrl('search/site/test', array(), t('The core search block redirects to the Apache Solr search page.'), 'Acquia Search');
}
}
Classes
Name | Description |
---|---|
AcquiaSearchUnitTestCase | Unit tests of the functionality of the Acquia Search module. |
AcquiaSearchWebTestCase | Tests the functionality of the Acquia Search module. |