cms/drupal/modules/trigger/trigger.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Tests for trigger.module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Provides common helper methods.
       
    10  */
       
    11 class TriggerWebTestCase extends DrupalWebTestCase {
       
    12 
       
    13   /**
       
    14    * Configures an advanced action.
       
    15    *
       
    16    * @param $action
       
    17    *   The name of the action callback. For example: 'user_block_user_action'
       
    18    * @param $edit
       
    19    *   The $edit array for the form to be used to configure.
       
    20    *   Example members would be 'actions_label' (always), 'message', etc.
       
    21    *
       
    22    * @return
       
    23    *   the aid (action id) of the configured action, or FALSE if none.
       
    24    */
       
    25   protected function configureAdvancedAction($action, $edit) {
       
    26     // Create an advanced action.
       
    27     $hash = drupal_hash_base64($action);
       
    28     $this->drupalPost("admin/config/system/actions/configure/$hash", $edit, t('Save'));
       
    29     $this->assertText(t('The action has been successfully saved.'));
       
    30 
       
    31     // Now we have to find out the action ID of what we created.
       
    32     return db_query('SELECT aid FROM {actions} WHERE callback = :callback AND label = :label', array(':callback' => $action, ':label' => $edit['actions_label']))->fetchField();
       
    33   }
       
    34 
       
    35 }
       
    36 
       
    37 /**
       
    38  * Provides tests for node triggers.
       
    39  */
       
    40 class TriggerContentTestCase extends TriggerWebTestCase {
       
    41   var $_cleanup_roles = array();
       
    42   var $_cleanup_users = array();
       
    43 
       
    44   public static function getInfo() {
       
    45     return array(
       
    46       'name' => 'Trigger content (node) actions',
       
    47       'description' => 'Perform various tests with content actions.',
       
    48       'group' => 'Trigger',
       
    49     );
       
    50   }
       
    51 
       
    52   function setUp() {
       
    53     parent::setUp('trigger', 'trigger_test');
       
    54   }
       
    55 
       
    56   /**
       
    57    * Tests several content-oriented trigger issues.
       
    58    *
       
    59    * These are in one function to assure they happen in the right order.
       
    60    */
       
    61   function testActionsContent() {
       
    62     global $user;
       
    63     $content_actions = array('node_publish_action', 'node_unpublish_action', 'node_make_sticky_action', 'node_make_unsticky_action', 'node_promote_action', 'node_unpromote_action');
       
    64 
       
    65     $test_user = $this->drupalCreateUser(array('administer actions'));
       
    66     $web_user = $this->drupalCreateUser(array('create page content', 'access content', 'administer nodes'));
       
    67     foreach ($content_actions as $action) {
       
    68       $hash = drupal_hash_base64($action);
       
    69       $info = $this->actionInfo($action);
       
    70 
       
    71       // Assign an action to a trigger, then pull the trigger, and make sure
       
    72       // the actions fire.
       
    73       $this->drupalLogin($test_user);
       
    74       $edit = array('aid' => $hash);
       
    75       $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'), array(), array(), 'trigger-node-presave-assign-form');
       
    76       // Create an unpublished node.
       
    77       $this->drupalLogin($web_user);
       
    78       $edit = array();
       
    79       $langcode = LANGUAGE_NONE;
       
    80       $edit["title"] = '!SimpleTest test node! ' . $this->randomName(10);
       
    81       $edit["body[$langcode][0][value]"] = '!SimpleTest test body! ' . $this->randomName(32) . ' ' . $this->randomName(32);
       
    82       $edit[$info['property']] = !$info['expected'];
       
    83       $this->drupalPost('node/add/page', $edit, t('Save'));
       
    84       // Make sure the text we want appears.
       
    85       $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"])), 'Make sure the Basic page has actually been created');
       
    86       // Action should have been fired.
       
    87       $loaded_node = $this->drupalGetNodeByTitle($edit["title"]);
       
    88       $this->assertTrue($loaded_node->{$info['property']} == $info['expected'], format_string('Make sure the @action action fired.', array('@action' => $info['name'])));
       
    89       // Leave action assigned for next test
       
    90 
       
    91       // There should be an error when the action is assigned to the trigger
       
    92       // twice.
       
    93       $this->drupalLogin($test_user);
       
    94       // This action already assigned in this test.
       
    95       $edit = array('aid' => $hash);
       
    96       $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'), array(), array(), 'trigger-node-presave-assign-form');
       
    97       $this->assertRaw(t('The action you chose is already assigned to that trigger.'), 'Check to make sure an error occurs when assigning an action to a trigger twice.');
       
    98 
       
    99       // The action should be able to be unassigned from a trigger.
       
   100       $this->drupalPost('admin/structure/trigger/unassign/node/node_presave/' . $hash, array(), t('Unassign'));
       
   101       $this->assertRaw(t('Action %action has been unassigned.', array('%action' => ucfirst($info['name']))), format_string('Check to make sure the @action action can be unassigned from the trigger.', array('@action' => $info['name'])));
       
   102       $assigned = db_query("SELECT COUNT(*) FROM {trigger_assignments} WHERE aid IN (:keys)", array(':keys' => $content_actions))->fetchField();
       
   103       $this->assertFalse($assigned, 'Check to make sure unassign worked properly at the database level.');
       
   104     }
       
   105   }
       
   106 
       
   107   /**
       
   108    * Tests multiple node actions.
       
   109    *
       
   110    * Verifies that node actions are fired for each node individually, if acting
       
   111    * on multiple nodes.
       
   112    */
       
   113   function testActionContentMultiple() {
       
   114     // Assign an action to the node save/update trigger.
       
   115     $test_user = $this->drupalCreateUser(array('administer actions', 'administer nodes', 'create page content', 'access administration pages', 'access content overview'));
       
   116     $this->drupalLogin($test_user);
       
   117     $nodes = array();
       
   118 
       
   119     for ($index = 0; $index < 3; $index++) {
       
   120       $nodes[] = $this->drupalCreateNode(array('type' => 'page'));
       
   121     }
       
   122 
       
   123     $action_id = 'trigger_test_generic_any_action';
       
   124     $hash = drupal_hash_base64($action_id);
       
   125     $edit = array('aid' => $hash);
       
   126     $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'), array(), array(), 'trigger-node-update-assign-form');
       
   127 
       
   128     $edit = array(
       
   129       'operation' => 'unpublish',
       
   130       'nodes[' . $nodes[0]->nid . ']' => TRUE,
       
   131       'nodes[' . $nodes[1]->nid . ']' => TRUE,
       
   132     );
       
   133     $this->drupalPost('admin/content', $edit, t('Update'));
       
   134     $count = variable_get('trigger_test_generic_any_action', 0);
       
   135     $this->assertTrue($count == 2, format_string('Action was triggered 2 times. Actual: %count', array('%count' => $count)));
       
   136   }
       
   137 
       
   138   /**
       
   139    * Returns some info about each of the content actions.
       
   140    *
       
   141    * This is helper function for testActionsContent().
       
   142    *
       
   143    * @param $action
       
   144    *   The name of the action to return info about.
       
   145    *
       
   146    * @return
       
   147    *   An associative array of info about the action.
       
   148    */
       
   149   function actionInfo($action) {
       
   150     $info = array(
       
   151       'node_publish_action' => array(
       
   152         'property' => 'status',
       
   153         'expected' => 1,
       
   154         'name' => t('publish content'),
       
   155       ),
       
   156       'node_unpublish_action' => array(
       
   157         'property' => 'status',
       
   158         'expected' => 0,
       
   159         'name' => t('unpublish content'),
       
   160       ),
       
   161       'node_make_sticky_action' => array(
       
   162         'property' => 'sticky',
       
   163         'expected' => 1,
       
   164         'name' => t('make content sticky'),
       
   165       ),
       
   166       'node_make_unsticky_action' => array(
       
   167         'property' => 'sticky',
       
   168         'expected' => 0,
       
   169         'name' => t('make content unsticky'),
       
   170       ),
       
   171       'node_promote_action' => array(
       
   172         'property' => 'promote',
       
   173         'expected' => 1,
       
   174         'name' => t('promote content to front page'),
       
   175       ),
       
   176       'node_unpromote_action' => array(
       
   177         'property' => 'promote',
       
   178         'expected' => 0,
       
   179         'name' => t('remove content from front page'),
       
   180       ),
       
   181     );
       
   182     return $info[$action];
       
   183   }
       
   184 }
       
   185 
       
   186 /**
       
   187  * Tests cron trigger.
       
   188  */
       
   189 class TriggerCronTestCase extends TriggerWebTestCase {
       
   190   public static function getInfo() {
       
   191     return array(
       
   192       'name' => 'Trigger cron (system) actions',
       
   193       'description' => 'Perform various tests with cron trigger.',
       
   194       'group' => 'Trigger',
       
   195     );
       
   196   }
       
   197 
       
   198   function setUp() {
       
   199     parent::setUp('trigger', 'trigger_test');
       
   200   }
       
   201 
       
   202   /**
       
   203    * Tests assigning multiple actions to the cron trigger.
       
   204    *
       
   205    * This test ensures that both simple and multiple complex actions
       
   206    * succeed properly. This is done in the cron trigger test because
       
   207    * cron allows passing multiple actions in at once.
       
   208    */
       
   209   function testActionsCron() {
       
   210     // Create an administrative user.
       
   211     $test_user = $this->drupalCreateUser(array('administer actions'));
       
   212     $this->drupalLogin($test_user);
       
   213 
       
   214     // Assign a non-configurable action to the cron run trigger.
       
   215     $edit = array('aid' => drupal_hash_base64('trigger_test_system_cron_action'));
       
   216     $this->drupalPost('admin/structure/trigger/system', $edit, t('Assign'), array(), array(), 'trigger-cron-assign-form');
       
   217 
       
   218     // Assign a configurable action to the cron trigger.
       
   219     $action_label = $this->randomName();
       
   220     $edit = array(
       
   221       'actions_label' => $action_label,
       
   222       'subject' => $action_label,
       
   223     );
       
   224     $aid = $this->configureAdvancedAction('trigger_test_system_cron_conf_action', $edit);
       
   225     // $aid is likely 3 but if we add more uses for the sequences table in
       
   226     // core it might break, so it is easier to get the value from the database.
       
   227     $edit = array('aid' => drupal_hash_base64($aid));
       
   228     $this->drupalPost('admin/structure/trigger/system', $edit, t('Assign'), array(), array(), 'trigger-cron-assign-form');
       
   229 
       
   230     // Add a second configurable action to the cron trigger.
       
   231     $action_label = $this->randomName();
       
   232     $edit = array(
       
   233       'actions_label' => $action_label,
       
   234       'subject' => $action_label,
       
   235     );
       
   236     $aid = $this->configureAdvancedAction('trigger_test_system_cron_conf_action', $edit);
       
   237     $edit = array('aid' => drupal_hash_base64($aid));
       
   238     $this->drupalPost('admin/structure/trigger/system', $edit, t('Assign'), array(), array(), 'trigger-cron-assign-form');
       
   239 
       
   240     // Force a cron run.
       
   241     $this->cronRun();
       
   242 
       
   243     // Make sure the non-configurable action has fired.
       
   244     $action_run = variable_get('trigger_test_system_cron_action', FALSE);
       
   245     $this->assertTrue($action_run, 'Check that the cron run triggered the test action.');
       
   246 
       
   247     // Make sure that both configurable actions have fired.
       
   248     $action_run = variable_get('trigger_test_system_cron_conf_action', 0) == 2;
       
   249     $this->assertTrue($action_run, 'Check that the cron run triggered both complex actions.');
       
   250   }
       
   251 }
       
   252 
       
   253 /**
       
   254  * Provides a base class with trigger assignments and test comparisons.
       
   255  */
       
   256 class TriggerActionTestCase extends TriggerWebTestCase {
       
   257 
       
   258   function setUp() {
       
   259     parent::setUp('trigger');
       
   260   }
       
   261 
       
   262   /**
       
   263    * Creates a message with tokens.
       
   264    *
       
   265    * @param $trigger
       
   266    *
       
   267    * @return
       
   268    *   A message with embedded tokens.
       
   269    */
       
   270   function generateMessageWithTokens($trigger) {
       
   271     // Note that subject is limited to 254 characters in action configuration.
       
   272     $message = t('Action was triggered by trigger @trigger user:name=[user:name] user:uid=[user:uid] user:mail=[user:mail] user:url=[user:url] user:edit-url=[user:edit-url] user:created=[user:created]',
       
   273       array('@trigger' => $trigger));
       
   274     return trim($message);
       
   275   }
       
   276 
       
   277   /**
       
   278    * Generates a comparison message to match the pre-token-replaced message.
       
   279    *
       
   280    * @param $trigger
       
   281    *   Trigger, like 'user_login'.
       
   282    * @param $account
       
   283    *   Associated user account.
       
   284    *
       
   285    * @return
       
   286    *   The token-replaced equivalent message. This does not use token
       
   287    *   functionality.
       
   288    *
       
   289    * @see generateMessageWithTokens()
       
   290    */
       
   291   function generateTokenExpandedComparison($trigger, $account) {
       
   292     // Note that user:last-login was omitted because it changes and can't
       
   293     // be properly verified.
       
   294     $message = t('Action was triggered by trigger @trigger user:name=@username user:uid=@uid user:mail=@mail user:url=@user_url user:edit-url=@user_edit_url user:created=@user_created',
       
   295        array(
       
   296         '@trigger' => $trigger,
       
   297         '@username' => $account->name,
       
   298         '@uid' => !empty($account->uid) ? $account->uid : t('not yet assigned'),
       
   299         '@mail' => $account->mail,
       
   300         '@user_url' => !empty($account->uid) ? url("user/$account->uid", array('absolute' => TRUE)) : t('not yet assigned'),
       
   301         '@user_edit_url' => !empty($account->uid) ? url("user/$account->uid/edit", array('absolute' => TRUE)) : t('not yet assigned'),
       
   302         '@user_created' => isset($account->created) ? format_date($account->created, 'medium') : t('not yet created'),
       
   303         )
       
   304       );
       
   305       return trim($message);
       
   306   }
       
   307 
       
   308 
       
   309   /**
       
   310    * Assigns a simple (non-configurable) action to a trigger.
       
   311    *
       
   312    * @param $trigger
       
   313    *   The trigger to assign to, like 'user_login'.
       
   314    * @param $action
       
   315    *   The simple action to be assigned, like 'comment_insert'.
       
   316    */
       
   317   function assignSimpleAction($trigger, $action) {
       
   318     $form_name = "trigger_{$trigger}_assign_form";
       
   319     $form_html_id = strtr($form_name, '_', '-');
       
   320     $edit = array('aid' => drupal_hash_base64($action));
       
   321     $trigger_type = preg_replace('/_.*/', '', $trigger);
       
   322     $this->drupalPost("admin/structure/trigger/$trigger_type", $edit, t('Assign'), array(), array(), $form_html_id);
       
   323     $actions = trigger_get_assigned_actions($trigger);
       
   324     $this->assertTrue(!empty($actions[$action]), format_string('Simple action @action assigned to trigger @trigger', array('@action' => $action, '@trigger' => $trigger)));
       
   325   }
       
   326 
       
   327   /**
       
   328    * Assigns a system message action to the passed-in trigger.
       
   329    *
       
   330    * @param $trigger
       
   331    *   For example, 'user_login'
       
   332    */
       
   333   function assignSystemMessageAction($trigger) {
       
   334     $form_name = "trigger_{$trigger}_assign_form";
       
   335     $form_html_id = strtr($form_name, '_', '-');
       
   336     // Assign a configurable action 'System message' to the passed trigger.
       
   337     $action_edit = array(
       
   338       'actions_label' => $trigger . "_system_message_action_" . $this->randomName(16),
       
   339       'message' => $this->generateMessageWithTokens($trigger),
       
   340     );
       
   341 
       
   342     // Configure an advanced action that we can assign.
       
   343     $aid = $this->configureAdvancedAction('system_message_action', $action_edit);
       
   344 
       
   345     $edit = array('aid' => drupal_hash_base64($aid));
       
   346     $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), $form_html_id);
       
   347     drupal_static_reset('trigger_get_asssigned_actions');
       
   348   }
       
   349 
       
   350 
       
   351   /**
       
   352    * Assigns a system_send_email_action to the passed-in trigger.
       
   353    *
       
   354    * @param $trigger
       
   355    *   For example, 'user_login'
       
   356    */
       
   357   function assignSystemEmailAction($trigger) {
       
   358     $form_name = "trigger_{$trigger}_assign_form";
       
   359     $form_html_id = strtr($form_name, '_', '-');
       
   360 
       
   361     $message = $this->generateMessageWithTokens($trigger);
       
   362     // Assign a configurable action 'System message' to the passed trigger.
       
   363     $action_edit = array(
       
   364       // 'actions_label' => $trigger . "_system_send_message_action_" . $this->randomName(16),
       
   365       'actions_label' => $trigger . "_system_send_email_action",
       
   366       'recipient' => '[user:mail]',
       
   367       'subject' => $message,
       
   368       'message' => $message,
       
   369     );
       
   370 
       
   371     // Configure an advanced action that we can assign.
       
   372     $aid = $this->configureAdvancedAction('system_send_email_action', $action_edit);
       
   373 
       
   374     $edit = array('aid' => drupal_hash_base64($aid));
       
   375     $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), $form_html_id);
       
   376     drupal_static_reset('trigger_get_assigned_actions');
       
   377   }
       
   378 
       
   379   /**
       
   380    * Asserts correct token replacement in both system message and email.
       
   381    *
       
   382    * @param $trigger
       
   383    *   A trigger like 'user_login'.
       
   384    * @param $account
       
   385    *   The user account which triggered the action.
       
   386    * @param $email_depth
       
   387    *   Number of emails to scan, starting with most recent.
       
   388    */
       
   389   function assertSystemMessageAndEmailTokenReplacement($trigger, $account, $email_depth = 1) {
       
   390     $this->assertSystemMessageTokenReplacement($trigger, $account);
       
   391     $this->assertSystemEmailTokenReplacement($trigger, $account, $email_depth);
       
   392   }
       
   393 
       
   394   /**
       
   395    * Asserts correct token replacement for the given trigger and account.
       
   396    *
       
   397    * @param $trigger
       
   398    *   A trigger like 'user_login'.
       
   399    * @param $account
       
   400    *   The user account which triggered the action.
       
   401    */
       
   402   function assertSystemMessageTokenReplacement($trigger, $account) {
       
   403     $expected = $this->generateTokenExpandedComparison($trigger, $account);
       
   404     $this->assertText($expected,
       
   405       format_string('Expected system message to contain token-replaced text "@expected" found in configured system message action', array('@expected' => $expected )) );
       
   406   }
       
   407 
       
   408 
       
   409   /**
       
   410    * Asserts correct token replacement for the given trigger and account.
       
   411    *
       
   412    * @param $trigger
       
   413    *   A trigger like 'user_login'.
       
   414    * @param $account
       
   415    *   The user account which triggered the action.
       
   416    * @param $email_depth
       
   417    *   Number of emails to scan, starting with most recent.
       
   418    */
       
   419   function assertSystemEmailTokenReplacement($trigger, $account, $email_depth = 1) {
       
   420     $this->verboseEmail($email_depth);
       
   421     $expected = $this->generateTokenExpandedComparison($trigger, $account);
       
   422     $this->assertMailString('subject', $expected, $email_depth);
       
   423     $this->assertMailString('body', $expected, $email_depth);
       
   424     $this->assertMail('to', $account->mail, 'Mail sent to correct destination');
       
   425   }
       
   426 }
       
   427 
       
   428 /**
       
   429  * Tests token substitution in trigger actions.
       
   430  *
       
   431  * This tests nearly every permutation of user triggers with system actions
       
   432  * and checks the token replacement.
       
   433  */
       
   434 class TriggerUserTokenTestCase extends TriggerActionTestCase {
       
   435   public static function getInfo() {
       
   436     return array(
       
   437       'name' => 'Test user triggers',
       
   438       'description' => 'Test user triggers and system actions with token replacement.',
       
   439       'group' => 'Trigger',
       
   440     );
       
   441   }
       
   442 
       
   443 
       
   444   /**
       
   445    * Tests a variety of token replacements in actions.
       
   446    */
       
   447   function testUserTriggerTokenReplacement() {
       
   448     $test_user = $this->drupalCreateUser(array('administer actions', 'administer users', 'change own username', 'access user profiles'));
       
   449     $this->drupalLogin($test_user);
       
   450 
       
   451     $triggers = array('user_login', 'user_insert', 'user_update', 'user_delete', 'user_logout', 'user_view');
       
   452     foreach ($triggers as $trigger) {
       
   453       $this->assignSystemMessageAction($trigger);
       
   454       $this->assignSystemEmailAction($trigger);
       
   455     }
       
   456 
       
   457     $this->drupalLogout();
       
   458     $this->assertSystemEmailTokenReplacement('user_logout', $test_user);
       
   459 
       
   460     $this->drupalLogin($test_user);
       
   461     $this->assertSystemMessageAndEmailTokenReplacement('user_login', $test_user, 2);
       
   462     $this->assertSystemMessageAndEmailTokenReplacement('user_view', $test_user, 2);
       
   463 
       
   464     $this->drupalPost("user/{$test_user->uid}/edit", array('name' => $test_user->name . '_changed'), t('Save'));
       
   465     $test_user->name .= '_changed'; // Since we just changed it.
       
   466     $this->assertSystemMessageAndEmailTokenReplacement('user_update', $test_user, 2);
       
   467 
       
   468     $this->drupalGet('user');
       
   469     $this->assertSystemMessageAndEmailTokenReplacement('user_view', $test_user);
       
   470 
       
   471     $new_user = $this->drupalCreateUser(array('administer actions', 'administer users', 'cancel account', 'access administration pages'));
       
   472     $this->assertSystemEmailTokenReplacement('user_insert', $new_user);
       
   473 
       
   474     $this->drupalLogin($new_user);
       
   475     $user_to_delete = $this->drupalCreateUser(array('access content'));
       
   476     variable_set('user_cancel_method', 'user_cancel_delete');
       
   477 
       
   478     $this->drupalPost("user/{$user_to_delete->uid}/cancel", array(), t('Cancel account'));
       
   479     $this->assertSystemMessageAndEmailTokenReplacement('user_delete', $user_to_delete);
       
   480   }
       
   481 
       
   482 
       
   483 }
       
   484 
       
   485 /**
       
   486  * Tests token substitution in trigger actions.
       
   487  *
       
   488  * This tests nearly every permutation of user triggers with system actions
       
   489  * and checks the token replacement.
       
   490  */
       
   491 class TriggerUserActionTestCase extends TriggerActionTestCase {
       
   492   public static function getInfo() {
       
   493     return array(
       
   494       'name' => 'Test user actions',
       
   495       'description' => 'Test user actions.',
       
   496       'group' => 'Trigger',
       
   497     );
       
   498   }
       
   499 
       
   500   /**
       
   501    * Tests user action assignment and execution.
       
   502    */
       
   503   function testUserActionAssignmentExecution() {
       
   504     $test_user = $this->drupalCreateUser(array('administer actions', 'create article content', 'access comments', 'administer comments', 'skip comment approval', 'edit own comments'));
       
   505     $this->drupalLogin($test_user);
       
   506 
       
   507     $triggers = array('comment_presave', 'comment_insert', 'comment_update');
       
   508     // system_block_ip_action is difficult to test without ruining the test.
       
   509     $actions = array('user_block_user_action');
       
   510     foreach ($triggers as $trigger) {
       
   511       foreach ($actions as $action) {
       
   512         $this->assignSimpleAction($trigger, $action);
       
   513       }
       
   514     }
       
   515 
       
   516     $node = $this->drupalCreateNode(array('type' => 'article'));
       
   517     $this->drupalPost("node/{$node->nid}", array('comment_body[und][0][value]' => t("my comment"), 'subject' => t("my comment subject")), t('Save'));
       
   518     // Posting a comment should have blocked this user.
       
   519     $account = user_load($test_user->uid, TRUE);
       
   520     $this->assertTrue($account->status == 0, 'Account is blocked');
       
   521     $comment_author_uid = $account->uid;
       
   522     // Now rehabilitate the comment author so it can be be blocked again when
       
   523     // the comment is updated.
       
   524     user_save($account, array('status' => TRUE));
       
   525 
       
   526     $test_user = $this->drupalCreateUser(array('administer actions', 'create article content', 'access comments', 'administer comments', 'skip comment approval', 'edit own comments'));
       
   527     $this->drupalLogin($test_user);
       
   528 
       
   529     // Our original comment will have been comment 1.
       
   530     $this->drupalPost("comment/1/edit", array('comment_body[und][0][value]' => t("my comment, updated"), 'subject' => t("my comment subject")), t('Save'));
       
   531     $comment_author_account = user_load($comment_author_uid, TRUE);
       
   532     $this->assertTrue($comment_author_account->status == 0, format_string('Comment author account (uid=@uid) is blocked after update to comment', array('@uid' => $comment_author_uid)));
       
   533 
       
   534     // Verify that the comment was updated.
       
   535     $test_user = $this->drupalCreateUser(array('administer actions', 'create article content', 'access comments', 'administer comments', 'skip comment approval', 'edit own comments'));
       
   536     $this->drupalLogin($test_user);
       
   537 
       
   538     $this->drupalGet("node/$node->nid");
       
   539     $this->assertText(t("my comment, updated"));
       
   540     $this->verboseEmail();
       
   541   }
       
   542 }
       
   543 
       
   544 /**
       
   545  * Tests other triggers.
       
   546  */
       
   547 class TriggerOtherTestCase extends TriggerWebTestCase {
       
   548   var $_cleanup_roles = array();
       
   549   var $_cleanup_users = array();
       
   550 
       
   551   public static function getInfo() {
       
   552     return array(
       
   553       'name' => 'Trigger other actions',
       
   554       'description' => 'Test triggering of user, comment, taxonomy actions.',
       
   555       'group' => 'Trigger',
       
   556     );
       
   557   }
       
   558 
       
   559   function setUp() {
       
   560     parent::setUp('trigger', 'trigger_test', 'contact');
       
   561   }
       
   562 
       
   563   /**
       
   564    * Tests triggering on user create and user login.
       
   565    */
       
   566   function testActionsUser() {
       
   567     // Assign an action to the create user trigger.
       
   568     $test_user = $this->drupalCreateUser(array('administer actions'));
       
   569     $this->drupalLogin($test_user);
       
   570     $action_id = 'trigger_test_generic_action';
       
   571     $hash = drupal_hash_base64($action_id);
       
   572     $edit = array('aid' => $hash);
       
   573     $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), 'trigger-user-insert-assign-form');
       
   574 
       
   575     // Set action variable to FALSE.
       
   576     variable_set($action_id, FALSE);
       
   577 
       
   578     // Create an unblocked user
       
   579     $web_user = $this->drupalCreateUser(array('administer users'));
       
   580     $this->drupalLogin($web_user);
       
   581     $name = $this->randomName();
       
   582     $pass = user_password();
       
   583     $edit = array();
       
   584     $edit['name'] = $name;
       
   585     $edit['mail'] = $name . '@example.com';
       
   586     $edit['pass[pass1]'] = $pass;
       
   587     $edit['pass[pass2]'] = $pass;
       
   588     $edit['status'] = 1;
       
   589     $this->drupalPost('admin/people/create', $edit, t('Create new account'));
       
   590 
       
   591     // Verify that the action variable has been set.
       
   592     $this->assertTrue(variable_get($action_id, FALSE), 'Check that creating a user triggered the test action.');
       
   593 
       
   594     // Reset the action variable.
       
   595     variable_set($action_id, FALSE);
       
   596 
       
   597     $this->drupalLogin($test_user);
       
   598     // Assign a configurable action 'System message' to the user_login trigger.
       
   599     $action_edit = array(
       
   600       'actions_label' => $this->randomName(16),
       
   601       'message' => t("You have logged in:") . $this->randomName(16),
       
   602     );
       
   603 
       
   604     // Configure an advanced action that we can assign.
       
   605     $aid = $this->configureAdvancedAction('system_message_action', $action_edit);
       
   606     $edit = array('aid' => drupal_hash_base64($aid));
       
   607     $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), 'trigger-user-login-assign-form');
       
   608 
       
   609     // Verify that the action has been assigned to the correct hook.
       
   610     $actions = trigger_get_assigned_actions('user_login');
       
   611     $this->assertEqual(1, count($actions), 'One Action assigned to the hook');
       
   612     $this->assertEqual($actions[$aid]['label'], $action_edit['actions_label'], 'Correct action label found.');
       
   613 
       
   614     // User should get the configured message at login.
       
   615     $contact_user = $this->drupalCreateUser(array('access site-wide contact form'));;
       
   616     $this->drupalLogin($contact_user);
       
   617     $this->assertText($action_edit['message']);
       
   618   }
       
   619 
       
   620   /**
       
   621    * Tests triggering on comment save.
       
   622    */
       
   623   function testActionsComment() {
       
   624     // Assign an action to the comment save trigger.
       
   625     $test_user = $this->drupalCreateUser(array('administer actions'));
       
   626     $this->drupalLogin($test_user);
       
   627     $action_id = 'trigger_test_generic_action';
       
   628     $hash = drupal_hash_base64($action_id);
       
   629     $edit = array('aid' => $hash);
       
   630     $this->drupalPost('admin/structure/trigger/comment', $edit, t('Assign'), array(), array(), 'trigger-comment-insert-assign-form');
       
   631 
       
   632     // Set action variable to FALSE.
       
   633     variable_set($action_id, FALSE);
       
   634 
       
   635     // Create a node and add a comment to it.
       
   636     $web_user = $this->drupalCreateUser(array('create article content', 'access content', 'skip comment approval', 'post comments'));
       
   637     $this->drupalLogin($web_user);
       
   638     $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
       
   639     $edit = array();
       
   640     $edit['subject'] = $this->randomName(10);
       
   641     $edit['comment_body[' . LANGUAGE_NONE . '][0][value]'] = $this->randomName(10) . ' ' . $this->randomName(10);
       
   642     $this->drupalGet('comment/reply/' . $node->nid);
       
   643     $this->drupalPost(NULL, $edit, t('Save'));
       
   644 
       
   645     // Verify that the action variable has been set.
       
   646     $this->assertTrue(variable_get($action_id, FALSE), 'Check that creating a comment triggered the action.');
       
   647   }
       
   648 
       
   649   /**
       
   650    * Tests triggering on taxonomy new term.
       
   651    */
       
   652   function testActionsTaxonomy() {
       
   653     // Assign an action to the taxonomy term save trigger.
       
   654     $test_user = $this->drupalCreateUser(array('administer actions'));
       
   655     $this->drupalLogin($test_user);
       
   656     $action_id = 'trigger_test_generic_action';
       
   657     $hash = drupal_hash_base64($action_id);
       
   658     $edit = array('aid' => $hash);
       
   659     $this->drupalPost('admin/structure/trigger/taxonomy', $edit, t('Assign'), array(), array(), 'trigger-taxonomy-term-insert-assign-form');
       
   660 
       
   661     // Set action variable to FALSE.
       
   662     variable_set($action_id, FALSE);
       
   663 
       
   664     // Create a taxonomy vocabulary and add a term to it.
       
   665 
       
   666     // Create a vocabulary.
       
   667     $vocabulary = new stdClass();
       
   668     $vocabulary->name = $this->randomName();
       
   669     $vocabulary->description = $this->randomName();
       
   670     $vocabulary->machine_name = drupal_strtolower($this->randomName());
       
   671     $vocabulary->help = '';
       
   672     $vocabulary->nodes = array('article' => 'article');
       
   673     $vocabulary->weight = mt_rand(0, 10);
       
   674     taxonomy_vocabulary_save($vocabulary);
       
   675 
       
   676     $term = new stdClass();
       
   677     $term->name = $this->randomName();
       
   678     $term->vid = $vocabulary->vid;
       
   679     taxonomy_term_save($term);
       
   680 
       
   681     // Verify that the action variable has been set.
       
   682     $this->assertTrue(variable_get($action_id, FALSE), 'Check that creating a taxonomy term triggered the action.');
       
   683   }
       
   684 
       
   685 }
       
   686 
       
   687 /**
       
   688  * Tests that orphaned actions are properly handled.
       
   689  */
       
   690 class TriggerOrphanedActionsTestCase extends DrupalWebTestCase {
       
   691 
       
   692   public static function getInfo() {
       
   693     return array(
       
   694       'name' => 'Trigger orphaned actions',
       
   695       'description' => 'Test triggering an action that has since been removed.',
       
   696       'group' => 'Trigger',
       
   697     );
       
   698   }
       
   699 
       
   700   function setUp() {
       
   701     parent::setUp('trigger', 'trigger_test');
       
   702   }
       
   703 
       
   704   /**
       
   705    * Tests logic around orphaned actions.
       
   706    */
       
   707   function testActionsOrphaned() {
       
   708     $action = 'trigger_test_generic_any_action';
       
   709     $hash = drupal_hash_base64($action);
       
   710 
       
   711     // Assign an action from a disable-able module to a trigger, then pull the
       
   712     // trigger, and make sure the actions fire.
       
   713     $test_user = $this->drupalCreateUser(array('administer actions'));
       
   714     $this->drupalLogin($test_user);
       
   715     $edit = array('aid' => $hash);
       
   716     $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'), array(), array(), 'trigger-node-presave-assign-form');
       
   717 
       
   718     // Create an unpublished node.
       
   719     $web_user = $this->drupalCreateUser(array('create page content', 'edit own page content', 'access content', 'administer nodes'));
       
   720     $this->drupalLogin($web_user);
       
   721     $edit = array();
       
   722     $langcode = LANGUAGE_NONE;
       
   723     $edit["title"] = '!SimpleTest test node! ' . $this->randomName(10);
       
   724     $edit["body[$langcode][0][value]"] = '!SimpleTest test body! ' . $this->randomName(32) . ' ' . $this->randomName(32);
       
   725     $this->drupalPost('node/add/page', $edit, t('Save'));
       
   726     $this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"])), 'Make sure the Basic page has actually been created');
       
   727 
       
   728     // Action should have been fired.
       
   729     $this->assertTrue(variable_get('trigger_test_generic_any_action', FALSE), 'Trigger test action successfully fired.');
       
   730 
       
   731     // Disable the module that provides the action and make sure the trigger
       
   732     // doesn't white screen.
       
   733     module_disable(array('trigger_test'));
       
   734     $loaded_node = $this->drupalGetNodeByTitle($edit["title"]);
       
   735     $edit["body[$langcode][0][value]"] = '!SimpleTest test body! ' . $this->randomName(32) . ' ' . $this->randomName(32);
       
   736     $this->drupalPost("node/$loaded_node->nid/edit", $edit, t('Save'));
       
   737 
       
   738     // If the node body was updated successfully we have dealt with the
       
   739     // unavailable action.
       
   740     $this->assertRaw(t('!post %title has been updated.', array('!post' => 'Basic page', '%title' => $edit["title"])), 'Make sure the Basic page can be updated with the missing trigger function.');
       
   741   }
       
   742 }
       
   743 
       
   744 /**
       
   745  * Tests the unassigning of triggers.
       
   746  */
       
   747 class TriggerUnassignTestCase extends DrupalWebTestCase {
       
   748 
       
   749   public static function getInfo() {
       
   750     return array(
       
   751       'name' => 'Trigger unassigning',
       
   752       'description' => 'Tests the unassigning of triggers.',
       
   753       'group' => 'Trigger',
       
   754     );
       
   755   }
       
   756 
       
   757   function setUp() {
       
   758     parent::setUp('trigger', 'trigger_test');
       
   759     $web_user = $this->drupalCreateUser(array('administer actions'));
       
   760     $this->drupalLogin($web_user);
       
   761   }
       
   762 
       
   763   /**
       
   764    * Tests an attempt to unassign triggers when none are assigned.
       
   765    */
       
   766   function testUnassignAccessDenied() {
       
   767     $this->drupalGet('admin/structure/trigger/unassign');
       
   768     $this->assertResponse(403, 'If there are no actions available, return access denied.');
       
   769   }
       
   770 
       
   771 }