Merge pull request #4230 from dokuwiki-translate/lang_update_830_1709550808
[dokuwiki.git] / _test / tests / inc / mailer.test.php
blob2311d42ae399832a52bfaedf0d666702e9a731cf
1 <?php
3 use dokuwiki\HTTP\HTTPClient;
5 /**
6 * Extends the mailer class to expose internal variables for testing
7 */
8 class TestMailer extends Mailer {
9 public function prop($name){
10 return $this->$name;
13 public function &propRef($name) {
14 return $this->$name;
17 public function prepareHeaders() {
18 return parent::prepareHeaders();
21 public function cleanHeaders() {
22 parent::cleanHeaders();
27 /**
28 * @group mailer_class
30 class mailer_test extends DokuWikiTest {
33 function test_userheader(){
34 $mail = new TestMailer();
35 $headers = $mail->prop('headers');
36 $this->assertArrayNotHasKey('X-Dokuwiki-User',$headers);
38 $_SERVER['REMOTE_USER'] = 'andi';
39 $mail = new TestMailer();
40 $headers = $mail->prop('headers');
41 $this->assertArrayHasKey('X-Dokuwiki-User',$headers);
44 function test_setHeader(){
45 $mail = new TestMailer();
47 // check existance of default headers
48 $headers = $mail->prop('headers');
49 $this->assertArrayHasKey('X-Mailer',$headers);
50 $this->assertArrayHasKey('X-Dokuwiki-Title',$headers);
51 $this->assertArrayHasKey('X-Dokuwiki-Server',$headers);
52 $this->assertArrayHasKey('X-Auto-Response-Suppress',$headers);
53 $this->assertArrayHasKey('List-Id',$headers);
55 // set a bunch of test headers
56 $mail->setHeader('test-header','bla');
57 $mail->setHeader('to','A valid ASCII name <test@example.com>');
58 $mail->setHeader('from',"Thös ne\needs\x00serious cleaning\$§%.");
59 $mail->setHeader('bad',"Thös ne\needs\x00serious cleaning\$§%.",false);
60 $mail->setHeader("weird\n*+\x00foo.-_@bar?",'now clean');
62 // are they set?
63 $headers = $mail->prop('headers');
64 $this->assertArrayHasKey('Test-Header',$headers);
65 $this->assertEquals('bla',$headers['Test-Header']);
66 $this->assertArrayHasKey('To',$headers);
67 $this->assertEquals('A valid ASCII name <test@example.com>',$headers['To']);
68 $this->assertArrayHasKey('From',$headers);
69 $this->assertEquals('Ths neeedsserious cleaning.',$headers['From']);
70 $this->assertArrayHasKey('Bad',$headers);
71 $this->assertEquals("Thös ne\needs\x00serious cleaning\$§%.",$headers['Bad']);
72 $this->assertArrayHasKey('Weird+foo.-_@bar',$headers);
74 // unset a header again
75 $mail->setHeader('test-header','');
76 $headers = $mail->prop('headers');
77 $this->assertArrayNotHasKey('Test-Header',$headers);
80 function test_addresses(){
81 if (isWindows()) {
82 $this->markTestSkipped();
85 $mail = new TestMailer();
87 $mail->to('andi@splitbrain.org');
88 $mail->cleanHeaders();
89 $headers = $mail->prop('headers');
90 $this->assertEquals('andi@splitbrain.org', $headers['To']);
92 $mail->to('<andi@splitbrain.org>');
93 $mail->cleanHeaders();
94 $headers = $mail->prop('headers');
95 $this->assertEquals('andi@splitbrain.org', $headers['To']);
97 $mail->to('Andreas Gohr <andi@splitbrain.org>');
98 $mail->cleanHeaders();
99 $headers = $mail->prop('headers');
100 $this->assertEquals('Andreas Gohr <andi@splitbrain.org>', $headers['To']);
102 $mail->to('"Andreas Gohr" <andi@splitbrain.org>');
103 $mail->cleanHeaders();
104 $headers = $mail->prop('headers');
105 $this->assertEquals('"Andreas Gohr" <andi@splitbrain.org>', $headers['To']);
107 $mail->to('andi@splitbrain.org,foo@example.com');
108 $mail->cleanHeaders();
109 $headers = $mail->prop('headers');
110 $this->assertEquals('andi@splitbrain.org, foo@example.com', $headers['To']);
112 $mail->to('andi@splitbrain.org, Text <foo@example.com>');
113 $mail->cleanHeaders();
114 $headers = $mail->prop('headers');
115 $this->assertEquals('andi@splitbrain.org, Text <foo@example.com>', $headers['To']);
117 $mail->to('Andreas Gohr <andi@splitbrain.org>,foo@example.com');
118 $mail->cleanHeaders();
119 $headers = $mail->prop('headers');
120 $this->assertEquals('Andreas Gohr <andi@splitbrain.org>, foo@example.com', $headers['To']);
122 $mail->to('Andreas Gohr <andi@splitbrain.org> , foo <foo@example.com>');
123 $mail->cleanHeaders();
124 $headers = $mail->prop('headers');
125 $this->assertEquals('Andreas Gohr <andi@splitbrain.org>, foo <foo@example.com>', $headers['To']);
127 $mail->to('"Foo, Dr." <foo@example.com> , foo <foo@example.com>');
128 $mail->cleanHeaders();
129 $headers = $mail->prop('headers');
130 $this->assertEquals('=?UTF-8?B?IkZvbywgRHIuIg==?= <foo@example.com>, foo <foo@example.com>', $headers['To']);
132 $mail->to('Möp <moep@example.com> , foo <foo@example.com>');
133 $mail->cleanHeaders();
134 $headers = $mail->prop('headers');
135 $this->assertEquals('=?UTF-8?B?TcO2cA==?= <moep@example.com>, foo <foo@example.com>', $headers['To']);
137 $mail->to(array('Möp <moep@example.com> ',' foo <foo@example.com>'));
138 $mail->cleanHeaders();
139 $headers = $mail->prop('headers');
140 $this->assertEquals('=?UTF-8?B?TcO2cA==?= <moep@example.com>, foo <foo@example.com>', $headers['To']);
142 $mail->to(array('Beet, L van <lvb@example.com>',' foo <foo@example.com>'));
143 $mail->cleanHeaders();
144 $headers = $mail->prop('headers');
145 $this->assertEquals('=?UTF-8?B?QmVldCwgTCB2YW4=?= <lvb@example.com>, foo <foo@example.com>', $headers['To']);
150 function test_simplemail(){
151 global $conf;
152 $conf['htmlmail'] = 0;
154 $mailbody = 'A test mail in ASCII';
155 $mail = new TestMailer();
156 $mail->to('test@example.com');
157 $mail->setBody($mailbody);
159 $dump = $mail->dump();
161 // construct the expected mail body text - include the expected dokuwiki signature
162 $replacements = $mail->prop('replacements');
163 $expected_mail_body = chunk_split(base64_encode($mailbody.$replacements['text']['EMAILSIGNATURE']),72,MAILHEADER_EOL);
165 $this->assertNotRegexp('/Content-Type: multipart/',$dump);
166 $this->assertRegexp('#Content-Type: text/plain; charset=UTF-8#',$dump);
167 $this->assertRegexp('/'.preg_quote($expected_mail_body,'/').'/',$dump);
169 $conf['htmlmail'] = 1;
172 function test_replacements(){
173 $mail = new TestMailer();
175 $replacements = array( '@DATE@','@BROWSER@','@IPADDRESS@','@HOSTNAME@','@EMAILSIGNATURE@',
176 '@TITLE@','@DOKUWIKIURL@','@USER@','@NAME@','@MAIL@');
177 $mail->setBody('A test mail in with replacements '.join(' ',$replacements));
179 $text = $mail->prop('text');
180 $html = $mail->prop('html');
182 foreach($replacements as $repl){
183 $this->assertNotRegexp("/$repl/",$text,"$repl replacement still in text");
184 $this->assertNotRegexp("/$repl/",$html,"$repl replacement still in html");
189 * @see https://forum.dokuwiki.org/post/35822
191 function test_emptyBCCorCC() {
192 $mail = new TestMailer();
193 $headers = &$mail->propRef('headers');
194 $headers['Bcc'] = '';
195 $headers['Cc'] = '';
196 $header = $mail->prepareHeaders();
197 $this->assertEquals(0, preg_match('/(^|\n)Bcc: (\n|$)/', $header), 'Bcc found in headers.');
198 $this->assertEquals(0, preg_match('/(^|\n)Cc: (\n|$)/', $header), 'Cc found in headers.');
201 function test_nullTOorCCorBCC() {
202 $mail = new TestMailer();
203 $headers = &$mail->propRef('headers');
204 $headers['Bcc'] = NULL;
205 $headers['Cc'] = NULL;
206 $headers['To'] = NULL;
207 $header = $mail->prepareHeaders();
208 $this->assertEquals(0, preg_match('/(^|\n)Bcc: (\n|$)/', $header), 'Bcc found in headers.');
209 $this->assertEquals(0, preg_match('/(^|\n)Cc: (\n|$)/', $header), 'Cc found in headers.');
210 $this->assertEquals(0, preg_match('/(^|\n)To: (\n|$)/', $header), 'To found in headers.');
214 * @group internet
216 function test_lint(){
217 // prepare a simple multipart message
218 $mail = new TestMailer();
219 $mail->to(array('Möp <moep@example.com> ',' foo <foo@example.com>'));
220 $mail->from('Me <test@example.com>');
221 $mail->subject('This is a töst');
222 $mail->setBody('Hello Wörld,
224 please don\'t burn, okay?
226 $mail->attachContent('some test data', 'text/plain', 'a text.txt');
227 $msg = $mail->dump();
228 $msglines = explode("\n", $msg);
230 //echo $msg;
232 // ask message lint if it is okay
233 $html = new HTTPClient();
234 $results = $html->post('https://www.splitbrain.org/_static/msglint/', array('msg'=>$msg));
235 if($results === false) {
236 $this->markTestSkipped('no response from validator');
237 return;
240 // parse the result lines
241 $lines = explode("\n", $results);
242 $rows = count($lines);
243 $i=0;
244 while(trim($lines[$i]) != '-----------' && $i<$rows) $i++; //skip preamble
245 for($i=$i+1; $i<$rows; $i++){
246 $line = trim($lines[$i]);
247 if($line == '-----------') break; //skip appendix
249 // get possible continuation of the line
250 while($lines[$i+1][0] == ' '){
251 $line .= ' '.trim($lines[$i+1]);
252 $i++;
255 // check the line for errors
256 if(substr($line,0,5) == 'ERROR' || substr($line,0,7) == 'WARNING'){
257 // ignore some errors
258 if(strpos($line, "missing mandatory header 'return-path'")) continue; #set by MDA
259 if(strpos($line, "bare newline in text body decoded")) continue; #we don't send mail bodies as CRLF, yet
260 if(strpos($line, "last decoded line too long")) continue; #we don't send mail bodies as CRLF, yet
262 // get the context in which the error occured
263 $errorin = '';
264 if(preg_match('/line (\d+)$/', $line, $m)){
265 $errorin .= "\n".$msglines[$m[1] - 1];
267 if(preg_match('/lines (\d+)-(\d+)$/', $line, $m)){
268 for($x=$m[1]-1; $x<$m[2]; $x++){
269 $errorin .= "\n".$msglines[$x];
273 // raise the error
274 throw new Exception($line.$errorin);
278 $this->assertTrue(true); // avoid being marked as risky for having no assertion
281 function test_simplemailsignature() {
282 global $conf;
283 $conf['htmlmail'] = 0;
285 $mailbody = 'A test mail in ASCII';
286 $signature = "\n-- \n" . 'This mail was generated by DokuWiki at' . "\n" . DOKU_URL . "\n";
287 $mail = new TestMailer();
288 $mail->to('test@example.com');
289 $mail->setBody($mailbody);
291 $dump = $mail->dump();
293 // construct the expected mail body text - include the expected dokuwiki signature
294 $expected_mail_body = chunk_split(base64_encode($mailbody . $signature), 72, MAILHEADER_EOL);
295 $this->assertRegexp('/' . preg_quote($expected_mail_body, '/') . '/', $dump);
297 $conf['htmlmail'] = 1;
300 function test_htmlmailsignature() {
301 $mailbody_text = 'A test mail in ASCII :)';
302 $mailbody_html = 'A test mail in <strong>html</strong>';
303 $htmlmsg_expected = '<html>
304 <head>
305 <title>My Test Wiki</title>
306 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
307 </head>
308 <body>
310 A test mail in <strong>html</strong>
312 <br /><hr />
313 <small>This mail was generated by DokuWiki at<br /><a href="' . DOKU_URL . '">' . DOKU_URL . '</a></small>
314 </body>
315 </html>
318 $mail = new TestMailer();
319 $mail->to('test@example.com');
320 $mail->setBody($mailbody_text, null, null, $mailbody_html);
322 $dump = $mail->dump();
324 // construct the expected mail body text - include the expected dokuwiki signature
325 $expected_mail_body = chunk_split(base64_encode($htmlmsg_expected), 72, MAILHEADER_EOL);
327 $this->assertRegexp('/Content-Type: multipart/', $dump);
328 $this->assertRegexp('#Content-Type: text/plain; charset=UTF-8#', $dump);
329 $this->assertRegexp('/' . preg_quote($expected_mail_body, '/') . '/', $dump);
333 function test_htmlmailsignaturecustom() {
334 global $lang;
335 $lang['email_signature_html'] = 'Official message from your DokuWiki @DOKUWIKIURL@<br />Created by wonderful mail class <a href="https://www.dokuwiki.org/devel:mail">https://www.dokuwiki.org/devel:mail</a>';
337 $mailbody_text = 'A test mail in ASCII :)';
338 $mailbody_html = 'A test mail in <strong>html</strong>';
339 $htmlmsg_expected = '<html>
340 <head>
341 <title>My Test Wiki</title>
342 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
343 </head>
344 <body>
346 A test mail in <strong>html</strong>
348 <br /><hr />
349 <small>Official message from your DokuWiki <a href="' . DOKU_URL . '">' . DOKU_URL . '</a><br />Created by wonderful mail class <a href="https://www.dokuwiki.org/devel:mail">https://www.dokuwiki.org/devel:mail</a></small>
350 </body>
351 </html>
354 $mail = new TestMailer();
355 $mail->to('test@example.com');
356 $mail->setBody($mailbody_text, null, null, $mailbody_html);
358 $dump = $mail->dump();
360 // construct the expected mail body text - include the expected dokuwiki signature
361 $replacements = $mail->prop('replacements');
362 $expected_mail_body = chunk_split(base64_encode($htmlmsg_expected), 72, MAILHEADER_EOL);
364 $this->assertRegexp('/' . preg_quote($expected_mail_body, '/') . '/', $dump);
368 function test_getCleanName() {
369 $mail = new TestMailer();
370 $name = $mail->getCleanName('Foo Bar');
371 $this->assertEquals('Foo Bar', $name);
372 $name = $mail->getCleanName('Foo, Bar');
373 $this->assertEquals('"Foo, Bar"', $name);
374 $name = $mail->getCleanName('Foo" Bar');
375 $this->assertEquals('"Foo\" Bar"', $name);
376 $name = $mail->getCleanName("\tFoo tar ");
377 $this->assertEquals('Foo tar', $name);
381 //Setup VIM: ex: et ts=4 :