/**
  * Check that config is updated as expected.
  *
  * 1. Webhook created where non exists.
  * 2. Webhook untouched if ok
  * 3. Webhook deleted, new one created if different.
  * 4. Webhooks untouched if multiple
  * 5. As 1 but in dry-run
  * 6. As 2 but in dry-run
  * 7. As 3 but in dry-run
  *
  *
  * @depends testGetMCInterestGroupings
  */
 public function testConfigureList()
 {
     //
     // Test 1
     //
     // The default mock list does not have any webhooks set, test one gets
     // created.
     //
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled();
     $api_prophecy->post('/lists/dummylistid/webhooks', Argument::any())->shouldBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id);
     $this->assertEquals(1, count($warnings));
     $this->assertContains(ts('Created a webhook at Mailchimp'), $warnings[0]);
     //
     // Test 2
     //
     // If it's all correct, nothing to do.
     //
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled()->willReturn(json_decode(json_encode(['http_code' => 200, 'data' => ['webhooks' => [['id' => 'dummywebhookid', 'url' => CRM_Mailchimp_Utils::getWebhookUrl(), 'events' => ['subscribe' => TRUE, 'unsubscribe' => TRUE, 'profile' => TRUE, 'cleaned' => TRUE, 'upemail' => TRUE, 'campaign' => FALSE], 'sources' => ['user' => TRUE, 'admin' => TRUE, 'api' => FALSE]]]]])));
     $api_prophecy->post()->shouldNotBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id);
     $this->assertEquals(0, count($warnings));
     //
     // Test 3
     //
     // If something's different, note and change.
     //
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled()->willReturn(json_decode(json_encode(['http_code' => 200, 'data' => ['webhooks' => [['id' => 'dummywebhookid', 'url' => 'http://example.com', 'events' => ['subscribe' => FALSE, 'unsubscribe' => TRUE, 'profile' => TRUE, 'cleaned' => TRUE, 'upemail' => TRUE, 'campaign' => FALSE], 'sources' => ['user' => TRUE, 'admin' => TRUE, 'api' => TRUE]]]]])));
     $api_prophecy->delete('/lists/dummylistid/webhooks/dummywebhookid')->shouldBeCalled();
     $api_prophecy->post('/lists/dummylistid/webhooks', Argument::any())->shouldBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id);
     $this->assertEquals(3, count($warnings));
     $this->assertContains('Changed webhook URL from http://example.com to', $warnings[0]);
     $this->assertContains('Changed webhook source api', $warnings[1]);
     $this->assertContains('Changed webhook event subscribe', $warnings[2]);
     //
     // Test 4
     //
     // If multiple webhooks configured, leave it alone.
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled()->willReturn(json_decode(json_encode(['http_code' => 200, 'data' => ['webhooks' => [1, 2]]])));
     $api_prophecy->delete()->shouldNotBeCalled();
     $api_prophecy->post()->shouldNotBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id);
     $this->assertEquals(1, count($warnings));
     $this->assertContains('Mailchimp list dummylistid has more than one webhook configured.', $warnings[0]);
     //
     // Test 5
     //
     // The default mock list does not have any webhooks set, test one gets
     // created.
     //
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled();
     $api_prophecy->delete()->shouldNotBeCalled();
     $api_prophecy->post()->shouldNotBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id, TRUE);
     $this->assertEquals(1, count($warnings));
     $this->assertContains(ts('Need to create a webhook at Mailchimp'), $warnings[0]);
     //
     // Test 6
     //
     // If it's all correct, nothing to do.
     //
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled()->willReturn(json_decode(json_encode(['http_code' => 200, 'data' => ['webhooks' => [['id' => 'dummywebhookid', 'url' => CRM_Mailchimp_Utils::getWebhookUrl(), 'events' => ['subscribe' => TRUE, 'unsubscribe' => TRUE, 'profile' => TRUE, 'cleaned' => TRUE, 'upemail' => TRUE, 'campaign' => FALSE], 'sources' => ['user' => TRUE, 'admin' => TRUE, 'api' => FALSE]]]]])));
     $api_prophecy->delete()->shouldNotBeCalled();
     $api_prophecy->post()->shouldNotBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id, TRUE);
     $this->assertEquals(0, count($warnings));
     //
     // Test 7
     //
     // If something's different, note and change.
     //
     $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3');
     CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal());
     $api_prophecy->get('/lists/dummylistid/webhooks')->shouldBeCalled()->willReturn(json_decode(json_encode(['http_code' => 200, 'data' => ['webhooks' => [['id' => 'dummywebhookid', 'url' => 'http://example.com', 'events' => ['subscribe' => FALSE, 'unsubscribe' => TRUE, 'profile' => TRUE, 'cleaned' => TRUE, 'upemail' => TRUE, 'campaign' => FALSE], 'sources' => ['user' => TRUE, 'admin' => TRUE, 'api' => TRUE]]]]])));
     $api_prophecy->delete()->shouldNotBeCalled();
     $api_prophecy->post()->shouldNotBeCalled();
     $warnings = CRM_Mailchimp_Utils::configureList(static::$test_list_id, TRUE);
     $this->assertEquals(3, count($warnings));
     $this->assertContains('Need to change webhook URL from http://example.com to', $warnings[0]);
     $this->assertContains('Need to change webhook source api', $warnings[1]);
     $this->assertContains('Need to change webhook event subscribe', $warnings[2]);
     // We did not change anything on the fixture.
     static::$fixture_should_be_reset = FALSE;
 }
