CRM-21739 Test for getRecipients in/exclude mailing groups
authorJKingsnorth <john@johnkingsnorth.co.uk>
Mon, 26 Feb 2018 15:39:39 +0000 (15:39 +0000)
committerJKingsnorth <john@johnkingsnorth.co.uk>
Tue, 27 Feb 2018 12:03:14 +0000 (12:03 +0000)
tests/phpunit/CRM/Mailing/BAO/MailingTest.php

index 0fc0bfeb81acd94089cc7254b49b9a8c412da89b..63c12748b4037b77832ba7415909a0ceb8d52838 100644 (file)
@@ -35,20 +35,176 @@ class CRM_Mailing_BAO_MailingTest extends CiviUnitTestCase {
   }
 
   /**
-   * Things to test:
-   * - include static group(s)
-   * - include smart group(s)
-   * - exclude static group(s)
-   * - exclude smart group(s)
-   * - include previous recipients(ss)
-   * - exclude previous recipients(ss)
-   * Repeat for SMS.
+   * @todo Missing tests:
+   * - Ensure opt out emails are not mailed
+   * - Ensure 'stop' emails are not mailed
+   * - Ensure the deceased are not mailed
+   * - Tests for getLocationFilterAndOrderBy (selecting correct 'type')
+   * - ...
    */
 
+  /**
+   * Test to ensure that static and smart mailing groups can be added to an
+   * email mailing as 'include' or 'exclude' groups - and the members are
+   * included or excluded appropriately.
+   *
+   * contact 0 : static 0 (inc) + smart 5 (exc)
+   * contact 1 : static 0 (inc)
+   * contact 2 : static 1 (inc)
+   * contact 3 : static 1 (inc)
+   * contact 4 : static 2 (exc) + smart 3 (inc)
+   * contact 5 : smart 3 (inc)
+   * contact 6 : smart 4 (inc)
+   * contact 7 : smart 4 (inc)
+   */
+  public function testgetRecipientsEmailGroupIncludeExclude() {
+
+    // Set up groups; 3 standard, 3 smart
+    $groupIDs = array();
+    for ($i = 0; $i < 6; $i++) {
+      $params = array(
+        'name' => 'Test static group ' . $i,
+        'title' => 'Test static group ' . $i,
+        'is_active' => 1,
+      );
+      if ($i < 3) {
+        $groupIDs[$i] = $this->groupCreate($params);
+      }
+      else {
+        $groupIDs[$i] = $this->smartGroupCreate(array(
+          'formValues' => array('last_name' => 'smart' . $i),
+        ), $params);
+      }
+    }
+
+    // Create contacts
+    $contactIDs = array(
+      0 => $this->individualCreate(array('last_name' => 'smart5'), 0),
+      1 => $this->individualCreate(array(), 1),
+      2 => $this->individualCreate(array(), 2),
+      3 => $this->individualCreate(array(), 3),
+      4 => $this->individualCreate(array('last_name' => 'smart3'), 4),
+      5 => $this->individualCreate(array('last_name' => 'smart3'), 5),
+      6 => $this->individualCreate(array('last_name' => 'smart4'), 6),
+      7 => $this->individualCreate(array('last_name' => 'smart4'), 7),
+    );
+
+    // Add contacts to static groups
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupIDs[0],
+      'contact_id' => $contactIDs[0],
+    ));
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupIDs[0],
+      'contact_id' => $contactIDs[1],
+    ));
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupIDs[1],
+      'contact_id' => $contactIDs[2],
+    ));
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupIDs[1],
+      'contact_id' => $contactIDs[3],
+    ));
+    $this->callAPISuccess('GroupContact', 'Create', array(
+      'group_id' => $groupIDs[2],
+      'contact_id' => $contactIDs[4],
+    ));
+
+    // Force rebuild the smart groups
+    for ($i = 3; $i < 6; $i++) {
+      $group = new CRM_Contact_DAO_Group();
+      $group->id = $groupIDs[$i];
+      $group->find(TRUE);
+      CRM_Contact_BAO_GroupContactCache::load($group, TRUE);
+    }
+
+    // Check that we can include static groups in the mailing.
+    // Expected: Contacts [0-3] should be included.
+    $mailing = $this->callAPISuccess('Mailing', 'create', array());
+    $this->createMailingGroup($mailing['id'], $groupIDs[0]);
+    $this->createMailingGroup($mailing['id'], $groupIDs[1]);
+    $expected = $contactIDs;
+    unset($expected[4], $expected[5], $expected[6], $expected[7]);
+    $this->assertRecipientsCorrect($mailing['id'], $expected);
+
+    // Check that we can include smart groups in the mailing too.
+    // Expected: All contacts should be included.
+    $this->createMailingGroup($mailing['id'], $groupIDs[3]);
+    $this->createMailingGroup($mailing['id'], $groupIDs[4]);
+    $this->assertRecipientsCorrect($mailing['id'], $contactIDs);
+
+    // Check we can exclude static groups from the mailing.
+    // Expected: All contacts except [4]
+    $this->createMailingGroup($mailing['id'], $groupIDs[2], 'Exclude');
+    $expected = $contactIDs;
+    unset($expected[4]);
+    $this->assertRecipientsCorrect($mailing['id'], $expected);
+
+    // Check we can exclude smart groups from the mailing too.
+    // Expected: All contacts except [0] and [4]
+    $this->createMailingGroup($mailing['id'], $groupIDs[5], 'Exclude');
+    $expected = $contactIDs;
+    unset($expected[0], $expected[4]);
+    $this->assertRecipientsCorrect($mailing['id'], $expected);
+
+    // Tear down: delete mailing, groups, contacts
+    $this->deleteMailing($mailing['id']);
+    foreach ($groupIDs as $groupID) {
+      $this->groupDelete($groupID);
+    }
+    foreach ($contactIDs as $contactID) {
+      $this->contactDelete($contactID);
+    }
+
+  }
+
+  /**
+   * Helper function to assert whether the calculated recipients of a mailing
+   * match the expected list
+   *
+   * @param $mailingID
+   * @param $expectedRecipients array
+   *   Array of contact ID that should be in the recipient list.
+   */
+  private function assertRecipientsCorrect($mailingID, $expectedRecipients) {
+
+    // Reset keys to ensure match
+    $expectedRecipients = array_values($expectedRecipients);
+
+    // Load the recipients as a list of contact IDs
+    CRM_Mailing_BAO_Mailing::getRecipients($mailingID);
+    $recipients = $this->callAPISuccess('MailingRecipients', 'get', array('mailing_id' => $mailingID));
+    $contactIDs = array();
+    foreach ($recipients['values'] as $recipient) {
+      $contactIDs[] = $recipient['contact_id'];
+    }
+
+    // Check the lists match
+    $this->assertTreeEquals($expectedRecipients, $contactIDs);
+  }
+
+  /**
+   * Helper function to create a mailing include/exclude group.
+   *
+   * @param $mailingID
+   * @param $groupID
+   * @param string $type
+   * @return array|int
+   */
+  private function createMailingGroup($mailingID, $groupID, $type = 'Include') {
+    return $this->callAPISuccess('MailingGroup', 'create', array(
+      'mailing_id' => $mailingID,
+      'group_type' => $type,
+      'entity_table' => "civicrm_group",
+      'entity_id' => $groupID,
+    ));
+  }
+
   /**
    * Test CRM_Mailing_BAO_Mailing::getRecipients() on sms mode
    */
-  public function testgetRecipients() {
+  public function testgetRecipientsSMS() {
     // Tests for SMS bulk mailing recipients
     // +CRM-21320 Ensure primary mobile number is selected over non-primary