cdc5c450 |
1 | <?php |
2 | |
3 | /** |
4 | * Class CRM_Utils_EmailProcessorTest |
5 | * @group headless |
6 | */ |
7 | |
8 | class CRM_Utils_EmailProcessorTest extends CiviUnitTestCase { |
9 | |
10 | /** |
11 | * Event queue record. |
12 | * |
13 | * @var array |
14 | */ |
15 | protected $eventQueue = array(); |
16 | |
17 | /** |
18 | * ID of our sample contact. |
19 | * |
20 | * @var int |
21 | */ |
22 | protected $contactID; |
23 | |
24 | public function setUp() { |
25 | parent::setUp(); |
e7693ddd |
26 | CRM_Utils_File::cleanDir(__DIR__ . '/data/mail'); |
27 | mkdir(__DIR__ . '/data/mail'); |
cdc5c450 |
28 | $this->callAPISuccess('MailSettings', 'get', array( |
29 | 'api.MailSettings.create' => array( |
30 | 'name' => 'local', |
31 | 'protocol' => 'Localdir', |
32 | 'source' => __DIR__ . '/data/mail', |
33 | 'domain' => 'example.com', |
34 | ), |
35 | )); |
36 | } |
37 | |
e7693ddd |
38 | public function tearDown() { |
39 | CRM_Utils_File::cleanDir(__DIR__ . '/data/mail'); |
40 | parent::tearDown(); |
41 | $this->quickCleanup(array('civicrm_group', 'civicrm_group_contact', 'civicrm_mailing', 'civicrm_mailing_job', 'civicrm_mailing_event_bounce', 'civicrm_mailing_event_queue', 'civicrm_mailing_group', 'civicrm_mailing_recipients', 'civicrm_contact', 'civicrm_email')); |
42 | } |
43 | |
cdc5c450 |
44 | /** |
45 | * Test the job processing function works and processes a bounce. |
46 | */ |
47 | public function testBounceProcessing() { |
48 | $this->setUpMailing(); |
49 | |
50 | copy(__DIR__ . '/data/bounces/bounce_no_verp.txt', __DIR__ . '/data/mail/bounce_no_verp.txt'); |
51 | $this->assertTrue(file_exists(__DIR__ . '/data/mail/bounce_no_verp.txt')); |
52 | $this->callAPISuccess('job', 'fetch_bounces', array()); |
53 | $this->assertFalse(file_exists(__DIR__ . '/data/mail/bounce_no_verp.txt')); |
54 | $this->checkMailingBounces(1); |
55 | } |
56 | |
e7693ddd |
57 | /** |
58 | * Tests that a multipart related email does not cause pain & misery & fatal errors. |
59 | * |
60 | * Sample taken from https://www.phpclasses.org/browse/file/14672.html |
61 | */ |
62 | public function testProcessingMultipartRelatedEmail() { |
63 | $this->setUpMailing(); |
64 | $mail = 'test_sample_message.eml'; |
65 | |
66 | copy(__DIR__ . '/data/bounces/' . $mail, __DIR__ . '/data/mail/' . $mail); |
67 | $this->callAPISuccess('job', 'fetch_bounces', array()); |
68 | $this->assertFalse(file_exists(__DIR__ . '/data/mail/' . $mail)); |
69 | $this->checkMailingBounces(1); |
70 | } |
71 | |
cdc5c450 |
72 | /** |
73 | * Test that a deleted email does not cause a hard fail. |
74 | * |
75 | * The civicrm_mailing_event_queue table tracks email ids to represent an |
76 | * email address. The id may not represent the same email by the time the bounce may |
77 | * come in - a weakness of storing the id not the email. Relevant here |
78 | * is that it might have been deleted altogether, in which case the bounce should be |
79 | * silently ignored. This ignoring is also at the expense of the contact |
80 | * having the same email address with a different id. |
81 | * |
82 | * Longer term it would make sense to track the email address & track bounces back to that |
83 | * rather than an id that may not reflect the email used. Issue logged CRM-20021. |
84 | * |
85 | * For not however, we are testing absence of mysql error in conjunction with CRM-20016. |
86 | */ |
87 | public function testBounceProcessingDeletedEmail() { |
88 | $this->setUpMailing(); |
89 | $this->callAPISuccess('Email', 'get', array( |
90 | 'contact_id' => $this->contactID, |
91 | 'api.email.delete' => 1, |
92 | )); |
93 | |
94 | copy(__DIR__ . '/data/bounces/bounce_no_verp.txt', __DIR__ . '/data/mail/bounce_no_verp.txt'); |
95 | $this->assertTrue(file_exists(__DIR__ . '/data/mail/bounce_no_verp.txt')); |
96 | $this->callAPISuccess('job', 'fetch_bounces', array()); |
97 | $this->assertFalse(file_exists(__DIR__ . '/data/mail/bounce_no_verp.txt')); |
98 | $this->checkMailingBounces(1); |
99 | } |
100 | |
101 | /** |
e7693ddd |
102 | * |
cdc5c450 |
103 | * Wrapper to check for mailing bounces. |
104 | * |
105 | * Normally we would call $this->callAPISuccessGetCount but there is not one & there is resistance to |
106 | * adding apis for 'convenience' so just adding a hacky function to get past the impasse. |
107 | * |
108 | * @param int $expectedCount |
109 | */ |
110 | public function checkMailingBounces($expectedCount) { |
111 | $this->assertEquals($expectedCount, CRM_Core_DAO::singleValueQuery( |
e7693ddd |
112 | "SELECT count(*) FROM civicrm_mailing_event_bounce" |
cdc5c450 |
113 | )); |
114 | } |
115 | |
116 | /** |
117 | * Set up a mailing. |
118 | */ |
119 | public function setUpMailing() { |
120 | $this->contactID = $this->individualCreate(array('email' => 'undeliverable@example.com')); |
d15a97f4 |
121 | $groupID = $this->callAPISuccess('Group', 'create', array( |
cdc5c450 |
122 | 'title' => 'Mailing group', |
123 | 'api.GroupContact.create' => array( |
124 | 'contact_id' => $this->contactID, |
d15a97f4 |
125 | ), |
126 | )); |
cdc5c450 |
127 | $this->createMailing(array('scheduled_date' => 'now', 'groups' => array('include' => array($groupID)))); |
128 | $this->callAPISuccess('job', 'process_mailing', array()); |
129 | $this->eventQueue = $this->callAPISuccess('MailingEventQueue', 'get', array('api.MailingEventQueue.create' => array('hash' => 'aaaaaaaaaaaaaaaa'))); |
130 | } |
131 | |
132 | } |