xref: /dokuwiki/_test/tests/inc/mailer.test.php (revision 0f50ca14027960e75aa0608ebbea52cfd89ceb08)
1<?php
2
3/**
4 * Extends the mailer class to expose internal variables for testing
5 */
6class TestMailer extends Mailer {
7    public function prop($name){
8        return $this->$name;
9    }
10
11    public function &propRef($name) {
12        return $this->$name;
13    }
14
15    public function prepareHeaders() {
16        return parent::prepareHeaders();
17    }
18
19    public function cleanHeaders() {
20        parent::cleanHeaders();
21    }
22
23}
24
25class mailer_test extends DokuWikiTest {
26
27
28    function test_userheader(){
29        $mail = new TestMailer();
30        $headers = $mail->prop('headers');
31        $this->assertArrayNotHasKey('X-Dokuwiki-User',$headers);
32
33        $_SERVER['REMOTE_USER'] = 'andi';
34        $mail = new TestMailer();
35        $headers = $mail->prop('headers');
36        $this->assertArrayHasKey('X-Dokuwiki-User',$headers);
37    }
38
39    function test_setHeader(){
40        $mail = new TestMailer();
41
42        // check existance of default headers
43        $headers = $mail->prop('headers');
44        $this->assertArrayHasKey('X-Mailer',$headers);
45        $this->assertArrayHasKey('X-Dokuwiki-Title',$headers);
46        $this->assertArrayHasKey('X-Dokuwiki-Server',$headers);
47        $this->assertArrayHasKey('X-Auto-Response-Suppress',$headers);
48        $this->assertArrayHasKey('List-Id',$headers);
49
50        // set a bunch of test headers
51        $mail->setHeader('test-header','bla');
52        $mail->setHeader('to','A valid ASCII name <test@example.com>');
53        $mail->setHeader('from',"Thös ne\needs\x00serious cleaning\$§%.");
54        $mail->setHeader('bad',"Thös ne\needs\x00serious cleaning\$§%.",false);
55        $mail->setHeader("weird\n*+\x00foo.-_@bar?",'now clean');
56
57        // are they set?
58        $headers = $mail->prop('headers');
59        $this->assertArrayHasKey('Test-Header',$headers);
60        $this->assertEquals('bla',$headers['Test-Header']);
61        $this->assertArrayHasKey('To',$headers);
62        $this->assertEquals('A valid ASCII name <test@example.com>',$headers['To']);
63        $this->assertArrayHasKey('From',$headers);
64        $this->assertEquals('Ths neeedsserious cleaning.',$headers['From']);
65        $this->assertArrayHasKey('Bad',$headers);
66        $this->assertEquals("Thös ne\needs\x00serious cleaning\$§%.",$headers['Bad']);
67        $this->assertArrayHasKey('Weird+foo.-_@bar',$headers);
68
69        // unset a header again
70        $mail->setHeader('test-header','');
71        $headers = $mail->prop('headers');
72        $this->assertArrayNotHasKey('Test-Header',$headers);
73    }
74
75    function test_addresses(){
76        $mail = new TestMailer();
77
78        $mail->to('andi@splitbrain.org');
79        $mail->cleanHeaders();
80        $headers = $mail->prop('headers');
81        $this->assertEquals('andi@splitbrain.org', $headers['To']);
82
83        $mail->to('<andi@splitbrain.org>');
84        $mail->cleanHeaders();
85        $headers = $mail->prop('headers');
86        $this->assertEquals('andi@splitbrain.org', $headers['To']);
87
88        $mail->to('Andreas Gohr <andi@splitbrain.org>');
89        $mail->cleanHeaders();
90        $headers = $mail->prop('headers');
91        $this->assertEquals('Andreas Gohr <andi@splitbrain.org>', $headers['To']);
92
93        $mail->to('Andreas Gohr <andi@splitbrain.org> , foo <foo@example.com>');
94        $mail->cleanHeaders();
95        $headers = $mail->prop('headers');
96        $this->assertEquals('Andreas Gohr <andi@splitbrain.org>, foo <foo@example.com>', $headers['To']);
97
98        $mail->to('Möp <moep@example.com> , foo <foo@example.com>');
99        $mail->cleanHeaders();
100        $headers = $mail->prop('headers');
101        $this->assertEquals('=?UTF-8?B?TcO2cA==?= <moep@example.com>, foo <foo@example.com>', $headers['To']);
102
103        $mail->to(array('Möp <moep@example.com> ',' foo <foo@example.com>'));
104        $mail->cleanHeaders();
105        $headers = $mail->prop('headers');
106        $this->assertEquals('=?UTF-8?B?TcO2cA==?= <moep@example.com>, foo <foo@example.com>', $headers['To']);
107
108        $mail->to(array('Beet, L van <lvb@example.com>',' foo <foo@example.com>'));
109        $mail->cleanHeaders();
110        $headers = $mail->prop('headers');
111        $this->assertEquals('=?UTF-8?B?QmVldCwgTCB2YW4=?= <lvb@example.com>, foo <foo@example.com>', $headers['To']);
112
113
114    }
115
116    function test_simplemail(){
117        global $conf;
118        $conf['htmlmail'] = 0;
119        $mail = new TestMailer();
120        $mail->to('test@example.com');
121        $mail->setBody('A test mail in ASCII');
122
123        $dump = $mail->dump();
124        $this->assertNotRegexp('/Content-Type: multipart/',$dump);
125        $this->assertRegexp('#Content-Type: text/plain; charset=UTF-8#',$dump);
126        $this->assertRegexp('/'.base64_encode('A test mail in ASCII').'/',$dump);
127
128        $conf['htmlmail'] = 1;
129    }
130
131    function test_replacements(){
132        $mail = new TestMailer();
133
134        $replacements = array( '@DATE@','@BROWSER@','@IPADDRESS@','@HOSTNAME@',
135                               '@TITLE@','@DOKUWIKIURL@','@USER@','@NAME@','@MAIL@');
136        $mail->setBody('A test mail in with replacements '.join(' ',$replacements));
137
138        $text = $mail->prop('text');
139        $html = $mail->prop('html');
140
141        foreach($replacements as $repl){
142            $this->assertNotRegexp("/$repl/",$text,"$repl replacement still in text");
143            $this->assertNotRegexp("/$repl/",$html,"$repl replacement still in html");
144        }
145    }
146
147    /**
148     * @see https://forum.dokuwiki.org/post/35822
149     */
150    function test_emptyBCCorCC() {
151        $mail = new TestMailer();
152        $headers = &$mail->propRef('headers');
153        $headers['Bcc'] = '';
154        $headers['Cc'] = '';
155        $header = $mail->prepareHeaders();
156        $this->assertEquals(0, preg_match('/(^|\n)Bcc: (\n|$)/', $header), 'Bcc found in headers.');
157        $this->assertEquals(0, preg_match('/(^|\n)Cc: (\n|$)/', $header), 'Cc found in headers.');
158    }
159
160    function test_nullTOorCCorBCC() {
161        $mail = new TestMailer();
162        $headers = &$mail->propRef('headers');
163        $headers['Bcc'] = NULL;
164        $headers['Cc'] = NULL;
165        $headers['To'] = NULL;
166        $header = $mail->prepareHeaders();
167        $this->assertEquals(0, preg_match('/(^|\n)Bcc: (\n|$)/', $header), 'Bcc found in headers.');
168        $this->assertEquals(0, preg_match('/(^|\n)Cc: (\n|$)/', $header), 'Cc found in headers.');
169        $this->assertEquals(0, preg_match('/(^|\n)To: (\n|$)/', $header), 'To found in headers.');
170    }
171
172    /**
173     * @group internet
174     */
175    function test_lint(){
176        // prepare a simple multipart message
177        $mail = new TestMailer();
178        $mail->to(array('Möp <moep@example.com> ',' foo <foo@example.com>'));
179        $mail->from('Me <test@example.com>');
180        $mail->subject('This is a töst');
181        $mail->setBody('Hello Wörld,
182
183        please don\'t burn, okay?
184        ');
185        $mail->attachContent('some test data', 'text/plain', 'a text.txt');
186        $msg = $mail->dump();
187        $msglines = explode("\n", $msg);
188
189        //echo $msg;
190
191        // ask message lint if it is okay
192        $html = new HTTPClient();
193        $results = $html->post('http://tools.ietf.org/tools/msglint/msglint', array('msg'=>$msg));
194        $this->assertTrue($results !== false);
195
196        // parse the result lines
197        $lines = explode("\n", $results);
198        $rows  = count($lines);
199        $i=0;
200        while(trim($lines[$i]) != '-----------' && $i<$rows) $i++; //skip preamble
201        for($i=$i+1; $i<$rows; $i++){
202            $line = trim($lines[$i]);
203            if($line == '-----------') break; //skip appendix
204
205            // get possible continuation of the line
206            while($lines[$i+1][0] == ' '){
207                $line .= ' '.trim($lines[$i+1]);
208                $i++;
209            }
210
211            // check the line for errors
212            if(substr($line,0,5) == 'ERROR' || substr($line,0,7) == 'WARNING'){
213                // ignore some errors
214                if(strpos($line, "missing mandatory header 'return-path'")) continue; #set by MDA
215                if(strpos($line, "bare newline in text body decoded")) continue; #seems to be false positive
216
217                // get the context in which the error occured
218                $errorin = '';
219                if(preg_match('/line (\d+)$/', $line, $m)){
220                    $errorin .= "\n".$msglines[$m[1] - 1];
221                }
222                if(preg_match('/lines (\d+)-(\d+)$/', $line, $m)){
223                    for($x=$m[1]-1; $x<$m[2]; $x++){
224                        $errorin .= "\n".$msglines[$x];
225                    }
226                }
227
228                // raise the error
229                throw new Exception($line.$errorin);
230            }
231        }
232
233    }
234}
235//Setup VIM: ex: et ts=4 :
236