/**
 * When the group settings form is saved, configure the mailchimp list if
 * appropriate.
 *
 * Implements hook_civicrm_postProcess($formName, &$form)
 *
 * @link https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postProcess
 */
function mailchimp_civicrm_postProcess($formName, &$form)
{
    if ($formName == 'CRM_Group_Form_Edit') {
        $vals = $form->_submitValues;
        if (!empty($vals['mc_fixup']) && !empty($vals['mailchimp_list']) && !empty($vals['mc_integration_option']) && $vals['mc_integration_option'] == 1) {
            // This group is supposed to have Mailchimp integration and the user wants
            // us to check the Mailchimp list is properly configured.
            $messages = CRM_Mailchimp_Utils::configureList($vals['mailchimp_list']);
            foreach ($messages as $message) {
                CRM_Core_Session::setStatus($message);
            }
        }
    }
}
 /**
  * Check all mapped groups' lists.
  *
  * Nb. this does not output anything itself so we can test it works. It is
  * used by the settings page.
  *
  * @param null|Array $groups array of membership groups to check, or NULL to
  *                   check all.
  *
  * @return Array of message strings that should be output with CRM_Core_Error
  * or such.
  *
  */
 public static function checkGroupsConfig($groups = NULL)
 {
     if ($groups === NULL) {
         $groups = CRM_Mailchimp_Utils::getGroupsToSync(array(), null, $membership_only = TRUE);
     }
     if (!is_array($groups)) {
         throw new InvalidArgumentException("expected array argument, if provided");
     }
     $api = CRM_Mailchimp_Utils::getMailchimpApi();
     $warnings = [];
     // Check all our groups do not have the sources:API set in the webhook, and
     // that they do have the webhook set.
     foreach ($groups as $group_id => $details) {
         $group_settings_link = "<a href='/civicrm/group?reset=1&action=update&id={$group_id}' >" . htmlspecialchars($details['civigroup_title']) . "</a>";
         $message_prefix = ts('CiviCRM group "%1" (Mailchimp list %2): ', [1 => $group_settings_link, 2 => $details['list_id']]);
         try {
             $test_warnings = CRM_Mailchimp_Utils::configureList($details['list_id'], $dry_run = TRUE);
             foreach ($test_warnings as $_) {
                 $warnings[] = $message_prefix . $_;
             }
         } catch (CRM_Mailchimp_NetworkErrorException $e) {
             $warnings[] = $message_prefix . ts("Problems (possibly temporary) fetching details from Mailchimp. ") . $e->getMessage();
         } catch (CRM_Mailchimp_RequestErrorException $e) {
             $message = $e->getMessage();
             if ($e->response->http_code == 404) {
                 // A little more helpful than "resource not found".
                 $warnings[] = $message_prefix . ts("The Mailchimp list that this once worked with has " . "been deleted on Mailchimp. Please edit the CiviCRM group settings to " . "either specify a different Mailchimp list that exists, or to remove " . "the Mailchimp integration for this group.");
             } else {
                 $warnings[] = $message_prefix . ts("Problems fetching details from Mailchimp. ") . $e->getMessage();
             }
         }
     }
     if ($warnings) {
         CRM_Core_Error::debug_log_message('Mailchimp list check warnings' . var_export($warnings, 1));
     }
     return $warnings;
 }