diff --git modules/simpletest/drupal_web_test_case.php modules/simpletest/drupal_web_test_case.php
index df4c82b..59fb766 100644
--- modules/simpletest/drupal_web_test_case.php
+++ modules/simpletest/drupal_web_test_case.php
@@ -2772,6 +2772,7 @@ class DrupalWebTestCase extends DrupalTestCase {
    *   Value of the field to assert.
    * @param $message
    *   Message to display.
+   *
    * @return
    *   TRUE on pass, FALSE on fail.
    */
@@ -2782,6 +2783,35 @@ class DrupalWebTestCase extends DrupalTestCase {
   }
 
   /**
+   * Assert that the most recently sent e-mail message has the pattern in it.
+   *
+   * @param $name
+   *   Name of field or message property to assert: subject, body, id, ...
+   * @param $regex
+   *   Pattern to search for.
+   * @param $message
+   *   Message to display
+   *
+   * @return
+   *   TRUE on pass, FALSE on fail.
+   */
+  protected function assertMailPattern($name, $regex, $message) {
+    $mails = $this->drupalGetMails();
+    $mail = end($mails);
+    $regex_found = preg_match("/$regex/", $mail[$name]);
+    return $this->assertTrue($regex_found, $message);
+  }
+
+  /**
+   * Output to verbose the most recent email sent.
+   */
+  protected function verboseEmail() {
+    $mails = $this->drupalGetMails();
+    $mail = end($mails);
+    $this->verbose(t('Latest e-mail was:') . '<pre>' . print_r($mail, TRUE) . '</pre>');
+  }
+
+  /**
    * Log verbose message in a text file.
    *
    * The a link to the vebose message will be placed in the test results via
diff --git modules/system/system.module modules/system/system.module
index 72c6e6a..e1e1b94 100644
--- modules/system/system.module
+++ modules/system/system.module
@@ -2961,7 +2961,16 @@ function system_send_email_action($entity, $context) {
 
   $recipient = token_replace($context['recipient'], $context);
 
-  $language = user_preferred_language($account);
+  // If the recipient is a registered user with a language preference, use
+  // the recipient's preferred language. Otherwise, use the current user's
+  // preferred language.
+  $recipient_account = user_load_by_mail($recipient);
+  if ($recipient_account) {
+    $language = user_preferred_language($recipient_account);
+  }
+  else {
+    $language = user_preferred_language($context['account']);
+  }
   $params = array('context' => $context);
 
   if (drupal_mail('system', 'action_send_email', $recipient, $language, $params)) {
diff --git modules/system/system.test modules/system/system.test
index 42bb46b..a53d565 100644
--- modules/system/system.test
+++ modules/system/system.test
@@ -1715,3 +1715,127 @@ class ShutdownFunctionsTest extends DrupalWebTestCase {
     $this->assertText(t('Second shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2)));
   }
 }
+
+/**
+ * Test system actions.
+ */
+class SystemActionsTest extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'System Actions',
+      'description' => 'Test actions provided by system module',
+      'group' => 'System'
+    );
+  }
+
+  function setUp() {
+    parent::setUp('trigger', 'taxonomy');
+  }
+
+  /**
+   * Test system_send_email_action.
+   *
+   * Creates a system send email action, associates it with the node_view
+   * trigger. Views the node, tests the email.
+   */
+  function testSystemSendEmailAction() {
+    $test_user = $this->drupalCreateUser(array('administer actions', 'access content', 'create article content'));
+    $this->drupalLogin($test_user);
+    // Create an article that we will view later;
+    $this->drupalPost('node/add/article', array('title' => t("some title"), 'body[und][0][value]' => t('some body')), t('Save'));
+    $this->assertText(t("Article some title has been created"));
+    $saved_node = $this->getUrl();
+
+    // Configure an email action that we will trigger.
+    $action_label = $this->randomName(16);
+    $send_mail_action_edit = array(
+      'actions_label' => $action_label,
+      'recipient' => $this->randomName(8) . "@example.com",
+      'subject' => $this->randomName(8),
+      'message' => t('Node viewed:[node:title]'),
+    );
+    $aid = $this->configureAdvancedAction('system_send_email_action', $send_mail_action_edit);
+    $hook = 'node_view';
+    $edit = array(
+      'aid' => md5($aid),
+    );
+    $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'), array(), array(), 'trigger-node-view-assign-form');
+
+    // Verify that the action has been assigned to the correct hook.
+    $actions = trigger_get_assigned_actions($hook);
+    $this->assertEqual(1, count($actions), t('One Action assigned to the hook'));
+    $this->assertEqual($actions[$aid]['label'], $action_label, t('Correct action label found.'));
+
+    // Visit the page we created earlier and trigger sending an email.
+    $this->drupalGet($saved_node);
+    $this->verboseEmail();
+    $this->assertMail('to', $send_mail_action_edit['recipient'], t("Correct recipient for email"));
+    $this->assertMailPattern('body', t('Node viewed:some title'), t("Email body is correct and has expanded token"));
+  }
+
+  /**
+   * Test system_message_action.
+   *
+   * Configure system message action. Associate it with taxonomy term insert
+   * trigger. Create a taxonomy term. View the message.
+   */
+  function testSystemMessageAction() {
+    $test_user = $this->drupalCreateUser(array('administer actions', 'administer taxonomy', 'access content', 'create article content'));
+    $this->drupalLogin($test_user);
+
+    // Configure a message action to trigger.
+    $system_message_action_edit = array(
+      'actions_label' => $this->randomName(16),
+      'message' => $this->randomName(16),
+    );
+    $aid = $this->configureAdvancedAction('system_message_action', $system_message_action_edit);
+    $edit = array(
+      'aid' => md5($aid),
+    );
+    $this->drupalPost('admin/structure/trigger/taxonomy', $edit, t('Assign'), array(), array(), 'trigger-taxonomy-term-insert-assign-form');
+
+    // Verify that the action has been assigned to the correct hook.
+    $actions = trigger_get_assigned_actions('taxonomy_term_insert');
+    $this->assertEqual(1, count($actions), t('One Action assigned to the hook'));
+    $this->assertEqual($actions[$aid]['label'], $system_message_action_edit['actions_label'], t('Correct action label found.'));
+
+    // Now create a taxonomy term and look for the message we configured.
+    $this->drupalPost('admin/structure/taxonomy/1/add', array('name' => t("some taxonomy term")), t('Save'));
+    $this->assertText(t("Created new term"));
+
+    // Should have triggered system message.
+    $this->assertText($system_message_action_edit['message']);
+  }
+
+  /**
+   * Configure an advanced action.
+   *
+   * @param string $hook
+   *   The name of the hook. For example: 'user_presave', 'user_login'
+   * @param array $action_configure_edit
+   *   The $edit array for the form to be used to configure.
+   *   Example members would be 'actions_label' (always), 'message', etc.
+   *
+   * @return integer
+   *   the aid (action id) of the configured action, or -1 if none.
+   */
+  protected function configureAdvancedAction($hook, $action_configure_edit) {
+    // Create an advanced action.
+    $hash = md5($hook);
+    $this->drupalPost("admin/config/system/actions/configure/$hash", $action_configure_edit, t('Save'));
+    $this->assertText(t('The action has been successfully saved.'));
+
+    // Now we have to find out the action ID of what we created.
+    $cell_to_find = "//div/table/tbody/tr/td[2][. = '{$action_configure_edit['actions_label']}']/../td[3]/a[@href]";
+    $this->assertFieldByXPath($cell_to_find, t('configure'), t('Found the configure link'));
+    $atag = $this->xpath($cell_to_find);
+    $this->assertTrue(is_object($atag[0]), t("Found the cell with 'configure' in it"));
+    if (is_object($atag[0])) {
+      $href = (string)$atag[0]->attributes()->href;
+      $aid = preg_replace('/^.*\//', '', (string)$href);
+      $this->verbose(t('The action ID for configured action hook=@hook is aid=@aid.', array('@hook' => $hook, '@aid' => $aid)));
+      return $aid;
+    }
+    return -1;
+  }
+}
