Newer
Older
<?php
/**
* @file
* Tests for the Mollom module.
*/
/**
* Indicates that Mollom testing keys are reseller keys.
*
* If the above keys are reseller keys, make sure to change this value to TRUE.
* If you set this to TRUE and you are testing with non-reseller keys, the
* tests will fail due to unprivileged API access.
*/
define('MOLLOM_TEST_RESELLER_KEY', FALSE);
/**
* Common base test class for Mollom tests.
*/
class MollomWebTestCase extends DrupalWebTestCase {
protected $profile = 'testing';
/**
* The text the user should see when they are blocked from submitting a form
* because the Mollom servers are unreachable.
*/
protected $fallback_message = 'The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.';
/**
* The text the user should see if there submission was determinted to be spam.
*/
protected $spam_message = 'Your submission has triggered the spam filter and will not be accepted.';
/**
* The text the user should see if they did not fill out the CAPTCHA correctly.
*/
Dries Buytaert
committed
protected $incorrect_message = 'The word verification was not completed correctly. Please complete this new word verification and try again.';
/**
* The text the user should see if the textual analysis was unsure about the
* content.
*/
protected $unsure_message = "To complete this form, please complete the word verification below.";
/**
* The text the user should see if the textual analysis determined that there
* was profane content.
*/
protected $profanity_message = "Your submission has triggered the profanity filter and will not be accepted until the inappropriate language is removed.";
/**
* The private key used during testing.
*/
/**
* The Mollom client class implementation to use.
*
* By default, we use MollomDrupalTest and test against production Mollom
* testing servers.
* Assign MollomDrupalTestLocal to test against local dummy/fake REST server.
*
* @see mollom.drupal.inc
*
* @var string
*/
protected $mollomClass = 'MollomDrupalTest';
/**
* Flag indicating whether to automatically create testing API keys.
*
* If mollom_testing_mode is enabled, Mollom module automatically uses the
* MollomDrupalTest client implementation. This implementation automatically
* creates testing API keys when being instantiated (and ensures to re-create
* testing API keys in case they vanish). The behavior is executed by default,
* but depends on the 'mollom_testing_create_keys' variable being TRUE.
*
* Some functional test cases verify that expected errors are displayed in
* case no or invalid API keys are configured. For such test cases, set this
* flag to FALSE to skip the automatic creation of testing keys.
*
* @see MollomDrupalTest::$createKeys
* @see MollomDrupalTest::createKeys()
*/
protected $createKeys = TRUE;
function __construct($test_id = NULL) {
parent::__construct($test_id);
// Hide this base class in assertions.
$this->skipClasses[__CLASS__] = TRUE;
}
/**
* Set up an administrative user account and testing keys.
*/
function setUp() {
// Grab the configured endpoints from the variables because the
// parent::setup() call will clear our variables.
$mollom_api_endpoint = variable_get('mollom_api_endpoint', '');
$mollom_test_api_endpoint = variable_get('mollom_test_api_endpoint', '');
// Re-initialize stored session_id and watchdog messages.
$this->resetResponseID();
$this->messages = array();
$modules = func_get_args();
$modules = (isset($modules[0]) ? $modules[0] : array());
// Automatically enable local testing server implementation.
if (strstr($this->mollomClass, 'Local') && !in_array('mollom_test_server', $modules)) {
$modules[] = 'mollom_test_server';
// If not explicitly disabled by a test, setup with Mollom.
Dries Buytaert
committed
if (empty($this->disableDefaultSetup)) {
$modules[] = 'mollom';
// Database logging is unconditionally required to assert watchdog messages.
$modules[] = 'dblog';
parent::setUp($modules);
// Save the Mollom client implementation to use for running the tests.
variable_set('mollom_class', $this->mollomClass);
Dries Buytaert
committed
// Save the flag telling the testing client implementation whether to
// automatically create testing API keys.
variable_set('mollom_testing_create_keys', $this->createKeys);
// Set the API server endpoints.
if ($mollom_api_endpoint) {
variable_set('mollom_api_endpoint', $mollom_api_endpoint);
}
if ($mollom_test_api_endpoint) {
variable_set('mollom_test_api_endpoint', $mollom_test_api_endpoint);
}
Daniel Kudwien
committed
// Disable testing mode warnings.
// drupal_set_message() starts a session, which disables page caching, and
// in turn, page/form cache related tests would not behave correctly.
Daniel Kudwien
committed
variable_set('mollom_testing_mode_omit_warning', TRUE);
// Log all messages.
variable_set('mollom_log_minimum_severity', WATCHDOG_DEBUG);
// D7's new default theme Bartik is bogus in various locations, which leads
// to failing tests.
// @todo Remove this override.
variable_set('theme_default', 'garland');
// If not explicitly disabled by a test, setup and validate testing keys,
// and create a default admin user.
if (empty($this->disableDefaultSetup)) {
$permissions = array(
Dries Buytaert
committed
'access administration pages',
'administer mollom',
Dries Buytaert
committed
'administer content types',
'administer permissions',
Dries Buytaert
committed
'administer users',
Daniel Kudwien
committed
'bypass node access',
);
if (module_exists('comment')) {
$permissions[] = 'access comments';
$permissions[] = 'post comments';
$permissions[] = 'skip comment approval';
$permissions[] = 'administer comments';
}
$this->admin_user = $this->drupalCreateUser($permissions);
if ($this->createKeys) {
$this->setKeys();
$this->assertValidKeys();
}
// Delete the testing site.
// Not (always) possible when working with local testing server, since
// getServerRecord() removes server records upon retrieval, so the site
// record may no longer exist.
// @todo Only remove keys after running the last test in a test case.
/*
if ($this->mollomClass == 'MollomDrupalTest') {
$this->deleteKeys();
}
// Capture any (remaining) watchdog messages.
$this->assertMollomWatchdogMessages();
parent::tearDown();
}
/**
* Assert any watchdog messages based on their severity.
*
* This function can be (repeatedly) invoked to assert new watchdog messages.
* All watchdog messages with a higher severity than WATCHDOG_NOTICE are
* considered as "severe".
* @param $max_severity
* (optional) A maximum watchdog severity level message constant that log
* messages must have to pass the assertion. All messages with a higher
* severity will fail. Defaults to WATCHDOG_NOTICE. If a severity level
* higher than WATCHDOG_NOTICE is passed, then at least one severe message
* is expected.
* @todo Add this to Drupal core.
protected function assertMollomWatchdogMessages($max_severity = WATCHDOG_NOTICE) {
// Ensure that all messages have been written before attempting to verify
// them. Actions executed within the test class may lead to log messages,
// but those get only logged when hook_exit() is triggered.
// mollom.module may not be installed by a test and thus not loaded yet.
drupal_load('module', 'mollom');
mollom_log_write();
module_load_include('inc', 'dblog', 'dblog.admin');
$this->messages = array();
$query = db_select('watchdog', 'w')
->fields('w')
->orderBy('w.timestamp', 'ASC');
// The comparison logic applied in this function is a bit confusing, since
// the values of watchdog severity level constants defined by RFC 3164 are
// negated to their actual "severity level" meaning:
// WATCHDOG_EMERGENCY is 0, WATCHDOG_NOTICE is 5, WATCHDOG_DEBUG is 7.
$fail_expected = ($max_severity < WATCHDOG_NOTICE);
$had_severe_message = FALSE;
foreach ($query->execute() as $row) {
$this->messages[$row->wid] = $row;
// Only messages with a maximum severity of $max_severity or less severe
// messages must pass. More severe messages need to fail. See note about
// severity level constant values above.
$output = theme_dblog_message(array('event' => $row, 'link' => FALSE));
if ($row->severity >= $max_severity) {
// Visually separate debug log messages from other messages.
if ($row->severity == WATCHDOG_DEBUG) {
$this->error($output, 'User notice');
}
else {
$this->pass(check_plain($row->type) . ': ' . $output, t('Watchdog'));
$this->fail(check_plain($row->type) . ': ' . $output, t('Watchdog'));
// In case a severe message is expected, non-severe messages always pass,
// since we would trigger a false positive test failure otherwise.
// However, in order to actually assert the expectation, there must have
// been at least one severe log message.
$had_severe_message = ($had_severe_message || $row->severity < WATCHDOG_NOTICE);
}
// Assert that there was a severe message, in case we expected one.
if ($fail_expected && !$had_severe_message) {
$this->fail(t('Severe log message was found.'), t('Watchdog'));
}
// Delete processed watchdog messages.
if (!empty($this->messages)) {
$seen_ids = array_keys($this->messages);
db_delete('watchdog')->condition('wid', $seen_ids)->execute();
}
}
/**
* Assert that the Mollom session id remains the same.
*
* The Mollom session id is only known to one server. If we are communicating
* with a different Mollom server (due to a refreshed server list or being
* redirected), then we will get a new session_id.
*
* @param $type
* The type of ID to assert; e.g., 'contentId', 'captchaId'.
* @param $id
* The ID of $type in the last request, as returned from Mollom.
* @param $new_expected
* (optional) Boolean indicating whether a new ID is expected; e.g., after
* incorrectly solving a CAPTCHA.
*/
protected function assertResponseID($type, $id, $new_expected = FALSE) {
if (!isset($this->responseIds[$type]) || $new_expected) {
// Use assertTrue() instead of pass(), to test !empty().
$this->assertTrue($id, t('New %type: %id', array(
'%type' => $type,
'%id' => $id,
)));
$this->responseIds[$type] = $id;
$this->assertSame($type, $id, $this->responseIds[$type]);
return $this->responseIds[$type];
}
/**
* Reset the statically cached Mollom session id.
*
* @param $type
* The type of ID to reset; e.g., 'contentId', 'captchaId'.
protected function resetResponseID($type = NULL) {
if (isset($type)) {
unset($this->responseIds[$type]);
}
else {
unset($this->responseIds);
}
}
/**
* Assert a Mollom session id in a form.
*
* This is a wrapper around assertResponseID() allows to assert that a proper
* Mollom session id is found in the form contained in the internal browser
* output. The usual flow is:
* - drupalGet() or drupalPost() requests or submits a form.
* - drupalGet() and drupalPost() invoke assertMollomWatchdogMessages()
* internally, which records all new watchdog messages.
* - This function, assertResponseIDInForm(), is invoked to assert that there
* is a Mollom session id and, depending on the recorded watchdog messages,
* that it either equals the last known session id or the new session id is
* used for future comparisons in case of a server redirect.
* - The return value of this function is used to invoke assertMollomData(),
* to verify that the proper session id was stored in the database.
*
* @param $type
* The type of ID to assert; e.g., 'contentId', 'captchaId'.
* @param $new_expected
* (optional) Boolean indicating whether a new ID is expected; e.g., after
* incorrectly solving a CAPTCHA.
protected function assertResponseIDInForm($type, $new_expected = FALSE) {
$id = $this->getFieldValueByName('mollom[' . $type . ']');
return $this->assertResponseID($type, $id, $new_expected);
* Instantiate a Mollom client and make it available on $this->mollom;
*
* @param $force
* (Optional) If true, then a new class is always instantiated.
protected function getClient($force = FALSE) {
if ($force || !isset($this->mollom)) {
// mollom.module may not be enabled in the parent site executing the test.
drupal_load('module', 'mollom');
$this->mollom = mollom($this->mollomClass, $force);
}
return $this->mollom;
}
/**
* Setup Mollom API keys for testing.
*
* New keys are only created if MollomWebTestCase::$createKeys or respectively
* the 'mollom_testing_create_keys' variable is set to TRUE.
*
Daniel Kudwien
committed
* @param bool $once
* (optional) Whether to disable the 'mollom_testing_create_keys' variable
* after the first call (and thus omit API key verifications on every page
* request). Defaults to FALSE; i.e., API keys are verified repetitively.
*
* @see MollomWebTestCase::$createKeys
* @see MollomDrupalTest::__construct()
* @see MollomDrupalTest::createKeys()
*/
protected function setKeys($once = FALSE) {
// Instantiate a Mollom client class.
// Depending on MollomWebTestCase::$createKeys and ultimately the
// 'mollom_testing_create_keys' variable, MollomDrupalTest::__construct()
// will automatically setup testing API keys.
$this->getClient();
$this->mollom->createKeys();
// Make API keys available to test methods.
if (!empty($this->mollom->publicKey)) {
$this->publicKey = $this->mollom->publicKey;
$this->privateKey = $this->mollom->privateKey;
// Multiple tests might be executed in a single request. Every test sets
// up a new child site from scratch. The Mollom class with testing API
// keys still exists in the test, but the configuration is gone.
$this->mollom->saveKeys();
Daniel Kudwien
committed
if ($once) {
variable_set('mollom_testing_create_keys', FALSE);
}
* Calls _mollom_status() directly to verify that current API keys are valid.
Dries Buytaert
committed
$status = _mollom_status(TRUE);
$this->assertMollomWatchdogMessages();
$this->assertIdentical($status['isVerified'], TRUE, t('Mollom servers can be contacted and testing API keys are valid.'));
/**
* Deletes the current testing site.
*/
protected function deleteKeys() {
if (!empty($this->mollom->publicKey)) {
$this->mollom->deleteSite($this->mollom->publicKey);
}
unset($this->publicKey, $this->privateKey, $this->mollom);
Daniel Kudwien
committed
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
/**
* Saves a mollom_form entity to protect a given form with Mollom.
*
* @param string $form_id
* The form id to protect.
* @param int $mode
* The protection mode. Defaults to MOLLOM_MODE_ANALYSIS.
* @param array $values
* (optional) An associative array of properties to additionally set on the
* mollom_form entity.
*
* @return int
* The save status, as returned by mollom_form_save().
*/
protected function setProtection($form_id, $mode = MOLLOM_MODE_ANALYSIS, $values = array()) {
if (!$mollom_form = mollom_form_load($form_id)) {
$mollom_form = mollom_form_new($form_id);
}
$mollom_form['mode'] = $mode;
if ($values) {
foreach ($values as $property => $value) {
$mollom_form[$property] = $value;
}
}
$status = mollom_form_save($mollom_form);
return $status;
}
/**
* Configure Mollom protection for a given form.
*
* @param $form_id
* The form id to configure.
Dries Buytaert
committed
* @param $mode
* The Mollom protection mode for the form.
* (optional) A list of form elements to enable for text analysis. If
* omitted and the form registers individual elements, all fields are
* enabled by default.
* @param $edit
* (optional) An array of POST data to pass through to drupalPost() when
* configuring the form's protection.
Daniel Kudwien
committed
protected function setProtectionUI($form_id, $mode = MOLLOM_MODE_ANALYSIS, $fields = NULL, $edit = array()) {
Dries Buytaert
committed
// Always start from overview page, also to make debugging easier.
$this->drupalGet('admin/config/content/mollom');
// Determine whether the form is already protected.
$exists = db_query_range('SELECT 1 FROM {mollom_form} WHERE form_id = :form_id', 0, 1, array(':form_id' => $form_id))->fetchField();
// Add a new form.
if (!$exists) {
$this->clickLink(t('Add form'));
$add_form_edit = array(
$this->drupalPost(NULL, $add_form_edit, t('Next'));
Dries Buytaert
committed
$this->assertLinkByHref('admin/config/content/mollom/manage/' . $form_id);
$this->drupalGet('admin/config/content/mollom/manage/' . $form_id);
$edit += array(
Dries Buytaert
committed
'mollom[mode]' => $mode,
);
// Process the enabled fields.
$form_list = mollom_form_list();
$form_info = mollom_form_info($form_id, $form_list[$form_id]['module']);
if (!empty($form_info['elements'])) {
$edit += array(
'mollom[checks][spam]' => TRUE,
);
}
foreach (array_keys($form_info['elements']) as $field) {
if (!isset($fields) || in_array($field, $fields)) {
// If the user specified all fields by default or to include this
// field, set its checkbox value to TRUE.
$edit['mollom[enabled_fields][' . rawurlencode($field) . ']'] = TRUE;
// Otherwise set the field's checkbox value to FALSE.
$edit['mollom[enabled_fields][' . rawurlencode($field) . ']'] = FALSE;
}
}
$this->drupalPost(NULL, $edit, t('Save'));
$this->assertText(t('The form protection has been added.'));
}
else {
$this->assertText(t('The form protection has been updated.'));
}
}
/**
* Remove Mollom protection for a given form.
*
* @param $form_id
* The form id to configure.
*/
protected function delProtection($form_id) {
// Determine whether the form is protected.
$exists = db_query_range('SELECT 1 FROM {mollom_form} WHERE form_id = :form_id', 0, 1, array(':form_id' => $form_id));
$this->drupalGet('admin/config/content/mollom/unprotect/' . $form_id);
$this->assertText(t('Mollom will no longer protect this form from spam.'), t('Unprotect confirmation form found.'));
$this->drupalPost(NULL, array(), t('Confirm'));
}
}
/**
* Assert that Mollom session data was stored for a submission.
*
* @param $entity
* The entity type to search for in {mollom}.
* @param $id
* The entity id to search for in {mollom}.
* @param $response_type
* (optional) The type of ID to assert; e.g., 'contentId', 'captchaId'.
* @param $response_id
* (optional) The ID of $type to assert additionally.
protected function assertMollomData($entity, $id, $response_type = '', $response_id = NULL) {
$data = mollom_data_load($entity, $id);
$this->assertTrue($data->id, t('Mollom session data for %entity @id exists: <pre>@data</pre>', array(
'%entity' => $entity,
'@id' => $id,
'@data' => var_export($data, TRUE),
)));
if (isset($response_id)) {
$this->assertSame(t('Stored @type ID', array('@type' => $response_type)), $data->$response_type, $response_id);
Dries Buytaert
committed
return $data;
}
/**
* Assert that no Mollom session data exists for a certain entity.
*/
protected function assertNoMollomData($entity, $id) {
$data = mollom_data_load($entity, $id);
$this->assertFalse($data, t('No Mollom session data exists for %entity @id.', array('%entity' => $entity, '@id' => $id)));
}
Dries Buytaert
committed
* Assert that the CAPTCHA field is found on the current page.
Daniel Kudwien
committed
$inputs = $this->xpath('//input[@type=:type and @name=:name]', array(
':type' => 'text',
':name' => 'mollom[captcha]',
));
$labels = $this->xpath('//label[@for=:for]/span[@class=:class]', array(
':for' => 'edit-mollom-captcha',
':class' => 'form-required',
));
$this->assert(!empty($inputs[0]) && !empty($labels[0]), 'Required CAPTCHA field found.');
Lisa Backer
committed
$image = $this->xpath('//img[@alt=:alt]', array(':alt' => t("Type the characters you see in this picture.")));
$this->assert(!empty($image), 'CAPTCHA image found.');
Dries Buytaert
committed
* Assert that the CAPTCHA field is not found on the current page.
Daniel Kudwien
committed
$this->assertNoText($this->unsure_message);
$this->assertNoText($this->incorrect_message);
$this->assertNoFieldByXPath('//input[@type="text"][@name="mollom[captcha]"]', '', 'CAPTCHA field not found.');
Lisa Backer
committed
$image = $this->xpath('//img[@alt=:alt]', array(':alt' => t("Type the characters you see in this picture.")));
$this->assert(empty($image), 'CAPTCHA image not found.');
Dries Buytaert
committed
/**
* Assert that the privacy policy link is found on the current page.
*/
protected function assertPrivacyLink() {
$elements = $this->xpath('//div[contains(@class, "mollom-privacy")]');
$this->assertTrue($elements, t('Privacy policy container found.'));
}
/**
* Assert that the privacy policy link is not found on the current page.
*/
protected function assertNoPrivacyLink() {
$elements = $this->xpath('//div[contains(@class, "mollom-privacy")]');
$this->assertFalse($elements, t('Privacy policy container not found.'));
}
/**
* Test submitting a form with a correct CAPTCHA value.
*
* @param $url
* The URL of the form, or NULL to use the current page.
* @param $edit
* An array of form values used in drupalPost().
* @param $button
* The text of the form button to click in drupalPost().
* @param $success_message
* An optional message to test does appear after submission.
*/
protected function postCorrectCaptcha($url, array $edit = array(), $button, $success_message = '') {
Daniel Kudwien
committed
if (isset($url)) {
$this->drupalGet($url);
}
$this->assertCaptchaField();
Daniel Kudwien
committed
$this->drupalPost(NULL, $edit, $button);
$this->assertNoCaptchaField();
$this->assertNoText($this->incorrect_message);
if ($success_message) {
$this->assertText($success_message);
}
}
/**
* Test submitting a form with an incorrect CAPTCHA value.
*
* @param $url
* The URL of the form, or NULL to use the current page.
* @param $edit
* An array of form values used in drupalPost().
* @param $button
* The text of the form button to click in drupalPost().
* @param $success_message
* An optional message to test does not appear after submission.
*/
protected function postIncorrectCaptcha($url, array $edit = array(), $button, $success_message = '') {
Daniel Kudwien
committed
if (isset($url)) {
$this->drupalGet($url);
}
$this->assertCaptchaField();
$edit['mollom[captcha]'] = 'incorrect';
$before_url = $this->getUrl();
Daniel Kudwien
committed
$this->drupalPost(NULL, $edit, $button);
$this->assertCaptchaField();
$this->assertText($this->incorrect_message);
if ($success_message) {
$this->assertNoText($success_message);
}
}
/**
* Test submitting a form with 'spam' values.
*
* @param $url
* The URL of the form, or NULL to use the current page.
* @param $spam_fields
* An array of form field names to inject spam content into.
* @param $edit
* An array of non-spam form values used in drupalPost().
* @param $button
* The text of the form button to click in drupalPost().
* @param $success_message
* An optional message to test does not appear after submission.
*/
protected function assertSpamSubmit($url, array $spam_fields, array $edit = array(), $button, $success_message = '') {
$edit += array_fill_keys($spam_fields, 'spam');
$this->drupalPost($url, $edit, $button);
Daniel Kudwien
committed
$this->assertNoCaptchaField();
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
$this->assertText($this->spam_message);
if ($success_message) {
$this->assertNoText($success_message);
}
}
/**
* Test submitting a form with 'ham' values.
*
* @param $url
* The URL of the form, or NULL to use the current page.
* @param $ham_fields
* An array of form field names to inject ham content into.
* @param $edit
* An array of non-spam form values used in drupalPost().
* @param $button
* The text of the form button to click in drupalPost().
* @param $success_message
* An optional message to test does appear after submission.
*/
protected function assertHamSubmit($url, array $ham_fields, array $edit = array(), $button, $success_message = '') {
$edit += array_fill_keys($ham_fields, 'ham');
$this->drupalPost($url, $edit, $button);
$this->assertNoCaptchaField($url);
$this->assertNoText($this->spam_message);
if ($success_message) {
$this->assertText($success_message);
}
}
/**
* Test submitting a form with unsure values and resulting CAPTCHA submissions.
*
* @param $url
* The URL of the form, or NULL to use the current page.
* @param $unsure_fields
* An array of form field names to inject unsure content into.
* @param $edit
* An array of non-spam form values used in drupalPost().
* @param $button
* The text of the form button to click in drupalPost().
* @param $success_message
* An optional message to test does appear after sucessful form and CAPTCHA
* submission.
*/
protected function assertUnsureSubmit($url, array $unsure_fields, array $edit = array(), $button, $success_message = '') {
$edit += array_fill_keys($unsure_fields, 'unsure');
$this->drupalPost($url, $edit, $button);
Daniel Kudwien
committed
$this->assertCaptchaField();
$this->assertText($this->unsure_message);
if ($success_message) {
$this->assertNoText($success_message);
}
$this->postIncorrectCaptcha(NULL, $edit, $button, $success_message);
$this->postCorrectCaptcha(NULL, $edit, $button, $success_message);
}
Daniel Kudwien
committed
/**
* Asserts that the most recently sent mail contains a "Report to Mollom" link.
*
* Contrary to DrupalWebTestCase::assertMail(), this function removes the last
* sent mail from the internally recorded stack.
*
* @param string $entity_type
* (optional) The expected entity type contained in the report link.
* Defaults to 'mollom_content'.
*
* @return array|false
* FALSE if the link was not found, or an associative array containing:
* - url: The full report link URL.
* - entity: The entity type contained in the report link URL.
* - id: The entity ID contained in the report link URL.
* - mail: The full mail message array, as recorded by TestingMailSystem.
* - external: TRUE.
* The array can be passed directly as $options to drupalGet().
Daniel Kudwien
committed
*/
protected function assertMailMollomReportLink($entity_type = 'mollom_content') {
// Grab the last sent mail.
// @see DrupalWebTestCase::assertMail()
$captured_emails = variable_get('drupal_test_email_collector', array());
$message = array_pop($captured_emails);
variable_set('drupal_test_email_collector', $captured_emails);
$found = FALSE;
// Determine the report URI pattern for the passed entity type.
$path = FALSE;
foreach (mollom_form_list() as $form_id => $info) {
if (isset($info['entity']) && $info['entity'] == $entity_type && isset($info['report path'])) {
$path = $info['report path'];
break;
}
}
if ($path) {
$path = strtr($path, array('%id' => '([^\s]+)'));
if (preg_match('@http.+?' . $path . '@', $message['body'], $matches)) {
$found = array(
'url' => $matches[0],
'entity' => $entity_type,
'id' => $matches[1],
'mail' => $message,
'external' => TRUE,
);
}
}
elseif (preg_match('@http.+?mollom/report/([^/]+)/([^\s]+)@', $message['body'], $matches)) {
Daniel Kudwien
committed
$found = array(
'url' => $matches[0],
'entity' => $matches[1],
'id' => $matches[2],
'mail' => $message,
'external' => TRUE,
Daniel Kudwien
committed
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
);
}
$this->assertTrue($found, t('Report to Mollom link found in e-mail: %url', array('%url' => $found['url'])));
$this->assertSame('Report link entity type', $found['entity'], $entity_type);
$this->assertMollomData($found['entity'], $found['id']);
return $found;
}
/**
* Asserts that the most recently sent mail does NOT contain a "Report to Mollom" link.
*
* Contrary to DrupalWebTestCase::assertMail(), this function removes the last
* sent mail from the internally recorded stack.
*
* @return bool
* TRUE if no link was found, FALSE otherwise.
*/
protected function assertNoMailMollomReportLink() {
// Grab the last sent mail.
// @see DrupalWebTestCase::assertMail()
$captured_emails = variable_get('drupal_test_email_collector', array());
$message = array_pop($captured_emails);
if (empty($message)) {
$this->fail('No mail to assert.');
return;
}
variable_set('drupal_test_email_collector', $captured_emails);
$found = preg_match('@http.+?mollom/report/([^/]+)/([^\s]+)@', $message['body'], $matches);
$this->assertFalse($found, 'Report to Mollom link not found in e-mail.');
if ($found) {
debug($message);
}
}
protected function getFieldValueByID($id) {
$fields = $this->xpath($this->constructFieldXpath('id', $id));
return (string) $fields[0]['value'];
}
/**
* Retrieve a field value by name.
*/
protected function getFieldValueByName($name) {
$fields = $this->xpath($this->constructFieldXpath('name', $name));
return (string) $fields[0]['value'];
* Retrieve sent request parameter values from testing server implementation.
* @param $resource
* (optional) The resource name to retrieve submitted values from. Defaults
* to 'content'.
Daniel Kudwien
committed
* @param $retain
* (optional) Whether to retain the (last) record being read. Defaults to
* FALSE; i.e., the record being read is removed.
Dries Buytaert
committed
* @see MollomWebTestCase::resetServerRecords()
Daniel Kudwien
committed
protected function getServerRecord($resource = 'content', $retain = FALSE) {
$function = 'mollom_test_server_' . $resource;
Daniel Kudwien
committed
// Ensure that we do not read obsolete/outdated data from variable_get()'s
// static cache while variables might have been updated in the child site.
$this->refreshVariables();
// Retrieve last recorded values.
$storage = variable_get($function, array());
Daniel Kudwien
committed
$return = ($retain ? end($storage) : array_shift($storage));
variable_set($function, $storage);
Dries Buytaert
committed
/**
* Resets recorded XML-RPC values.
*
* @param $resource
* (optional) The resource name to reset records of. Defaults to 'content'.
Dries Buytaert
committed
*
* @see MollomWebTestCase::getServerRecord()
*/
protected function resetServerRecords($resource = 'content') {
$function = 'mollom_test_server_' . $resource;
Dries Buytaert
committed
// Delete the variable.
variable_del($function);
}
/**
* Wraps drupalGet() for additional watchdog message assertion.
*
* @param $options
* In addition to regular $options that are passed to url():
* - watchdog: (optional) Boolean whether to assert that only non-severe
* watchdog messages have been logged. Defaults to TRUE. Use FALSE to
* negate the watchdog message severity assertion.
*
* @see DrupalWebTestCase->drupalGet()
* @see MollomWebTestCase->assertMollomWatchdogMessages()
* @see MollomWebTestCase->assertResponseID()
*/
protected function drupalGet($path, array $options = array(), array $headers = array()) {
$output = parent::drupalGet($path, $options, $headers);
$options += array('watchdog' => WATCHDOG_NOTICE);
$this->assertMollomWatchdogMessages($options['watchdog']);
return $output;
}
/**
* Wraps drupalPost() for additional watchdog message assertion.
*
* @param $options
* In addition to regular $options that are passed to url():
* - watchdog: (optional) Boolean whether to assert that only non-severe
* watchdog messages have been logged. Defaults to TRUE. Use FALSE to
* negate the watchdog message severity assertion.
*
* @see MollomWebTestCase->assertMollomWatchdogMessages()
* @see MollomWebTestCase->assertResponseID()
* @see DrupalWebTestCase->drupalPost()
*/
Dries Buytaert
committed
protected function drupalPost($path, $edit, $submit, array $options = array(), array $headers = array(), $form_html_id = NULL, $extra_post = NULL) {
$output = parent::drupalPost($path, $edit, $submit, $options, $headers, $form_html_id, $extra_post);
$options += array('watchdog' => WATCHDOG_NOTICE);
$this->assertMollomWatchdogMessages($options['watchdog']);
return $output;
}
Dries Buytaert
committed
* Asserts that two values belonging to the same variable are equal.
Dries Buytaert
committed
* Checks to see whether two values, which belong to the same variable name or
* identifier, are equal and logs a readable assertion message.
*
* @param $name
* A name or identifier to use in the assertion message.
* @param $first
* The first value to check.
* @param $second
* The second value to check.
Dries Buytaert
committed
*
* @return
* TRUE if the assertion succeeded, FALSE otherwise.
Dries Buytaert
committed
*
* @see MollomWebTestCase::assertNotSame()
*
* @todo D8: Move into core. This improved assertEqual() did not get into D7,
* since the function signature differs and it's plenty of work to manually
* update all assertEqual() invocations throughout all tests.
Dries Buytaert
committed
protected function assertSame($name, $first, $second) {
$message = t("@name: @first is equal to @second.", array(
Dries Buytaert
committed
'@first' => var_export($first, TRUE),
'@second' => var_export($second, TRUE),
));
$this->assertEqual($first, $second, $message);
}
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Asserts that two values belonging to the same variable are not equal.
Dries Buytaert
committed
*
Dries Buytaert
committed
* Checks to see whether two values, which belong to the same variable name or
* identifier, are not equal and logs a readable assertion message.
Dries Buytaert
committed
*
* @param $name
* A name or identifier to use in the assertion message.
* @param $first
* The first value to check.
* @param $second
* The second value to check.
Dries Buytaert
committed
*
Dries Buytaert
committed
* @return
* TRUE if the assertion succeeded, FALSE otherwise.
Dries Buytaert
committed
*
* @see MollomWebTestCase::assertSame()
Dries Buytaert
committed
*/
Dries Buytaert
committed
protected function assertNotSame($name, $first, $second) {
$message = t("@name: '@first' is not equal to '@second'.", array(
Dries Buytaert
committed
'@name' => $name,
Dries Buytaert
committed
'@first' => var_export($first, TRUE),
'@second' => var_export($second, TRUE),
Dries Buytaert
committed
));
$this->assertNotEqual($first, $second, $message);
}
Daniel Kudwien
committed
/**
* Enables aggressive page caching options to resemble reverse-proxies.
*/
protected function enablePageCache() {
variable_set('cache', 1);
variable_set('page_cache_maximum_age', 180);
// A minimum cache lifetime causes cache_clear_all() to start a session.
//variable_set('cache_lifetime', 60);
}
Daniel Kudwien
committed
/**
* Asserts a successful mollom_test_form submission.
*
* @param $old_mid
* (optional) The existing test record id to assert.
*/
protected function assertTestSubmitData($old_mid = NULL) {
$this->assertText('Successful form submission.');
$mid = $this->getFieldValueByName('mid');
if (isset($old_mid)) {
$this->assertSame('Test record id', $mid, $old_mid);
}
else {