[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/_test/tests/inc/ -> mailer.test.php (source)

   1  <?php
   2  
   3  use dokuwiki\HTTP\HTTPClient;
   4  
   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;
  11      }
  12  
  13      public function &propRef($name) {
  14          return $this->$name;
  15      }
  16  
  17      public function prepareHeaders() {
  18          return parent::prepareHeaders();
  19      }
  20  
  21      public function cleanHeaders() {
  22          parent::cleanHeaders();
  23      }
  24  
  25  }
  26  
  27  /**
  28   * @group mailer_class
  29   */
  30  class mailer_test extends DokuWikiTest {
  31  
  32  
  33      function test_userheader(){
  34          $mail = new TestMailer();
  35          $headers = $mail->prop('headers');
  36          $this->assertArrayNotHasKey('X-Dokuwiki-User',$headers);
  37  
  38          $_SERVER['REMOTE_USER'] = 'andi';
  39          $mail = new TestMailer();
  40          $headers = $mail->prop('headers');
  41          $this->assertArrayHasKey('X-Dokuwiki-User',$headers);
  42      }
  43  
  44      function test_setHeader(){
  45          $mail = new TestMailer();
  46  
  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);
  54  
  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');
  61  
  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);
  73  
  74          // unset a header again
  75          $mail->setHeader('test-header','');
  76          $headers = $mail->prop('headers');
  77          $this->assertArrayNotHasKey('Test-Header',$headers);
  78      }
  79  
  80      function test_addresses(){
  81          if (isWindows()) {
  82              $this->markTestSkipped();
  83          }
  84  
  85          $mail = new TestMailer();
  86  
  87          $mail->to('andi@splitbrain.org');
  88          $mail->cleanHeaders();
  89          $headers = $mail->prop('headers');
  90          $this->assertEquals('andi@splitbrain.org', $headers['To']);
  91  
  92          $mail->to('<andi@splitbrain.org>');
  93          $mail->cleanHeaders();
  94          $headers = $mail->prop('headers');
  95          $this->assertEquals('andi@splitbrain.org', $headers['To']);
  96  
  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']);
 101  
 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']);
 106  
 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']);
 111  
 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']);
 116  
 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']);
 121  
 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']);
 126  
 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']);
 131  
 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']);
 136  
 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']);
 141  
 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']);
 146  
 147  
 148      }
 149  
 150      function test_simplemail(){
 151          global $conf;
 152          $conf['htmlmail'] = 0;
 153  
 154          $mailbody = 'A test mail in ASCII';
 155          $mail = new TestMailer();
 156          $mail->to('test@example.com');
 157          $mail->setBody($mailbody);
 158  
 159          $dump = $mail->dump();
 160  
 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);
 164  
 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);
 168  
 169          $conf['htmlmail'] = 1;
 170      }
 171  
 172      function test_replacements(){
 173          $mail = new TestMailer();
 174  
 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));
 178  
 179          $text = $mail->prop('text');
 180          $html = $mail->prop('html');
 181  
 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");
 185          }
 186      }
 187  
 188      /**
 189       * @see https://forum.dokuwiki.org/post/35822
 190       */
 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.');
 199      }
 200  
 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.');
 211      }
 212  
 213      /**
 214       * @group internet
 215       */
 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,
 223  
 224          please don\'t burn, okay?
 225          ');
 226          $mail->attachContent('some test data', 'text/plain', 'a text.txt');
 227          $msg = $mail->dump();
 228          $msglines = explode("\n", $msg);
 229  
 230          //echo $msg;
 231  
 232          // ask message lint if it is okay
 233          $html = new HTTPClient();
 234          $results = $html->post('https://tools.ietf.org/tools/msglint/msglint', array('msg'=>$msg));
 235          if($results === false) {
 236              $this->markTestSkipped('no response from validator');
 237              return;
 238          }
 239  
 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
 248  
 249              // get possible continuation of the line
 250              while($lines[$i+1][0] == ' '){
 251                  $line .= ' '.trim($lines[$i+1]);
 252                  $i++;
 253              }
 254  
 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
 261  
 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];
 266                  }
 267                  if(preg_match('/lines (\d+)-(\d+)$/', $line, $m)){
 268                      for($x=$m[1]-1; $x<$m[2]; $x++){
 269                          $errorin .= "\n".$msglines[$x];
 270                      }
 271                  }
 272  
 273                  // raise the error
 274                  throw new Exception($line.$errorin);
 275              }
 276          }
 277  
 278          $this->assertTrue(true); // avoid being marked as risky for having no assertion
 279      }
 280  
 281      function test_simplemailsignature() {
 282          global $conf;
 283          $conf['htmlmail'] = 0;
 284  
 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);
 290  
 291          $dump = $mail->dump();
 292  
 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);
 296  
 297          $conf['htmlmail'] = 1;
 298      }
 299  
 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>
 309  
 310  A test mail in <strong>html</strong>
 311  
 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>
 316  ';
 317  
 318          $mail = new TestMailer();
 319          $mail->to('test@example.com');
 320          $mail->setBody($mailbody_text, null, null, $mailbody_html);
 321  
 322          $dump = $mail->dump();
 323  
 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);
 326  
 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);
 330  
 331      }
 332  
 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>';
 336  
 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>
 345  
 346  A test mail in <strong>html</strong>
 347  
 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>
 352  ';
 353  
 354          $mail = new TestMailer();
 355          $mail->to('test@example.com');
 356          $mail->setBody($mailbody_text, null, null, $mailbody_html);
 357  
 358          $dump = $mail->dump();
 359  
 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);
 363  
 364          $this->assertRegexp('/' . preg_quote($expected_mail_body, '/') . '/', $dump);
 365  
 366      }
 367  
 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      }
 377  }
 378  //Setup VIM: ex: et ts=4 :