Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * CakeEmailTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Network.Email
15
 * @since         CakePHP(tm) v 2.0.0
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18
 
19
App::uses('CakeEmail', 'Network/Email');
20
App::uses('File', 'Utility');
21
 
22
/**
23
 * Help to test CakeEmail
24
 *
25
 */
26
class TestCakeEmail extends CakeEmail {
27
 
28
/**
29
 * Config class name.
30
 *
31
 * Use a the testing config class in this file.
32
 *
33
 * @var string
34
 */
35
	protected $_configClass = 'TestEmailConfig';
36
 
37
/**
38
 * Config
39
 *
40
 */
41
	protected $_config = array();
42
 
43
/**
44
 * Wrap to protected method
45
 *
46
 * @return array
47
 */
48
	public function formatAddress($address) {
49
		return parent::_formatAddress($address);
50
	}
51
 
52
/**
53
 * Wrap to protected method
54
 *
55
 * @return array
56
 */
57
	public function wrap($text, $length = CakeEmail::LINE_LENGTH_MUST) {
58
		return parent::_wrap($text, $length);
59
	}
60
 
61
/**
62
 * Get the boundary attribute
63
 *
64
 * @return string
65
 */
66
	public function getBoundary() {
67
		return $this->_boundary;
68
	}
69
 
70
/**
71
 * Encode to protected method
72
 *
73
 * @return string
74
 */
75
	public function encode($text) {
76
		return $this->_encode($text);
77
	}
78
 
79
/**
80
 * Render to protected method
81
 *
82
 * @return array
83
 */
84
	public function render($content) {
85
		return $this->_render($content);
86
	}
87
 
88
}
89
 
90
/**
91
 * EmailConfig class
92
 *
93
 */
94
class TestEmailConfig {
95
 
96
/**
97
 * default config
98
 *
99
 * @var array
100
 */
101
	public $default = array(
102
		'subject' => 'Default Subject',
103
	);
104
 
105
/**
106
 * test config
107
 *
108
 * @var array
109
 */
110
	public $test = array(
111
		'from' => array('some@example.com' => 'My website'),
112
		'to' => array('test@example.com' => 'Testname'),
113
		'subject' => 'Test mail subject',
114
		'transport' => 'Debug',
115
		'theme' => 'TestTheme',
116
		'helpers' => array('Html', 'Form'),
117
	);
118
 
119
/**
120
 * test config 2
121
 *
122
 * @var array
123
 */
124
	public $test2 = array(
125
		'from' => array('some@example.com' => 'My website'),
126
		'to' => array('test@example.com' => 'Testname'),
127
		'subject' => 'Test mail subject',
128
		'transport' => 'Smtp',
129
		'host' => 'cakephp.org',
130
		'timeout' => 60
131
	);
132
 
133
}
134
 
135
/**
136
 * ExtendTransport class
137
 * test class to ensure the class has send() method
138
 *
139
 */
140
class ExtendTransport {
141
 
142
}
143
 
144
/**
145
 * CakeEmailTest class
146
 *
147
 * @package       Cake.Test.Case.Network.Email
148
 */
149
class CakeEmailTest extends CakeTestCase {
150
 
151
/**
152
 * setUp
153
 *
154
 * @return void
155
 */
156
	public function setUp() {
157
		parent::setUp();
158
 
159
		$this->_configFileExists = true;
160
		$emailConfig = new File(APP . 'Config' . DS . 'email.php');
161
		if (!$emailConfig->exists()) {
162
			$this->_configFileExists = false;
163
			$emailConfig->create();
164
		}
165
 
166
		$this->CakeEmail = new TestCakeEmail();
167
 
168
		App::build(array(
169
			'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
170
		));
171
	}
172
 
173
/**
174
 * tearDown method
175
 *
176
 * @return void
177
 */
178
	public function tearDown() {
179
		parent::tearDown();
180
		App::build();
181
 
182
		if (!$this->_configFileExists) {
183
			unlink(APP . 'Config' . DS . 'email.php');
184
		}
185
	}
186
 
187
/**
188
 * Test if the EmailConfig::$default configuration is read when present
189
 *
190
 * @return void
191
 */
192
	public function testDefaultConfig() {
193
		$this->assertEquals('Default Subject', $this->CakeEmail->subject());
194
	}
195
 
196
/**
197
 * testFrom method
198
 *
199
 * @return void
200
 */
201
	public function testFrom() {
202
		$this->assertSame(array(), $this->CakeEmail->from());
203
 
204
		$this->CakeEmail->from('cake@cakephp.org');
205
		$expected = array('cake@cakephp.org' => 'cake@cakephp.org');
206
		$this->assertSame($expected, $this->CakeEmail->from());
207
 
208
		$this->CakeEmail->from(array('cake@cakephp.org'));
209
		$this->assertSame($expected, $this->CakeEmail->from());
210
 
211
		$this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
212
		$expected = array('cake@cakephp.org' => 'CakePHP');
213
		$this->assertSame($expected, $this->CakeEmail->from());
214
 
215
		$result = $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP'));
216
		$this->assertSame($expected, $this->CakeEmail->from());
217
		$this->assertSame($this->CakeEmail, $result);
218
 
219
		$this->setExpectedException('SocketException');
220
		$result = $this->CakeEmail->from(array('cake@cakephp.org' => 'CakePHP', 'fail@cakephp.org' => 'From can only be one address'));
221
	}
222
 
223
/**
224
 * Test that from addresses using colons work.
225
 *
226
 * @return void
227
 */
228
	public function testFromWithColonsAndQuotes() {
229
		$address = array(
230
			'info@example.com' => '70:20:00 " Forum'
231
		);
232
		$this->CakeEmail->from($address);
233
		$this->assertEquals($address, $this->CakeEmail->from());
234
		$this->CakeEmail->to('info@example.com')
235
			->subject('Test email')
236
			->transport('Debug');
237
 
238
		$result = $this->CakeEmail->send();
239
		$this->assertContains('From: "70:20:00 \" Forum" <info@example.com>', $result['headers']);
240
	}
241
 
242
/**
243
 * testSender method
244
 *
245
 * @return void
246
 */
247
	public function testSender() {
248
		$this->CakeEmail->reset();
249
		$this->assertSame(array(), $this->CakeEmail->sender());
250
 
251
		$this->CakeEmail->sender('cake@cakephp.org', 'Name');
252
		$expected = array('cake@cakephp.org' => 'Name');
253
		$this->assertSame($expected, $this->CakeEmail->sender());
254
 
255
		$headers = $this->CakeEmail->getHeaders(array('from' => true, 'sender' => true));
256
		$this->assertFalse($headers['From']);
257
		$this->assertSame('Name <cake@cakephp.org>', $headers['Sender']);
258
 
259
		$this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
260
		$headers = $this->CakeEmail->getHeaders(array('from' => true, 'sender' => true));
261
		$this->assertSame('CakePHP <cake@cakephp.org>', $headers['From']);
262
		$this->assertSame('', $headers['Sender']);
263
	}
264
 
265
/**
266
 * testTo method
267
 *
268
 * @return void
269
 */
270
	public function testTo() {
271
		$this->assertSame(array(), $this->CakeEmail->to());
272
 
273
		$result = $this->CakeEmail->to('cake@cakephp.org');
274
		$expected = array('cake@cakephp.org' => 'cake@cakephp.org');
275
		$this->assertSame($expected, $this->CakeEmail->to());
276
		$this->assertSame($this->CakeEmail, $result);
277
 
278
		$this->CakeEmail->to('cake@cakephp.org', 'CakePHP');
279
		$expected = array('cake@cakephp.org' => 'CakePHP');
280
		$this->assertSame($expected, $this->CakeEmail->to());
281
 
282
		$list = array(
283
			'root@localhost' => 'root',
284
			'bjørn@hammeröath.com' => 'Bjorn',
285
			'cake.php@cakephp.org' => 'Cake PHP',
286
			'cake-php@googlegroups.com' => 'Cake Groups',
287
			'root@cakephp.org'
288
		);
289
		$this->CakeEmail->to($list);
290
		$expected = array(
291
			'root@localhost' => 'root',
292
			'bjørn@hammeröath.com' => 'Bjorn',
293
			'cake.php@cakephp.org' => 'Cake PHP',
294
			'cake-php@googlegroups.com' => 'Cake Groups',
295
			'root@cakephp.org' => 'root@cakephp.org'
296
		);
297
		$this->assertSame($expected, $this->CakeEmail->to());
298
 
299
		$this->CakeEmail->addTo('jrbasso@cakephp.org');
300
		$this->CakeEmail->addTo('mark_story@cakephp.org', 'Mark Story');
301
		$this->CakeEmail->addTo('foobar@ætdcadsl.dk');
302
		$result = $this->CakeEmail->addTo(array('phpnut@cakephp.org' => 'PhpNut', 'jose_zap@cakephp.org'));
303
		$expected = array(
304
			'root@localhost' => 'root',
305
			'bjørn@hammeröath.com' => 'Bjorn',
306
			'cake.php@cakephp.org' => 'Cake PHP',
307
			'cake-php@googlegroups.com' => 'Cake Groups',
308
			'root@cakephp.org' => 'root@cakephp.org',
309
			'jrbasso@cakephp.org' => 'jrbasso@cakephp.org',
310
			'mark_story@cakephp.org' => 'Mark Story',
311
			'foobar@ætdcadsl.dk' => 'foobar@ætdcadsl.dk',
312
			'phpnut@cakephp.org' => 'PhpNut',
313
			'jose_zap@cakephp.org' => 'jose_zap@cakephp.org'
314
		);
315
		$this->assertSame($expected, $this->CakeEmail->to());
316
		$this->assertSame($this->CakeEmail, $result);
317
	}
318
 
319
/**
320
 * Data provider function for testBuildInvalidData
321
 *
322
 * @return array
323
 */
324
	public static function invalidEmails() {
325
		return array(
326
			array(1.0),
327
			array(''),
328
			array('string'),
329
			array('<tag>'),
330
			array(array('ok@cakephp.org', 1.0, '', 'string'))
331
		);
332
	}
333
 
334
/**
335
 * testBuildInvalidData
336
 *
337
 * @dataProvider invalidEmails
338
 * @expectedException SocketException
339
 * @return void
340
 */
341
	public function testInvalidEmail($value) {
342
		$this->CakeEmail->to($value);
343
	}
344
 
345
/**
346
 * testBuildInvalidData
347
 *
348
 * @dataProvider invalidEmails
349
 * @expectedException SocketException
350
 * @return void
351
 */
352
	public function testInvalidEmailAdd($value) {
353
		$this->CakeEmail->addTo($value);
354
	}
355
 
356
/**
357
 * test emailPattern method
358
 *
359
 * @return void
360
 */
361
	public function testEmailPattern() {
362
		$regex = '/.+@.+\..+/i';
363
		$this->assertSame($regex, $this->CakeEmail->emailPattern($regex)->emailPattern());
364
	}
365
 
366
/**
367
 * Tests that it is possible to set email regex configuration to a CakeEmail object
368
 *
369
 * @return void
370
 */
371
	public function testConfigEmailPattern() {
372
		$regex = '/.+@.+\..+/i';
373
		$email = new CakeEmail(array('emailPattern' => $regex));
374
		$this->assertSame($regex, $email->emailPattern());
375
	}
376
 
377
/**
378
 * Tests that it is possible set custom email validation
379
 *
380
 * @return void
381
 */
382
	public function testCustomEmailValidation() {
383
		$regex = '/^[\.a-z0-9!#$%&\'*+\/=?^_`{|}~-]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]{2,6}$/i';
384
 
385
		$this->CakeEmail->emailPattern($regex)->to('pass.@example.com');
386
		$this->assertSame(array(
387
			'pass.@example.com' => 'pass.@example.com',
388
		), $this->CakeEmail->to());
389
 
390
		$this->CakeEmail->addTo('pass..old.docomo@example.com');
391
		$this->assertSame(array(
392
			'pass.@example.com' => 'pass.@example.com',
393
			'pass..old.docomo@example.com' => 'pass..old.docomo@example.com',
394
		), $this->CakeEmail->to());
395
 
396
		$this->CakeEmail->reset();
397
		$emails = array(
398
			'pass.@example.com',
399
			'pass..old.docomo@example.com'
400
		);
401
		$additionalEmails = array(
402
			'.extend.@example.com',
403
			'.docomo@example.com'
404
		);
405
		$this->CakeEmail->emailPattern($regex)->to($emails);
406
		$this->assertSame(array(
407
			'pass.@example.com' => 'pass.@example.com',
408
			'pass..old.docomo@example.com' => 'pass..old.docomo@example.com',
409
		), $this->CakeEmail->to());
410
 
411
		$this->CakeEmail->addTo($additionalEmails);
412
		$this->assertSame(array(
413
			'pass.@example.com' => 'pass.@example.com',
414
			'pass..old.docomo@example.com' => 'pass..old.docomo@example.com',
415
			'.extend.@example.com' => '.extend.@example.com',
416
			'.docomo@example.com' => '.docomo@example.com',
417
		), $this->CakeEmail->to());
418
	}
419
 
420
/**
421
 * Tests that it is possible to unset the email pattern and make use of filter_var() instead.
422
 *
423
 * @return void
424
 *
425
 * @expectedException SocketException
426
 * @expectedExceptionMessage Invalid email: "fail.@example.com"
427
 */
428
	public function testUnsetEmailPattern() {
429
		$email = new CakeEmail();
430
		$this->assertSame(CakeEmail::EMAIL_PATTERN, $email->emailPattern());
431
 
432
		$email->emailPattern(null);
433
		$this->assertNull($email->emailPattern());
434
 
435
		$email->to('pass@example.com');
436
		$email->to('fail.@example.com');
437
	}
438
 
439
/**
440
 * testFormatAddress method
441
 *
442
 * @return void
443
 */
444
	public function testFormatAddress() {
445
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'cake@cakephp.org'));
446
		$expected = array('cake@cakephp.org');
447
		$this->assertSame($expected, $result);
448
 
449
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'cake@cakephp.org', 'php@cakephp.org' => 'php@cakephp.org'));
450
		$expected = array('cake@cakephp.org', 'php@cakephp.org');
451
		$this->assertSame($expected, $result);
452
 
453
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'CakePHP', 'php@cakephp.org' => 'Cake'));
454
		$expected = array('CakePHP <cake@cakephp.org>', 'Cake <php@cakephp.org>');
455
		$this->assertSame($expected, $result);
456
 
457
		$result = $this->CakeEmail->formatAddress(array('me@example.com' => 'Last, First'));
458
		$expected = array('"Last, First" <me@example.com>');
459
		$this->assertSame($expected, $result);
460
 
461
		$result = $this->CakeEmail->formatAddress(array('me@example.com' => '"Last" First'));
462
		$expected = array('"\"Last\" First" <me@example.com>');
463
		$this->assertSame($expected, $result);
464
 
465
		$result = $this->CakeEmail->formatAddress(array('me@example.com' => 'Last First'));
466
		$expected = array('Last First <me@example.com>');
467
		$this->assertSame($expected, $result);
468
 
469
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => 'ÄÖÜTest'));
470
		$expected = array('=?UTF-8?B?w4TDlsOcVGVzdA==?= <cake@cakephp.org>');
471
		$this->assertSame($expected, $result);
472
 
473
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => '日本語Test'));
474
		$expected = array('=?UTF-8?B?5pel5pys6KqeVGVzdA==?= <cake@cakephp.org>');
475
		$this->assertSame($expected, $result);
476
	}
477
 
478
/**
479
 * testFormatAddressJapanese
480
 *
481
 * @return void
482
 */
483
	public function testFormatAddressJapanese() {
484
		$this->skipIf(!function_exists('mb_convert_encoding'));
485
 
486
		$this->CakeEmail->headerCharset = 'ISO-2022-JP';
487
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => '日本語Test'));
488
		$expected = array('=?ISO-2022-JP?B?GyRCRnxLXDhsGyhCVGVzdA==?= <cake@cakephp.org>');
489
		$this->assertSame($expected, $result);
490
 
491
		$result = $this->CakeEmail->formatAddress(array('cake@cakephp.org' => '寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処やぶら小路の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助'));
492
		$expected = array("=?ISO-2022-JP?B?GyRCPHc4Qkw1PHc4Qkw1OF45ZSROOyQkakBaJGwzJDo9TXg/ZTV7GyhC?=\r\n" .
493
			" =?ISO-2022-JP?B?GyRCJE4/ZTlUS3YxQE1oS3ZJd01oS3Y/KSQmPzIkaz1oJEs9OyRgGyhC?=\r\n" .
494
			" =?ISO-2022-JP?B?GyRCPWgkZCRWJGk+Lk8pJE5pLjQ7O1IlUSUkJV0lUSUkJV0lUSUkGyhC?=\r\n" .
495
			" =?ISO-2022-JP?B?GyRCJV0kTiU3JWUhPCVqJXMlLCVzJTclZSE8JWolcyUsJXMkTiUwGyhC?=\r\n" .
496
			" =?ISO-2022-JP?B?GyRCITwlaiVzJUAlJCUwITwlaiVzJUAlJCROJV0lcyVdJTMlVCE8GyhC?=\r\n" .
497
			" =?ISO-2022-JP?B?GyRCJE4lXSVzJV0lMyVKITwkTkQ5NVdMPyRORDk9dRsoQg==?= <cake@cakephp.org>");
498
		$this->assertSame($expected, $result);
499
	}
500
 
501
/**
502
 * testAddresses method
503
 *
504
 * @return void
505
 */
506
	public function testAddresses() {
507
		$this->CakeEmail->reset();
508
		$this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
509
		$this->CakeEmail->replyTo('replyto@cakephp.org', 'ReplyTo CakePHP');
510
		$this->CakeEmail->readReceipt('readreceipt@cakephp.org', 'ReadReceipt CakePHP');
511
		$this->CakeEmail->returnPath('returnpath@cakephp.org', 'ReturnPath CakePHP');
512
		$this->CakeEmail->to('to@cakephp.org', 'To, CakePHP');
513
		$this->CakeEmail->cc('cc@cakephp.org', 'Cc CakePHP');
514
		$this->CakeEmail->bcc('bcc@cakephp.org', 'Bcc CakePHP');
515
		$this->CakeEmail->addTo('to2@cakephp.org', 'To2 CakePHP');
516
		$this->CakeEmail->addCc('cc2@cakephp.org', 'Cc2 CakePHP');
517
		$this->CakeEmail->addBcc('bcc2@cakephp.org', 'Bcc2 CakePHP');
518
 
519
		$this->assertSame($this->CakeEmail->from(), array('cake@cakephp.org' => 'CakePHP'));
520
		$this->assertSame($this->CakeEmail->replyTo(), array('replyto@cakephp.org' => 'ReplyTo CakePHP'));
521
		$this->assertSame($this->CakeEmail->readReceipt(), array('readreceipt@cakephp.org' => 'ReadReceipt CakePHP'));
522
		$this->assertSame($this->CakeEmail->returnPath(), array('returnpath@cakephp.org' => 'ReturnPath CakePHP'));
523
		$this->assertSame($this->CakeEmail->to(), array('to@cakephp.org' => 'To, CakePHP', 'to2@cakephp.org' => 'To2 CakePHP'));
524
		$this->assertSame($this->CakeEmail->cc(), array('cc@cakephp.org' => 'Cc CakePHP', 'cc2@cakephp.org' => 'Cc2 CakePHP'));
525
		$this->assertSame($this->CakeEmail->bcc(), array('bcc@cakephp.org' => 'Bcc CakePHP', 'bcc2@cakephp.org' => 'Bcc2 CakePHP'));
526
 
527
		$headers = $this->CakeEmail->getHeaders(array_fill_keys(array('from', 'replyTo', 'readReceipt', 'returnPath', 'to', 'cc', 'bcc'), true));
528
		$this->assertSame($headers['From'], 'CakePHP <cake@cakephp.org>');
529
		$this->assertSame($headers['Reply-To'], 'ReplyTo CakePHP <replyto@cakephp.org>');
530
		$this->assertSame($headers['Disposition-Notification-To'], 'ReadReceipt CakePHP <readreceipt@cakephp.org>');
531
		$this->assertSame($headers['Return-Path'], 'ReturnPath CakePHP <returnpath@cakephp.org>');
532
		$this->assertSame($headers['To'], '"To, CakePHP" <to@cakephp.org>, To2 CakePHP <to2@cakephp.org>');
533
		$this->assertSame($headers['Cc'], 'Cc CakePHP <cc@cakephp.org>, Cc2 CakePHP <cc2@cakephp.org>');
534
		$this->assertSame($headers['Bcc'], 'Bcc CakePHP <bcc@cakephp.org>, Bcc2 CakePHP <bcc2@cakephp.org>');
535
	}
536
 
537
/**
538
 * testMessageId method
539
 *
540
 * @return void
541
 */
542
	public function testMessageId() {
543
		$this->CakeEmail->messageId(true);
544
		$result = $this->CakeEmail->getHeaders();
545
		$this->assertTrue(isset($result['Message-ID']));
546
 
547
		$this->CakeEmail->messageId(false);
548
		$result = $this->CakeEmail->getHeaders();
549
		$this->assertFalse(isset($result['Message-ID']));
550
 
551
		$result = $this->CakeEmail->messageId('<my-email@localhost>');
552
		$this->assertSame($this->CakeEmail, $result);
553
		$result = $this->CakeEmail->getHeaders();
554
		$this->assertSame('<my-email@localhost>', $result['Message-ID']);
555
 
556
		$result = $this->CakeEmail->messageId();
557
		$this->assertSame('<my-email@localhost>', $result);
558
	}
559
 
560
/**
561
 * testMessageIdInvalid method
562
 *
563
 * @return void
564
 * @expectedException SocketException
565
 */
566
	public function testMessageIdInvalid() {
567
		$this->CakeEmail->messageId('my-email@localhost');
568
	}
569
 
570
/**
571
 * testDomain method
572
 *
573
 * @return void
574
 */
575
	public function testDomain() {
576
		$result = $this->CakeEmail->domain();
577
		$expected = env('HTTP_HOST') ? env('HTTP_HOST') : php_uname('n');
578
		$this->assertSame($expected, $result);
579
 
580
		$this->CakeEmail->domain('example.org');
581
		$result = $this->CakeEmail->domain();
582
		$expected = 'example.org';
583
		$this->assertSame($expected, $result);
584
	}
585
 
586
/**
587
 * testMessageIdWithDomain method
588
 *
589
 * @return void
590
 */
591
	public function testMessageIdWithDomain() {
592
		$this->CakeEmail->domain('example.org');
593
		$result = $this->CakeEmail->getHeaders();
594
		$expected = '@example.org>';
595
		$this->assertTextContains($expected, $result['Message-ID']);
596
 
597
		$_SERVER['HTTP_HOST'] = 'example.org';
598
		$result = $this->CakeEmail->getHeaders();
599
		$this->assertTextContains('example.org', $result['Message-ID']);
600
 
601
		$_SERVER['HTTP_HOST'] = 'example.org:81';
602
		$result = $this->CakeEmail->getHeaders();
603
		$this->assertTextNotContains(':81', $result['Message-ID']);
604
	}
605
 
606
/**
607
 * testSubject method
608
 *
609
 * @return void
610
 */
611
	public function testSubject() {
612
		$this->CakeEmail->subject('You have a new message.');
613
		$this->assertSame('You have a new message.', $this->CakeEmail->subject());
614
 
615
		$this->CakeEmail->subject('You have a new message, I think.');
616
		$this->assertSame($this->CakeEmail->subject(), 'You have a new message, I think.');
617
		$this->CakeEmail->subject(1);
618
		$this->assertSame('1', $this->CakeEmail->subject());
619
 
620
		$this->CakeEmail->subject('هذه رسالة بعنوان طويل مرسل للمستلم');
621
		$expected = '=?UTF-8?B?2YfYsNmHINix2LPYp9mE2Kkg2KjYudmG2YjYp9mGINi32YjZitmEINmF2LE=?=' . "\r\n" . ' =?UTF-8?B?2LPZhCDZhNmE2YXYs9iq2YTZhQ==?=';
622
		$this->assertSame($expected, $this->CakeEmail->subject());
623
	}
624
 
625
/**
626
 * testSubjectJapanese
627
 *
628
 * @return void
629
 */
630
	public function testSubjectJapanese() {
631
		$this->skipIf(!function_exists('mb_convert_encoding'));
632
		mb_internal_encoding('UTF-8');
633
 
634
		$this->CakeEmail->headerCharset = 'ISO-2022-JP';
635
		$this->CakeEmail->subject('日本語のSubjectにも対応するよ');
636
		$expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsJE4bKEJTdWJqZWN0GyRCJEskYkJQMX4kOSRrJGgbKEI=?=';
637
		$this->assertSame($expected, $this->CakeEmail->subject());
638
 
639
		$this->CakeEmail->subject('長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?');
640
		$expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
641
			" =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
642
			" =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=";
643
		$this->assertSame($expected, $this->CakeEmail->subject());
644
	}
645
 
646
/**
647
 * testHeaders method
648
 *
649
 * @return void
650
 */
651
	public function testHeaders() {
652
		$this->CakeEmail->messageId(false);
653
		$this->CakeEmail->setHeaders(array('X-Something' => 'nice'));
654
		$expected = array(
655
			'X-Something' => 'nice',
656
			'X-Mailer' => 'CakePHP Email',
657
			'Date' => date(DATE_RFC2822),
658
			'MIME-Version' => '1.0',
659
			'Content-Type' => 'text/plain; charset=UTF-8',
660
			'Content-Transfer-Encoding' => '8bit'
661
		);
662
		$this->assertSame($expected, $this->CakeEmail->getHeaders());
663
 
664
		$this->CakeEmail->addHeaders(array('X-Something' => 'very nice', 'X-Other' => 'cool'));
665
		$expected = array(
666
			'X-Something' => 'very nice',
667
			'X-Other' => 'cool',
668
			'X-Mailer' => 'CakePHP Email',
669
			'Date' => date(DATE_RFC2822),
670
			'MIME-Version' => '1.0',
671
			'Content-Type' => 'text/plain; charset=UTF-8',
672
			'Content-Transfer-Encoding' => '8bit'
673
		);
674
		$this->assertSame($expected, $this->CakeEmail->getHeaders());
675
 
676
		$this->CakeEmail->from('cake@cakephp.org');
677
		$this->assertSame($expected, $this->CakeEmail->getHeaders());
678
 
679
		$expected = array(
680
			'From' => 'cake@cakephp.org',
681
			'X-Something' => 'very nice',
682
			'X-Other' => 'cool',
683
			'X-Mailer' => 'CakePHP Email',
684
			'Date' => date(DATE_RFC2822),
685
			'MIME-Version' => '1.0',
686
			'Content-Type' => 'text/plain; charset=UTF-8',
687
			'Content-Transfer-Encoding' => '8bit'
688
		);
689
		$this->assertSame($expected, $this->CakeEmail->getHeaders(array('from' => true)));
690
 
691
		$this->CakeEmail->from('cake@cakephp.org', 'CakePHP');
692
		$expected['From'] = 'CakePHP <cake@cakephp.org>';
693
		$this->assertSame($expected, $this->CakeEmail->getHeaders(array('from' => true)));
694
 
695
		$this->CakeEmail->to(array('cake@cakephp.org', 'php@cakephp.org' => 'CakePHP'));
696
		$expected = array(
697
			'From' => 'CakePHP <cake@cakephp.org>',
698
			'To' => 'cake@cakephp.org, CakePHP <php@cakephp.org>',
699
			'X-Something' => 'very nice',
700
			'X-Other' => 'cool',
701
			'X-Mailer' => 'CakePHP Email',
702
			'Date' => date(DATE_RFC2822),
703
			'MIME-Version' => '1.0',
704
			'Content-Type' => 'text/plain; charset=UTF-8',
705
			'Content-Transfer-Encoding' => '8bit'
706
		);
707
		$this->assertSame($expected, $this->CakeEmail->getHeaders(array('from' => true, 'to' => true)));
708
 
709
		$this->CakeEmail->charset = 'ISO-2022-JP';
710
		$expected = array(
711
			'From' => 'CakePHP <cake@cakephp.org>',
712
			'To' => 'cake@cakephp.org, CakePHP <php@cakephp.org>',
713
			'X-Something' => 'very nice',
714
			'X-Other' => 'cool',
715
			'X-Mailer' => 'CakePHP Email',
716
			'Date' => date(DATE_RFC2822),
717
			'MIME-Version' => '1.0',
718
			'Content-Type' => 'text/plain; charset=ISO-2022-JP',
719
			'Content-Transfer-Encoding' => '7bit'
720
		);
721
		$this->assertSame($expected, $this->CakeEmail->getHeaders(array('from' => true, 'to' => true)));
722
 
723
		$result = $this->CakeEmail->setHeaders(array());
724
		$this->assertInstanceOf('CakeEmail', $result);
725
	}
726
 
727
/**
728
 * Data provider function for testInvalidHeaders
729
 *
730
 * @return array
731
 */
732
	public static function invalidHeaders() {
733
		return array(
734
			array(10),
735
			array(''),
736
			array('string'),
737
			array(false),
738
			array(null)
739
		);
740
	}
741
 
742
/**
743
 * testInvalidHeaders
744
 *
745
 * @dataProvider invalidHeaders
746
 * @expectedException SocketException
747
 * @return void
748
 */
749
	public function testInvalidHeaders($value) {
750
		$this->CakeEmail->setHeaders($value);
751
	}
752
 
753
/**
754
 * testInvalidAddHeaders
755
 *
756
 * @dataProvider invalidHeaders
757
 * @expectedException SocketException
758
 * @return void
759
 */
760
	public function testInvalidAddHeaders($value) {
761
		$this->CakeEmail->addHeaders($value);
762
	}
763
 
764
/**
765
 * testTemplate method
766
 *
767
 * @return void
768
 */
769
	public function testTemplate() {
770
		$this->CakeEmail->template('template', 'layout');
771
		$expected = array('template' => 'template', 'layout' => 'layout');
772
		$this->assertSame($expected, $this->CakeEmail->template());
773
 
774
		$this->CakeEmail->template('new_template');
775
		$expected = array('template' => 'new_template', 'layout' => 'layout');
776
		$this->assertSame($expected, $this->CakeEmail->template());
777
 
778
		$this->CakeEmail->template('template', null);
779
		$expected = array('template' => 'template', 'layout' => null);
780
		$this->assertSame($expected, $this->CakeEmail->template());
781
 
782
		$this->CakeEmail->template(null, null);
783
		$expected = array('template' => null, 'layout' => null);
784
		$this->assertSame($expected, $this->CakeEmail->template());
785
	}
786
 
787
/**
788
 * testTheme method
789
 *
790
 * @return void
791
 */
792
	public function testTheme() {
793
		$this->assertNull($this->CakeEmail->theme());
794
 
795
		$this->CakeEmail->theme('default');
796
		$expected = 'default';
797
		$this->assertSame($expected, $this->CakeEmail->theme());
798
	}
799
 
800
/**
801
 * testViewVars method
802
 *
803
 * @return void
804
 */
805
	public function testViewVars() {
806
		$this->assertSame(array(), $this->CakeEmail->viewVars());
807
 
808
		$this->CakeEmail->viewVars(array('value' => 12345));
809
		$this->assertSame(array('value' => 12345), $this->CakeEmail->viewVars());
810
 
811
		$this->CakeEmail->viewVars(array('name' => 'CakePHP'));
812
		$this->assertSame(array('value' => 12345, 'name' => 'CakePHP'), $this->CakeEmail->viewVars());
813
 
814
		$this->CakeEmail->viewVars(array('value' => 4567));
815
		$this->assertSame(array('value' => 4567, 'name' => 'CakePHP'), $this->CakeEmail->viewVars());
816
	}
817
 
818
/**
819
 * testAttachments method
820
 *
821
 * @return void
822
 */
823
	public function testAttachments() {
824
		$this->CakeEmail->attachments(CAKE . 'basics.php');
825
		$expected = array(
826
			'basics.php' => array(
827
				'file' => CAKE . 'basics.php',
828
				'mimetype' => 'application/octet-stream'
829
			)
830
		);
831
		$this->assertSame($expected, $this->CakeEmail->attachments());
832
 
833
		$this->CakeEmail->attachments(array());
834
		$this->assertSame(array(), $this->CakeEmail->attachments());
835
 
836
		$this->CakeEmail->attachments(array(
837
			array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain')
838
		));
839
		$this->CakeEmail->addAttachments(CAKE . 'bootstrap.php');
840
		$this->CakeEmail->addAttachments(array(CAKE . 'bootstrap.php'));
841
		$this->CakeEmail->addAttachments(array('other.txt' => CAKE . 'bootstrap.php', 'license' => CAKE . 'LICENSE.txt'));
842
		$expected = array(
843
			'basics.php' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain'),
844
			'bootstrap.php' => array('file' => CAKE . 'bootstrap.php', 'mimetype' => 'application/octet-stream'),
845
			'other.txt' => array('file' => CAKE . 'bootstrap.php', 'mimetype' => 'application/octet-stream'),
846
			'license' => array('file' => CAKE . 'LICENSE.txt', 'mimetype' => 'application/octet-stream')
847
		);
848
		$this->assertSame($expected, $this->CakeEmail->attachments());
849
 
850
		$this->setExpectedException('SocketException');
851
		$this->CakeEmail->attachments(array(array('nofile' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
852
	}
853
 
854
/**
855
 * testTransport method
856
 *
857
 * @return void
858
 */
859
	public function testTransport() {
860
		$result = $this->CakeEmail->transport('Debug');
861
		$this->assertSame($this->CakeEmail, $result);
862
		$this->assertSame('Debug', $this->CakeEmail->transport());
863
 
864
		$result = $this->CakeEmail->transportClass();
865
		$this->assertInstanceOf('DebugTransport', $result);
866
 
867
		$this->setExpectedException('SocketException');
868
		$this->CakeEmail->transport('Invalid');
869
		$result = $this->CakeEmail->transportClass();
870
	}
871
 
872
/**
873
 * testExtendTransport method
874
 *
875
 * @return void
876
 */
877
	public function testExtendTransport() {
878
		$this->setExpectedException('SocketException');
879
		$this->CakeEmail->transport('Extend');
880
		$this->CakeEmail->transportClass();
881
	}
882
 
883
/**
884
 * testConfig method
885
 *
886
 * @return void
887
 */
888
	public function testConfig() {
889
		$transportClass = $this->CakeEmail->transport('debug')->transportClass();
890
 
891
		$config = array('test' => 'ok', 'test2' => true);
892
		$this->CakeEmail->config($config);
893
		$this->assertSame($config, $transportClass->config());
894
		$expected = $config + array('subject' => 'Default Subject');
895
		$this->assertSame($expected, $this->CakeEmail->config());
896
 
897
		$this->CakeEmail->config(array());
898
		$this->assertSame($config, $transportClass->config());
899
 
900
		$config = array('test' => 'test@example.com', 'subject' => 'my test subject');
901
		$this->CakeEmail->config($config);
902
		$expected = array('test' => 'test@example.com', 'subject' => 'my test subject', 'test2' => true);
903
		$this->assertSame($expected, $this->CakeEmail->config());
904
		$this->assertSame(array('test' => 'test@example.com', 'test2' => true), $transportClass->config());
905
	}
906
 
907
/**
908
 * testConfigString method
909
 *
910
 * @return void
911
 */
912
	public function testConfigString() {
913
		$configs = new TestEmailConfig();
914
		$this->CakeEmail->config('test');
915
 
916
		$result = $this->CakeEmail->to();
917
		$this->assertEquals($configs->test['to'], $result);
918
 
919
		$result = $this->CakeEmail->from();
920
		$this->assertEquals($configs->test['from'], $result);
921
 
922
		$result = $this->CakeEmail->subject();
923
		$this->assertEquals($configs->test['subject'], $result);
924
 
925
		$result = $this->CakeEmail->theme();
926
		$this->assertEquals($configs->test['theme'], $result);
927
 
928
		$result = $this->CakeEmail->transport();
929
		$this->assertEquals($configs->test['transport'], $result);
930
 
931
		$result = $this->CakeEmail->transportClass();
932
		$this->assertInstanceOf('DebugTransport', $result);
933
 
934
		$result = $this->CakeEmail->helpers();
935
		$this->assertEquals($configs->test['helpers'], $result);
936
	}
937
 
938
/**
939
 * Test updating config doesn't reset transport's config.
940
 *
941
 * @return void
942
 */
943
	public function testConfigMerge() {
944
		$this->CakeEmail->config('test2');
945
 
946
		$expected = array(
947
			'host' => 'cakephp.org',
948
			'port' => 25,
949
			'timeout' => 60,
950
			'username' => null,
951
			'password' => null,
952
			'client' => null,
953
			'tls' => false
954
		);
955
		$this->assertEquals($expected, $this->CakeEmail->transportClass()->config());
956
 
957
		$this->CakeEmail->config(array('log' => true));
958
		$result = $this->CakeEmail->transportClass()->config();
959
		$expected += array('log' => true);
960
		$this->assertEquals($expected, $this->CakeEmail->transportClass()->config());
961
 
962
		$this->CakeEmail->config(array('timeout' => 45));
963
		$result = $this->CakeEmail->transportClass()->config();
964
		$this->assertEquals(45, $result['timeout']);
965
	}
966
 
967
/**
968
 * Calling send() with no parameters should not overwrite the view variables.
969
 *
970
 * @return void
971
 */
972
	public function testSendWithNoContentDoesNotOverwriteViewVar() {
973
		$this->CakeEmail->reset();
974
		$this->CakeEmail->transport('Debug');
975
		$this->CakeEmail->from('cake@cakephp.org');
976
		$this->CakeEmail->to('you@cakephp.org');
977
		$this->CakeEmail->subject('My title');
978
		$this->CakeEmail->emailFormat('text');
979
		$this->CakeEmail->template('default');
980
		$this->CakeEmail->viewVars(array(
981
			'content' => 'A message to you',
982
		));
983
 
984
		$result = $this->CakeEmail->send();
985
		$this->assertContains('A message to you', $result['message']);
986
	}
987
 
988
/**
989
 * testSendWithContent method
990
 *
991
 * @return void
992
 */
993
	public function testSendWithContent() {
994
		$this->CakeEmail->reset();
995
		$this->CakeEmail->transport('Debug');
996
		$this->CakeEmail->from('cake@cakephp.org');
997
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
998
		$this->CakeEmail->subject('My title');
999
		$this->CakeEmail->config(array('empty'));
1000
 
1001
		$result = $this->CakeEmail->send("Here is my body, with multi lines.\nThis is the second line.\r\n\r\nAnd the last.");
1002
		$expected = array('headers', 'message');
1003
		$this->assertEquals($expected, array_keys($result));
1004
		$expected = "Here is my body, with multi lines.\r\nThis is the second line.\r\n\r\nAnd the last.\r\n\r\n";
1005
 
1006
		$this->assertEquals($expected, $result['message']);
1007
		$this->assertTrue((bool)strpos($result['headers'], 'Date: '));
1008
		$this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
1009
		$this->assertTrue((bool)strpos($result['headers'], 'To: '));
1010
 
1011
		$result = $this->CakeEmail->send("Other body");
1012
		$expected = "Other body\r\n\r\n";
1013
		$this->assertSame($expected, $result['message']);
1014
		$this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
1015
		$this->assertTrue((bool)strpos($result['headers'], 'To: '));
1016
 
1017
		$this->CakeEmail->reset();
1018
		$this->CakeEmail->transport('Debug');
1019
		$this->CakeEmail->from('cake@cakephp.org');
1020
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1021
		$this->CakeEmail->subject('My title');
1022
		$this->CakeEmail->config(array('empty'));
1023
		$result = $this->CakeEmail->send(array('Sending content', 'As array'));
1024
		$expected = "Sending content\r\nAs array\r\n\r\n\r\n";
1025
		$this->assertSame($expected, $result['message']);
1026
	}
1027
 
1028
/**
1029
 * testSendWithoutFrom method
1030
 *
1031
 * @return void
1032
 */
1033
	public function testSendWithoutFrom() {
1034
		$this->CakeEmail->transport('Debug');
1035
		$this->CakeEmail->to('cake@cakephp.org');
1036
		$this->CakeEmail->subject('My title');
1037
		$this->CakeEmail->config(array('empty'));
1038
		$this->setExpectedException('SocketException');
1039
		$this->CakeEmail->send("Forgot to set From");
1040
	}
1041
 
1042
/**
1043
 * testSendWithoutTo method
1044
 *
1045
 * @return void
1046
 */
1047
	public function testSendWithoutTo() {
1048
		$this->CakeEmail->transport('Debug');
1049
		$this->CakeEmail->from('cake@cakephp.org');
1050
		$this->CakeEmail->subject('My title');
1051
		$this->CakeEmail->config(array('empty'));
1052
		$this->setExpectedException('SocketException');
1053
		$this->CakeEmail->send("Forgot to set To");
1054
	}
1055
 
1056
/**
1057
 * Test send() with no template.
1058
 *
1059
 * @return void
1060
 */
1061
	public function testSendNoTemplateWithAttachments() {
1062
		$this->CakeEmail->transport('debug');
1063
		$this->CakeEmail->from('cake@cakephp.org');
1064
		$this->CakeEmail->to('cake@cakephp.org');
1065
		$this->CakeEmail->subject('My title');
1066
		$this->CakeEmail->emailFormat('text');
1067
		$this->CakeEmail->attachments(array(CAKE . 'basics.php'));
1068
		$result = $this->CakeEmail->send('Hello');
1069
 
1070
		$boundary = $this->CakeEmail->getBoundary();
1071
		$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
1072
		$expected = "--$boundary\r\n" .
1073
			"Content-Type: text/plain; charset=UTF-8\r\n" .
1074
			"Content-Transfer-Encoding: 8bit\r\n" .
1075
			"\r\n" .
1076
			"Hello" .
1077
			"\r\n" .
1078
			"\r\n" .
1079
			"\r\n" .
1080
			"--$boundary\r\n" .
1081
			"Content-Type: application/octet-stream\r\n" .
1082
			"Content-Transfer-Encoding: base64\r\n" .
1083
			"Content-Disposition: attachment; filename=\"basics.php\"\r\n\r\n";
1084
		$this->assertContains($expected, $result['message']);
1085
	}
1086
 
1087
/**
1088
 * Test send() with no template and data string attachment
1089
 *
1090
 * @return void
1091
 */
1092
 
1093
	public function testSendNoTemplateWithDataStringAttachment() {
1094
		$this->CakeEmail->transport('debug');
1095
		$this->CakeEmail->from('cake@cakephp.org');
1096
		$this->CakeEmail->to('cake@cakephp.org');
1097
		$this->CakeEmail->subject('My title');
1098
		$this->CakeEmail->emailFormat('text');
1099
		$data = file_get_contents(CAKE . 'Console/Templates/skel/webroot/img/cake.icon.png');
1100
		$this->CakeEmail->attachments(array('cake.icon.png' => array(
1101
				'data' => $data,
1102
				'mimetype' => 'image/png'
1103
		)));
1104
		$result = $this->CakeEmail->send('Hello');
1105
 
1106
		$boundary = $this->CakeEmail->getBoundary();
1107
		$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
1108
		$expected = "--$boundary\r\n" .
1109
				"Content-Type: text/plain; charset=UTF-8\r\n" .
1110
				"Content-Transfer-Encoding: 8bit\r\n" .
1111
				"\r\n" .
1112
				"Hello" .
1113
				"\r\n" .
1114
				"\r\n" .
1115
				"\r\n" .
1116
				"--$boundary\r\n" .
1117
				"Content-Type: image/png\r\n" .
1118
				"Content-Transfer-Encoding: base64\r\n" .
1119
				"Content-Disposition: attachment; filename=\"cake.icon.png\"\r\n\r\n";
1120
		$expected .= chunk_split(base64_encode($data), 76, "\r\n");
1121
		$this->assertContains($expected, $result['message']);
1122
	}
1123
 
1124
/**
1125
 * Test send() with no template as both
1126
 *
1127
 * @return void
1128
 */
1129
	public function testSendNoTemplateWithAttachmentsAsBoth() {
1130
		$this->CakeEmail->transport('debug');
1131
		$this->CakeEmail->from('cake@cakephp.org');
1132
		$this->CakeEmail->to('cake@cakephp.org');
1133
		$this->CakeEmail->subject('My title');
1134
		$this->CakeEmail->emailFormat('both');
1135
		$this->CakeEmail->attachments(array(CAKE . 'VERSION.txt'));
1136
		$result = $this->CakeEmail->send('Hello');
1137
 
1138
		$boundary = $this->CakeEmail->getBoundary();
1139
		$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
1140
		$expected = "--$boundary\r\n" .
1141
			"Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
1142
			"\r\n" .
1143
			"--alt-$boundary\r\n" .
1144
			"Content-Type: text/plain; charset=UTF-8\r\n" .
1145
			"Content-Transfer-Encoding: 8bit\r\n" .
1146
			"\r\n" .
1147
			"Hello" .
1148
			"\r\n" .
1149
			"\r\n" .
1150
			"\r\n" .
1151
			"--alt-$boundary\r\n" .
1152
			"Content-Type: text/html; charset=UTF-8\r\n" .
1153
			"Content-Transfer-Encoding: 8bit\r\n" .
1154
			"\r\n" .
1155
			"Hello" .
1156
			"\r\n" .
1157
			"\r\n" .
1158
			"\r\n" .
1159
			"--alt-{$boundary}--\r\n" .
1160
			"\r\n" .
1161
			"--$boundary\r\n" .
1162
			"Content-Type: application/octet-stream\r\n" .
1163
			"Content-Transfer-Encoding: base64\r\n" .
1164
			"Content-Disposition: attachment; filename=\"VERSION.txt\"\r\n\r\n";
1165
		$this->assertContains($expected, $result['message']);
1166
	}
1167
 
1168
/**
1169
 * Test setting inline attachments and messages.
1170
 *
1171
 * @return void
1172
 */
1173
	public function testSendWithInlineAttachments() {
1174
		$this->CakeEmail->transport('debug');
1175
		$this->CakeEmail->from('cake@cakephp.org');
1176
		$this->CakeEmail->to('cake@cakephp.org');
1177
		$this->CakeEmail->subject('My title');
1178
		$this->CakeEmail->emailFormat('both');
1179
		$this->CakeEmail->attachments(array(
1180
			'cake.png' => array(
1181
				'file' => CAKE . 'VERSION.txt',
1182
				'contentId' => 'abc123'
1183
			)
1184
		));
1185
		$result = $this->CakeEmail->send('Hello');
1186
 
1187
		$boundary = $this->CakeEmail->getBoundary();
1188
		$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
1189
		$expected = "--$boundary\r\n" .
1190
			"Content-Type: multipart/related; boundary=\"rel-$boundary\"\r\n" .
1191
			"\r\n" .
1192
			"--rel-$boundary\r\n" .
1193
			"Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
1194
			"\r\n" .
1195
			"--alt-$boundary\r\n" .
1196
			"Content-Type: text/plain; charset=UTF-8\r\n" .
1197
			"Content-Transfer-Encoding: 8bit\r\n" .
1198
			"\r\n" .
1199
			"Hello" .
1200
			"\r\n" .
1201
			"\r\n" .
1202
			"\r\n" .
1203
			"--alt-$boundary\r\n" .
1204
			"Content-Type: text/html; charset=UTF-8\r\n" .
1205
			"Content-Transfer-Encoding: 8bit\r\n" .
1206
			"\r\n" .
1207
			"Hello" .
1208
			"\r\n" .
1209
			"\r\n" .
1210
			"\r\n" .
1211
			"--alt-{$boundary}--\r\n" .
1212
			"\r\n" .
1213
			"--rel-$boundary\r\n" .
1214
			"Content-Type: application/octet-stream\r\n" .
1215
			"Content-Transfer-Encoding: base64\r\n" .
1216
			"Content-ID: <abc123>\r\n" .
1217
			"Content-Disposition: inline; filename=\"cake.png\"\r\n\r\n";
1218
		$this->assertContains($expected, $result['message']);
1219
		$this->assertContains('--rel-' . $boundary . '--', $result['message']);
1220
		$this->assertContains('--' . $boundary . '--', $result['message']);
1221
	}
1222
 
1223
/**
1224
 * Test setting inline attachments and HTML only messages.
1225
 *
1226
 * @return void
1227
 */
1228
	public function testSendWithInlineAttachmentsHtmlOnly() {
1229
		$this->CakeEmail->transport('debug');
1230
		$this->CakeEmail->from('cake@cakephp.org');
1231
		$this->CakeEmail->to('cake@cakephp.org');
1232
		$this->CakeEmail->subject('My title');
1233
		$this->CakeEmail->emailFormat('html');
1234
		$this->CakeEmail->attachments(array(
1235
			'cake.png' => array(
1236
				'file' => CAKE . 'VERSION.txt',
1237
				'contentId' => 'abc123'
1238
			)
1239
		));
1240
		$result = $this->CakeEmail->send('Hello');
1241
 
1242
		$boundary = $this->CakeEmail->getBoundary();
1243
		$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
1244
		$expected = "--$boundary\r\n" .
1245
			"Content-Type: multipart/related; boundary=\"rel-$boundary\"\r\n" .
1246
			"\r\n" .
1247
			"--rel-$boundary\r\n" .
1248
			"Content-Type: text/html; charset=UTF-8\r\n" .
1249
			"Content-Transfer-Encoding: 8bit\r\n" .
1250
			"\r\n" .
1251
			"Hello" .
1252
			"\r\n" .
1253
			"\r\n" .
1254
			"\r\n" .
1255
			"--rel-$boundary\r\n" .
1256
			"Content-Type: application/octet-stream\r\n" .
1257
			"Content-Transfer-Encoding: base64\r\n" .
1258
			"Content-ID: <abc123>\r\n" .
1259
			"Content-Disposition: inline; filename=\"cake.png\"\r\n\r\n";
1260
		$this->assertContains($expected, $result['message']);
1261
		$this->assertContains('--rel-' . $boundary . '--', $result['message']);
1262
		$this->assertContains('--' . $boundary . '--', $result['message']);
1263
	}
1264
 
1265
/**
1266
 * Test disabling content-disposition.
1267
 *
1268
 * @return void
1269
 */
1270
	public function testSendWithNoContentDispositionAttachments() {
1271
		$this->CakeEmail->transport('debug');
1272
		$this->CakeEmail->from('cake@cakephp.org');
1273
		$this->CakeEmail->to('cake@cakephp.org');
1274
		$this->CakeEmail->subject('My title');
1275
		$this->CakeEmail->emailFormat('text');
1276
		$this->CakeEmail->attachments(array(
1277
			'cake.png' => array(
1278
				'file' => CAKE . 'VERSION.txt',
1279
				'contentDisposition' => false
1280
			)
1281
		));
1282
		$result = $this->CakeEmail->send('Hello');
1283
 
1284
		$boundary = $this->CakeEmail->getBoundary();
1285
		$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
1286
		$expected = "--$boundary\r\n" .
1287
			"Content-Type: text/plain; charset=UTF-8\r\n" .
1288
			"Content-Transfer-Encoding: 8bit\r\n" .
1289
			"\r\n" .
1290
			"Hello" .
1291
			"\r\n" .
1292
			"\r\n" .
1293
			"\r\n" .
1294
			"--{$boundary}\r\n" .
1295
			"Content-Type: application/octet-stream\r\n" .
1296
			"Content-Transfer-Encoding: base64\r\n" .
1297
			"\r\n";
1298
 
1299
		$this->assertContains($expected, $result['message']);
1300
		$this->assertContains('--' . $boundary . '--', $result['message']);
1301
	}
1302
/**
1303
 * testSendWithLog method
1304
 *
1305
 * @return void
1306
 */
1307
	public function testSendWithLog() {
1308
		CakeLog::config('email', array(
1309
			'engine' => 'File',
1310
			'path' => TMP
1311
		));
1312
		CakeLog::drop('default');
1313
		$this->CakeEmail->transport('Debug');
1314
		$this->CakeEmail->to('me@cakephp.org');
1315
		$this->CakeEmail->from('cake@cakephp.org');
1316
		$this->CakeEmail->subject('My title');
1317
		$this->CakeEmail->config(array('log' => 'cake_test_emails'));
1318
		$result = $this->CakeEmail->send("Logging This");
1319
 
1320
		App::uses('File', 'Utility');
1321
		$File = new File(TMP . 'cake_test_emails.log');
1322
		$log = $File->read();
1323
		$this->assertTrue(strpos($log, $result['headers']) !== false);
1324
		$this->assertTrue(strpos($log, $result['message']) !== false);
1325
		$File->delete();
1326
		CakeLog::drop('email');
1327
	}
1328
 
1329
/**
1330
 * testSendWithLogAndScope method
1331
 *
1332
 * @return void
1333
 */
1334
	public function testSendWithLogAndScope() {
1335
		CakeLog::config('email', array(
1336
			'engine' => 'File',
1337
			'path' => TMP,
1338
			'types' => array('cake_test_emails'),
1339
			'scopes' => array('email')
1340
		));
1341
		CakeLog::drop('default');
1342
		$this->CakeEmail->transport('Debug');
1343
		$this->CakeEmail->to('me@cakephp.org');
1344
		$this->CakeEmail->from('cake@cakephp.org');
1345
		$this->CakeEmail->subject('My title');
1346
		$this->CakeEmail->config(array('log' => array('level' => 'cake_test_emails', 'scope' => 'email')));
1347
		$result = $this->CakeEmail->send("Logging This");
1348
 
1349
		App::uses('File', 'Utility');
1350
		$File = new File(TMP . 'cake_test_emails.log');
1351
		$log = $File->read();
1352
		$this->assertTrue(strpos($log, $result['headers']) !== false);
1353
		$this->assertTrue(strpos($log, $result['message']) !== false);
1354
		$File->delete();
1355
		CakeLog::drop('email');
1356
	}
1357
 
1358
/**
1359
 * testSendRender method
1360
 *
1361
 * @return void
1362
 */
1363
	public function testSendRender() {
1364
		$this->CakeEmail->reset();
1365
		$this->CakeEmail->transport('debug');
1366
 
1367
		$this->CakeEmail->from('cake@cakephp.org');
1368
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1369
		$this->CakeEmail->subject('My title');
1370
		$this->CakeEmail->config(array('empty'));
1371
		$this->CakeEmail->template('default', 'default');
1372
		$result = $this->CakeEmail->send();
1373
 
1374
		$this->assertContains('This email was sent using the CakePHP Framework', $result['message']);
1375
		$this->assertContains('Message-ID: ', $result['headers']);
1376
		$this->assertContains('To: ', $result['headers']);
1377
	}
1378
 
1379
/**
1380
 * test sending and rendering with no layout
1381
 *
1382
 * @return void
1383
 */
1384
	public function testSendRenderNoLayout() {
1385
		$this->CakeEmail->reset();
1386
		$this->CakeEmail->transport('debug');
1387
 
1388
		$this->CakeEmail->from('cake@cakephp.org');
1389
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1390
		$this->CakeEmail->subject('My title');
1391
		$this->CakeEmail->config(array('empty'));
1392
		$this->CakeEmail->template('default', null);
1393
		$result = $this->CakeEmail->send('message body.');
1394
 
1395
		$this->assertContains('message body.', $result['message']);
1396
		$this->assertNotContains('This email was sent using the CakePHP Framework', $result['message']);
1397
	}
1398
 
1399
/**
1400
 * testSendRender both method
1401
 *
1402
 * @return void
1403
 */
1404
	public function testSendRenderBoth() {
1405
		$this->CakeEmail->reset();
1406
		$this->CakeEmail->transport('debug');
1407
 
1408
		$this->CakeEmail->from('cake@cakephp.org');
1409
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1410
		$this->CakeEmail->subject('My title');
1411
		$this->CakeEmail->config(array('empty'));
1412
		$this->CakeEmail->template('default', 'default');
1413
		$this->CakeEmail->emailFormat('both');
1414
		$result = $this->CakeEmail->send();
1415
 
1416
		$this->assertContains('Message-ID: ', $result['headers']);
1417
		$this->assertContains('To: ', $result['headers']);
1418
 
1419
		$boundary = $this->CakeEmail->getBoundary();
1420
		$this->assertContains('Content-Type: multipart/alternative; boundary="' . $boundary . '"', $result['headers']);
1421
 
1422
		$expected = "--$boundary\r\n" .
1423
			"Content-Type: text/plain; charset=UTF-8\r\n" .
1424
			"Content-Transfer-Encoding: 8bit\r\n" .
1425
			"\r\n" .
1426
			"\r\n" .
1427
			"\r\n" .
1428
			"This email was sent using the CakePHP Framework, http://cakephp.org." .
1429
			"\r\n" .
1430
			"\r\n" .
1431
			"--$boundary\r\n" .
1432
			"Content-Type: text/html; charset=UTF-8\r\n" .
1433
			"Content-Transfer-Encoding: 8bit\r\n" .
1434
			"\r\n" .
1435
			"<!DOCTYPE html";
1436
		$this->assertStringStartsWith($expected, $result['message']);
1437
 
1438
		$expected = "</html>\r\n" .
1439
			"\r\n" .
1440
			"\r\n" .
1441
			"--$boundary--\r\n";
1442
		$this->assertStringEndsWith($expected, $result['message']);
1443
	}
1444
 
1445
/**
1446
 * testSendRender method for ISO-2022-JP
1447
 *
1448
 * @return void
1449
 */
1450
	public function testSendRenderJapanese() {
1451
		$this->skipIf(!function_exists('mb_convert_encoding'));
1452
 
1453
		$this->CakeEmail->reset();
1454
		$this->CakeEmail->transport('debug');
1455
 
1456
		$this->CakeEmail->from('cake@cakephp.org');
1457
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1458
		$this->CakeEmail->subject('My title');
1459
		$this->CakeEmail->config(array('empty'));
1460
		$this->CakeEmail->template('default', 'japanese');
1461
		$this->CakeEmail->charset = 'ISO-2022-JP';
1462
		$result = $this->CakeEmail->send();
1463
 
1464
		$expected = mb_convert_encoding('CakePHP Framework を使って送信したメールです。 http://cakephp.org.', 'ISO-2022-JP');
1465
		$this->assertContains($expected, $result['message']);
1466
		$this->assertContains('Message-ID: ', $result['headers']);
1467
		$this->assertContains('To: ', $result['headers']);
1468
	}
1469
 
1470
/**
1471
 * testSendRenderThemed method
1472
 *
1473
 * @return void
1474
 */
1475
	public function testSendRenderThemed() {
1476
		$this->CakeEmail->reset();
1477
		$this->CakeEmail->transport('debug');
1478
 
1479
		$this->CakeEmail->from('cake@cakephp.org');
1480
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1481
		$this->CakeEmail->subject('My title');
1482
		$this->CakeEmail->config(array('empty'));
1483
		$this->CakeEmail->theme('TestTheme');
1484
		$this->CakeEmail->template('themed', 'default');
1485
		$result = $this->CakeEmail->send();
1486
 
1487
		$this->assertContains('In TestTheme', $result['message']);
1488
		$this->assertContains('Message-ID: ', $result['headers']);
1489
		$this->assertContains('To: ', $result['headers']);
1490
		$this->assertContains('/theme/TestTheme/img/test.jpg', $result['message']);
1491
	}
1492
 
1493
/**
1494
 * testSendRenderWithHTML method and assert line length is kept below the required limit
1495
 *
1496
 * @return void
1497
 */
1498
	public function testSendRenderWithHTML() {
1499
		$this->CakeEmail->reset();
1500
		$this->CakeEmail->transport('debug');
1501
 
1502
		$this->CakeEmail->from('cake@cakephp.org');
1503
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1504
		$this->CakeEmail->subject('My title');
1505
		$this->CakeEmail->config(array('empty'));
1506
		$this->CakeEmail->emailFormat('html');
1507
		$this->CakeEmail->template('html', 'default');
1508
		$result = $this->CakeEmail->send();
1509
 
1510
		$this->assertTextContains('<h1>HTML Ipsum Presents</h1>', $result['message']);
1511
		$this->assertLineLengths($result['message']);
1512
	}
1513
 
1514
/**
1515
 * testSendRenderWithVars method
1516
 *
1517
 * @return void
1518
 */
1519
	public function testSendRenderWithVars() {
1520
		$this->CakeEmail->reset();
1521
		$this->CakeEmail->transport('debug');
1522
 
1523
		$this->CakeEmail->from('cake@cakephp.org');
1524
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1525
		$this->CakeEmail->subject('My title');
1526
		$this->CakeEmail->config(array('empty'));
1527
		$this->CakeEmail->template('custom', 'default');
1528
		$this->CakeEmail->viewVars(array('value' => 12345));
1529
		$result = $this->CakeEmail->send();
1530
 
1531
		$this->assertContains('Here is your value: 12345', $result['message']);
1532
	}
1533
 
1534
/**
1535
 * testSendRenderWithVars method for ISO-2022-JP
1536
 *
1537
 * @return void
1538
 */
1539
	public function testSendRenderWithVarsJapanese() {
1540
		$this->skipIf(!function_exists('mb_convert_encoding'));
1541
		$this->CakeEmail->reset();
1542
		$this->CakeEmail->transport('debug');
1543
 
1544
		$this->CakeEmail->from('cake@cakephp.org');
1545
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1546
		$this->CakeEmail->subject('My title');
1547
		$this->CakeEmail->config(array('empty'));
1548
		$this->CakeEmail->template('japanese', 'default');
1549
		$this->CakeEmail->viewVars(array('value' => '日本語の差し込み123'));
1550
		$this->CakeEmail->charset = 'ISO-2022-JP';
1551
		$result = $this->CakeEmail->send();
1552
 
1553
		$expected = mb_convert_encoding('ここにあなたの設定した値が入ります: 日本語の差し込み123', 'ISO-2022-JP');
1554
		$this->assertTrue((bool)strpos($result['message'], $expected));
1555
	}
1556
 
1557
/**
1558
 * testSendRenderWithHelpers method
1559
 *
1560
 * @return void
1561
 */
1562
	public function testSendRenderWithHelpers() {
1563
		$this->CakeEmail->reset();
1564
		$this->CakeEmail->transport('debug');
1565
 
1566
		$timestamp = time();
1567
		$this->CakeEmail->from('cake@cakephp.org');
1568
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1569
		$this->CakeEmail->subject('My title');
1570
		$this->CakeEmail->config(array('empty'));
1571
		$this->CakeEmail->template('custom_helper', 'default');
1572
		$this->CakeEmail->viewVars(array('time' => $timestamp));
1573
 
1574
		$result = $this->CakeEmail->helpers(array('Time'));
1575
		$this->assertInstanceOf('CakeEmail', $result);
1576
 
1577
		$result = $this->CakeEmail->send();
1578
		$this->assertTrue((bool)strpos($result['message'], 'Right now: ' . date('Y-m-d\TH:i:s\Z', $timestamp)));
1579
 
1580
		$result = $this->CakeEmail->helpers();
1581
		$this->assertEquals(array('Time'), $result);
1582
	}
1583
 
1584
/**
1585
 * testSendRenderWithImage method
1586
 *
1587
 * @return void
1588
 */
1589
	public function testSendRenderWithImage() {
1590
		$this->CakeEmail->reset();
1591
		$this->CakeEmail->transport('Debug');
1592
 
1593
		$this->CakeEmail->from('cake@cakephp.org');
1594
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1595
		$this->CakeEmail->subject('My title');
1596
		$this->CakeEmail->config(array('empty'));
1597
		$this->CakeEmail->template('image');
1598
		$this->CakeEmail->emailFormat('html');
1599
		$server = env('SERVER_NAME') ? env('SERVER_NAME') : 'localhost';
1600
 
1601
		if (env('SERVER_PORT') && env('SERVER_PORT') != 80) {
1602
			$server .= ':' . env('SERVER_PORT');
1603
		}
1604
 
1605
		$expected = '<img src="http://' . $server . '/img/image.gif" alt="cool image" width="100" height="100"/>';
1606
		$result = $this->CakeEmail->send();
1607
		$this->assertContains($expected, $result['message']);
1608
	}
1609
 
1610
/**
1611
 * testSendRenderPlugin method
1612
 *
1613
 * @return void
1614
 */
1615
	public function testSendRenderPlugin() {
1616
		App::build(array(
1617
			'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
1618
		));
1619
		CakePlugin::load(array('TestPlugin', 'TestPluginTwo'));
1620
 
1621
		$this->CakeEmail->reset();
1622
		$this->CakeEmail->transport('debug');
1623
		$this->CakeEmail->from('cake@cakephp.org');
1624
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1625
		$this->CakeEmail->subject('My title');
1626
		$this->CakeEmail->config(array('empty'));
1627
 
1628
		$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'default')->send();
1629
		$this->assertContains('Into TestPlugin.', $result['message']);
1630
		$this->assertContains('This email was sent using the CakePHP Framework', $result['message']);
1631
 
1632
		$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'TestPlugin.plug_default')->send();
1633
		$this->assertContains('Into TestPlugin.', $result['message']);
1634
		$this->assertContains('This email was sent using the TestPlugin.', $result['message']);
1635
 
1636
		$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'plug_default')->send();
1637
		$this->assertContains('Into TestPlugin.', $result['message']);
1638
		$this->assertContains('This email was sent using the TestPlugin.', $result['message']);
1639
 
1640
		$this->CakeEmail->template(
1641
			'TestPlugin.test_plugin_tpl',
1642
			'TestPluginTwo.default'
1643
		);
1644
		$result = $this->CakeEmail->send();
1645
		$this->assertContains('Into TestPlugin.', $result['message']);
1646
		$this->assertContains('This email was sent using TestPluginTwo.', $result['message']);
1647
 
1648
		// test plugin template overridden by theme
1649
		$this->CakeEmail->theme('TestTheme');
1650
		$result = $this->CakeEmail->send();
1651
 
1652
		$this->assertContains('Into TestPlugin. (themed)', $result['message']);
1653
 
1654
		$this->CakeEmail->viewVars(array('value' => 12345));
1655
		$result = $this->CakeEmail->template('custom', 'TestPlugin.plug_default')->send();
1656
		$this->assertContains('Here is your value: 12345', $result['message']);
1657
		$this->assertContains('This email was sent using the TestPlugin.', $result['message']);
1658
 
1659
		$this->setExpectedException('MissingViewException');
1660
		$this->CakeEmail->template('test_plugin_tpl', 'plug_default')->send();
1661
	}
1662
 
1663
/**
1664
 * testSendMultipleMIME method
1665
 *
1666
 * @return void
1667
 */
1668
	public function testSendMultipleMIME() {
1669
		$this->CakeEmail->reset();
1670
		$this->CakeEmail->transport('debug');
1671
 
1672
		$this->CakeEmail->from('cake@cakephp.org');
1673
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1674
		$this->CakeEmail->subject('My title');
1675
		$this->CakeEmail->template('custom', 'default');
1676
		$this->CakeEmail->config(array());
1677
		$this->CakeEmail->viewVars(array('value' => 12345));
1678
		$this->CakeEmail->emailFormat('both');
1679
		$this->CakeEmail->send();
1680
 
1681
		$message = $this->CakeEmail->message();
1682
		$boundary = $this->CakeEmail->getBoundary();
1683
		$this->assertFalse(empty($boundary));
1684
		$this->assertContains('--' . $boundary, $message);
1685
		$this->assertContains('--' . $boundary . '--', $message);
1686
 
1687
		$this->CakeEmail->attachments(array('fake.php' => __FILE__));
1688
		$this->CakeEmail->send();
1689
 
1690
		$message = $this->CakeEmail->message();
1691
		$boundary = $this->CakeEmail->getBoundary();
1692
		$this->assertFalse(empty($boundary));
1693
		$this->assertContains('--' . $boundary, $message);
1694
		$this->assertContains('--' . $boundary . '--', $message);
1695
		$this->assertContains('--alt-' . $boundary, $message);
1696
		$this->assertContains('--alt-' . $boundary . '--', $message);
1697
	}
1698
 
1699
/**
1700
 * testSendAttachment method
1701
 *
1702
 * @return void
1703
 */
1704
	public function testSendAttachment() {
1705
		$this->CakeEmail->reset();
1706
		$this->CakeEmail->transport('debug');
1707
		$this->CakeEmail->from('cake@cakephp.org');
1708
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1709
		$this->CakeEmail->subject('My title');
1710
		$this->CakeEmail->config(array());
1711
		$this->CakeEmail->attachments(array(CAKE . 'basics.php'));
1712
		$result = $this->CakeEmail->send('body');
1713
		$this->assertContains("Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"basics.php\"", $result['message']);
1714
 
1715
		$this->CakeEmail->attachments(array('my.file.txt' => CAKE . 'basics.php'));
1716
		$result = $this->CakeEmail->send('body');
1717
		$this->assertContains("Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\"", $result['message']);
1718
 
1719
		$this->CakeEmail->attachments(array('file.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
1720
		$result = $this->CakeEmail->send('body');
1721
		$this->assertContains("Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\"", $result['message']);
1722
 
1723
		$this->CakeEmail->attachments(array('file2.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1')));
1724
		$result = $this->CakeEmail->send('body');
1725
		$this->assertContains("Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: <a1b1c1>\r\nContent-Disposition: inline; filename=\"file2.txt\"", $result['message']);
1726
	}
1727
 
1728
/**
1729
 * testDeliver method
1730
 *
1731
 * @return void
1732
 */
1733
	public function testDeliver() {
1734
		$instance = CakeEmail::deliver('all@cakephp.org', 'About', 'Everything ok', array('from' => 'root@cakephp.org'), false);
1735
		$this->assertInstanceOf('CakeEmail', $instance);
1736
		$this->assertSame($instance->to(), array('all@cakephp.org' => 'all@cakephp.org'));
1737
		$this->assertSame($instance->subject(), 'About');
1738
		$this->assertSame($instance->from(), array('root@cakephp.org' => 'root@cakephp.org'));
1739
 
1740
		$config = array(
1741
			'from' => 'cake@cakephp.org',
1742
			'to' => 'debug@cakephp.org',
1743
			'subject' => 'Update ok',
1744
			'template' => 'custom',
1745
			'layout' => 'custom_layout',
1746
			'viewVars' => array('value' => 123),
1747
			'cc' => array('cake@cakephp.org' => 'Myself')
1748
		);
1749
		$instance = CakeEmail::deliver(null, null, array('name' => 'CakePHP'), $config, false);
1750
		$this->assertSame($instance->from(), array('cake@cakephp.org' => 'cake@cakephp.org'));
1751
		$this->assertSame($instance->to(), array('debug@cakephp.org' => 'debug@cakephp.org'));
1752
		$this->assertSame($instance->subject(), 'Update ok');
1753
		$this->assertSame($instance->template(), array('template' => 'custom', 'layout' => 'custom_layout'));
1754
		$this->assertSame($instance->viewVars(), array('value' => 123, 'name' => 'CakePHP'));
1755
		$this->assertSame($instance->cc(), array('cake@cakephp.org' => 'Myself'));
1756
 
1757
		$configs = array('from' => 'root@cakephp.org', 'message' => 'Message from configs', 'transport' => 'Debug');
1758
		$instance = CakeEmail::deliver('all@cakephp.org', 'About', null, $configs, true);
1759
		$message = $instance->message();
1760
		$this->assertEquals($configs['message'], $message[0]);
1761
	}
1762
 
1763
/**
1764
 * testMessage method
1765
 *
1766
 * @return void
1767
 */
1768
	public function testMessage() {
1769
		$this->CakeEmail->reset();
1770
		$this->CakeEmail->transport('debug');
1771
		$this->CakeEmail->from('cake@cakephp.org');
1772
		$this->CakeEmail->to(array('you@cakephp.org' => 'You'));
1773
		$this->CakeEmail->subject('My title');
1774
		$this->CakeEmail->config(array('empty'));
1775
		$this->CakeEmail->template('default', 'default');
1776
		$this->CakeEmail->emailFormat('both');
1777
		$this->CakeEmail->send();
1778
 
1779
		$expected = '<p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>';
1780
		$this->assertContains($expected, $this->CakeEmail->message(CakeEmail::MESSAGE_HTML));
1781
 
1782
		$expected = 'This email was sent using the CakePHP Framework, http://cakephp.org.';
1783
		$this->assertContains($expected, $this->CakeEmail->message(CakeEmail::MESSAGE_TEXT));
1784
 
1785
		$message = $this->CakeEmail->message();
1786
		$this->assertContains('Content-Type: text/plain; charset=UTF-8', $message);
1787
		$this->assertContains('Content-Type: text/html; charset=UTF-8', $message);
1788
 
1789
		// UTF-8 is 8bit
1790
		$this->assertTrue($this->_checkContentTransferEncoding($message, '8bit'));
1791
 
1792
		$this->CakeEmail->charset = 'ISO-2022-JP';
1793
		$this->CakeEmail->send();
1794
		$message = $this->CakeEmail->message();
1795
		$this->assertContains('Content-Type: text/plain; charset=ISO-2022-JP', $message);
1796
		$this->assertContains('Content-Type: text/html; charset=ISO-2022-JP', $message);
1797
 
1798
		// ISO-2022-JP is 7bit
1799
		$this->assertTrue($this->_checkContentTransferEncoding($message, '7bit'));
1800
	}
1801
 
1802
/**
1803
 * testReset method
1804
 *
1805
 * @return void
1806
 */
1807
	public function testReset() {
1808
		$this->CakeEmail->to('cake@cakephp.org');
1809
		$this->CakeEmail->theme('TestTheme');
1810
		$this->CakeEmail->emailPattern('/.+@.+\..+/i');
1811
		$this->assertSame(array('cake@cakephp.org' => 'cake@cakephp.org'), $this->CakeEmail->to());
1812
 
1813
		$this->CakeEmail->reset();
1814
		$this->assertSame(array(), $this->CakeEmail->to());
1815
		$this->assertNull($this->CakeEmail->theme());
1816
		$this->assertSame(CakeEmail::EMAIL_PATTERN, $this->CakeEmail->emailPattern());
1817
	}
1818
 
1819
/**
1820
 * testReset with charset
1821
 *
1822
 * @return void
1823
 */
1824
	public function testResetWithCharset() {
1825
		$this->CakeEmail->charset = 'ISO-2022-JP';
1826
		$this->CakeEmail->reset();
1827
 
1828
		$this->assertSame('utf-8', $this->CakeEmail->charset, $this->CakeEmail->charset);
1829
		$this->assertNull($this->CakeEmail->headerCharset, $this->CakeEmail->headerCharset);
1830
	}
1831
 
1832
/**
1833
 * testWrap method
1834
 *
1835
 * @return void
1836
 */
1837
	public function testWrap() {
1838
		$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
1839
		$result = $this->CakeEmail->wrap($text, CakeEmail::LINE_LENGTH_SHOULD);
1840
		$expected = array(
1841
			'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac turpis orci,',
1842
			'non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.',
1843
			''
1844
		);
1845
		$this->assertSame($expected, $result);
1846
 
1847
		$text = 'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan amet.';
1848
		$result = $this->CakeEmail->wrap($text, CakeEmail::LINE_LENGTH_SHOULD);
1849
		$expected = array(
1850
			'Lorem ipsum dolor sit amet, consectetur < adipiscing elit. Donec ac turpis',
1851
			'orci, non commodo odio. Morbi nibh nisi, vehicula > pellentesque accumsan',
1852
			'amet.',
1853
			''
1854
		);
1855
		$this->assertSame($expected, $result);
1856
 
1857
		$text = '<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula pellentesque accumsan amet.<hr></p>';
1858
		$result = $this->CakeEmail->wrap($text, CakeEmail::LINE_LENGTH_SHOULD);
1859
		$expected = array(
1860
			'<p>Lorem ipsum dolor sit amet,<br> consectetur adipiscing elit.<br> Donec ac',
1861
			'turpis orci, non <b>commodo</b> odio. <br /> Morbi nibh nisi, vehicula',
1862
			'pellentesque accumsan amet.<hr></p>',
1863
			''
1864
		);
1865
		$this->assertSame($expected, $result);
1866
 
1867
		$text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac <a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh nisi, vehicula pellentesque accumsan amet.';
1868
		$result = $this->CakeEmail->wrap($text, CakeEmail::LINE_LENGTH_SHOULD);
1869
		$expected = array(
1870
			'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ac',
1871
			'<a href="http://cakephp.org">turpis</a> orci, non commodo odio. Morbi nibh',
1872
			'nisi, vehicula pellentesque accumsan amet.',
1873
			''
1874
		);
1875
		$this->assertSame($expected, $result);
1876
 
1877
		$text = 'Lorem ipsum <a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">ok</a>';
1878
		$result = $this->CakeEmail->wrap($text, CakeEmail::LINE_LENGTH_SHOULD);
1879
		$expected = array(
1880
			'Lorem ipsum',
1881
			'<a href="http://www.cakephp.org/controller/action/param1/param2" class="nice cool fine amazing awesome">',
1882
			'ok</a>',
1883
			''
1884
		);
1885
		$this->assertSame($expected, $result);
1886
 
1887
		$text = 'Lorem ipsum withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite ok.';
1888
		$result = $this->CakeEmail->wrap($text, CakeEmail::LINE_LENGTH_SHOULD);
1889
		$expected = array(
1890
			'Lorem ipsum',
1891
			'withonewordverybigMorethanthelineshouldsizeofrfcspecificationbyieeeavailableonieeesite',
1892
			'ok.',
1893
			''
1894
		);
1895
		$this->assertSame($expected, $result);
1896
	}
1897
 
1898
/**
1899
 * testRender method
1900
 *
1901
 * @return void
1902
 */
1903
	public function testRenderWithLayoutAndAttachment() {
1904
		$this->CakeEmail->emailFormat('html');
1905
		$this->CakeEmail->template('html', 'default');
1906
		$this->CakeEmail->attachments(array(CAKE . 'basics.php'));
1907
		$result = $this->CakeEmail->render(array());
1908
		$this->assertNotEmpty($result);
1909
 
1910
		$result = $this->CakeEmail->getBoundary();
1911
		$this->assertNotEmpty($result);
1912
	}
1913
 
1914
/**
1915
 * testConstructWithConfigArray method
1916
 *
1917
 * @return void
1918
 */
1919
	public function testConstructWithConfigArray() {
1920
		$configs = array(
1921
			'from' => array('some@example.com' => 'My website'),
1922
			'to' => 'test@example.com',
1923
			'subject' => 'Test mail subject',
1924
			'transport' => 'Debug',
1925
		);
1926
		$this->CakeEmail = new CakeEmail($configs);
1927
 
1928
		$result = $this->CakeEmail->to();
1929
		$this->assertEquals(array($configs['to'] => $configs['to']), $result);
1930
 
1931
		$result = $this->CakeEmail->from();
1932
		$this->assertEquals($configs['from'], $result);
1933
 
1934
		$result = $this->CakeEmail->subject();
1935
		$this->assertEquals($configs['subject'], $result);
1936
 
1937
		$result = $this->CakeEmail->transport();
1938
		$this->assertEquals($configs['transport'], $result);
1939
 
1940
		$result = $this->CakeEmail->transportClass();
1941
		$this->assertTrue($result instanceof DebugTransport);
1942
 
1943
		$result = $this->CakeEmail->send('This is the message');
1944
 
1945
		$this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
1946
		$this->assertTrue((bool)strpos($result['headers'], 'To: '));
1947
	}
1948
 
1949
/**
1950
 * testConfigArrayWithLayoutWithoutTemplate method
1951
 *
1952
 * @return void
1953
 */
1954
	public function testConfigArrayWithLayoutWithoutTemplate() {
1955
		$configs = array(
1956
			'from' => array('some@example.com' => 'My website'),
1957
			'to' => 'test@example.com',
1958
			'subject' => 'Test mail subject',
1959
			'transport' => 'Debug',
1960
			'layout' => 'custom'
1961
		);
1962
		$this->CakeEmail = new CakeEmail($configs);
1963
 
1964
		$result = $this->CakeEmail->template();
1965
		$this->assertEquals('', $result['template']);
1966
		$this->assertEquals($configs['layout'], $result['layout']);
1967
	}
1968
 
1969
/**
1970
 * testConstructWithConfigString method
1971
 *
1972
 * @return void
1973
 */
1974
	public function testConstructWithConfigString() {
1975
		$configs = new TestEmailConfig();
1976
		$this->CakeEmail = new TestCakeEmail('test');
1977
 
1978
		$result = $this->CakeEmail->to();
1979
		$this->assertEquals($configs->test['to'], $result);
1980
 
1981
		$result = $this->CakeEmail->from();
1982
		$this->assertEquals($configs->test['from'], $result);
1983
 
1984
		$result = $this->CakeEmail->subject();
1985
		$this->assertEquals($configs->test['subject'], $result);
1986
 
1987
		$result = $this->CakeEmail->transport();
1988
		$this->assertEquals($configs->test['transport'], $result);
1989
 
1990
		$result = $this->CakeEmail->transportClass();
1991
		$this->assertTrue($result instanceof DebugTransport);
1992
 
1993
		$result = $this->CakeEmail->send('This is the message');
1994
 
1995
		$this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
1996
		$this->assertTrue((bool)strpos($result['headers'], 'To: '));
1997
	}
1998
 
1999
/**
2000
 * testViewRender method
2001
 *
2002
 * @return void
2003
 */
2004
	public function testViewRender() {
2005
		$result = $this->CakeEmail->viewRender();
2006
		$this->assertEquals('View', $result);
2007
 
2008
		$result = $this->CakeEmail->viewRender('Theme');
2009
		$this->assertInstanceOf('CakeEmail', $result);
2010
 
2011
		$result = $this->CakeEmail->viewRender();
2012
		$this->assertEquals('Theme', $result);
2013
	}
2014
 
2015
/**
2016
 * testEmailFormat method
2017
 *
2018
 * @return void
2019
 */
2020
	public function testEmailFormat() {
2021
		$result = $this->CakeEmail->emailFormat();
2022
		$this->assertEquals('text', $result);
2023
 
2024
		$result = $this->CakeEmail->emailFormat('html');
2025
		$this->assertInstanceOf('CakeEmail', $result);
2026
 
2027
		$result = $this->CakeEmail->emailFormat();
2028
		$this->assertEquals('html', $result);
2029
 
2030
		$this->setExpectedException('SocketException');
2031
		$result = $this->CakeEmail->emailFormat('invalid');
2032
	}
2033
 
2034
/**
2035
 * Tests that it is possible to add charset configuration to a CakeEmail object
2036
 *
2037
 * @return void
2038
 */
2039
	public function testConfigCharset() {
2040
		$email = new CakeEmail();
2041
		$this->assertEquals(Configure::read('App.encoding'), $email->charset);
2042
		$this->assertEquals(Configure::read('App.encoding'), $email->headerCharset);
2043
 
2044
		$email = new CakeEmail(array('charset' => 'iso-2022-jp', 'headerCharset' => 'iso-2022-jp-ms'));
2045
		$this->assertEquals('iso-2022-jp', $email->charset);
2046
		$this->assertEquals('iso-2022-jp-ms', $email->headerCharset);
2047
 
2048
		$email = new CakeEmail(array('charset' => 'iso-2022-jp'));
2049
		$this->assertEquals('iso-2022-jp', $email->charset);
2050
		$this->assertEquals('iso-2022-jp', $email->headerCharset);
2051
 
2052
		$email = new CakeEmail(array('headerCharset' => 'iso-2022-jp-ms'));
2053
		$this->assertEquals(Configure::read('App.encoding'), $email->charset);
2054
		$this->assertEquals('iso-2022-jp-ms', $email->headerCharset);
2055
	}
2056
 
2057
/**
2058
 * Tests that the header is encoded using the configured headerCharset
2059
 *
2060
 * @return void
2061
 */
2062
	public function testHeaderEncoding() {
2063
		$this->skipIf(!function_exists('mb_convert_encoding'));
2064
		$email = new CakeEmail(array('headerCharset' => 'iso-2022-jp-ms', 'transport' => 'Debug'));
2065
		$email->subject('あれ?もしかしての前と');
2066
		$headers = $email->getHeaders(array('subject'));
2067
		$expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
2068
		$this->assertContains($expected, $headers['Subject']);
2069
 
2070
		$email->to('someone@example.com')->from('someone@example.com');
2071
		$result = $email->send('ってテーブルを作ってやってたらう');
2072
		$this->assertContains('ってテーブルを作ってやってたらう', $result['message']);
2073
	}
2074
 
2075
/**
2076
 * Tests that the body is encoded using the configured charset
2077
 *
2078
 * @return void
2079
 */
2080
	public function testBodyEncoding() {
2081
		$this->skipIf(!function_exists('mb_convert_encoding'));
2082
		$email = new CakeEmail(array(
2083
			'charset' => 'iso-2022-jp',
2084
			'headerCharset' => 'iso-2022-jp-ms',
2085
			'transport' => 'Debug'
2086
		));
2087
		$email->subject('あれ?もしかしての前と');
2088
		$headers = $email->getHeaders(array('subject'));
2089
		$expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
2090
		$this->assertContains($expected, $headers['Subject']);
2091
 
2092
		$email->to('someone@example.com')->from('someone@example.com');
2093
		$result = $email->send('ってテーブルを作ってやってたらう');
2094
		$this->assertContains('Content-Type: text/plain; charset=ISO-2022-JP', $result['headers']);
2095
		$this->assertContains(mb_convert_encoding('ってテーブルを作ってやってたらう', 'ISO-2022-JP'), $result['message']);
2096
	}
2097
 
2098
/**
2099
 * Tests that the body is encoded using the configured charset (Japanese standard encoding)
2100
 *
2101
 * @return void
2102
 */
2103
	public function testBodyEncodingIso2022Jp() {
2104
		$this->skipIf(!function_exists('mb_convert_encoding'));
2105
		$email = new CakeEmail(array(
2106
			'charset' => 'iso-2022-jp',
2107
			'headerCharset' => 'iso-2022-jp',
2108
			'transport' => 'Debug'
2109
		));
2110
		$email->subject('あれ?もしかしての前と');
2111
		$headers = $email->getHeaders(array('subject'));
2112
		$expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
2113
		$this->assertContains($expected, $headers['Subject']);
2114
 
2115
		$email->to('someone@example.com')->from('someone@example.com');
2116
		$result = $email->send('①㈱');
2117
		$this->assertTextContains("Content-Type: text/plain; charset=ISO-2022-JP", $result['headers']);
2118
		$this->assertTextNotContains("Content-Type: text/plain; charset=ISO-2022-JP-MS", $result['headers']); // not charset=iso-2022-jp-ms
2119
		$this->assertTextNotContains(mb_convert_encoding('①㈱', 'ISO-2022-JP-MS'), $result['message']);
2120
	}
2121
 
2122
/**
2123
 * Tests that the body is encoded using the configured charset (Japanese irregular encoding, but sometime use this)
2124
 *
2125
 * @return void
2126
 */
2127
	public function testBodyEncodingIso2022JpMs() {
2128
		$this->skipIf(!function_exists('mb_convert_encoding'));
2129
		$email = new CakeEmail(array(
2130
			'charset' => 'iso-2022-jp-ms',
2131
			'headerCharset' => 'iso-2022-jp-ms',
2132
			'transport' => 'Debug'
2133
		));
2134
		$email->subject('あれ?もしかしての前と');
2135
		$headers = $email->getHeaders(array('subject'));
2136
		$expected = "?ISO-2022-JP?B?GyRCJCIkbCEpJGIkNyQrJDckRiROQTAkSBsoQg==?=";
2137
		$this->assertContains($expected, $headers['Subject']);
2138
 
2139
		$email->to('someone@example.com')->from('someone@example.com');
2140
		$result = $email->send('①㈱');
2141
		$this->assertTextContains("Content-Type: text/plain; charset=ISO-2022-JP", $result['headers']);
2142
		$this->assertTextNotContains("Content-Type: text/plain; charset=iso-2022-jp-ms", $result['headers']); // not charset=iso-2022-jp-ms
2143
		$this->assertContains(mb_convert_encoding('①㈱', 'ISO-2022-JP-MS'), $result['message']);
2144
	}
2145
 
2146
	protected function _checkContentTransferEncoding($message, $charset) {
2147
		$boundary = '--' . $this->CakeEmail->getBoundary();
2148
		$result['text'] = false;
2149
		$result['html'] = false;
2150
		$length = count($message);
2151
		for ($i = 0; $i < $length; ++$i) {
2152
			if ($message[$i] === $boundary) {
2153
				$flag = false;
2154
				$type = '';
2155
				while (!preg_match('/^$/', $message[$i])) {
2156
					if (preg_match('/^Content-Type: text\/plain/', $message[$i])) {
2157
						$type = 'text';
2158
					}
2159
					if (preg_match('/^Content-Type: text\/html/', $message[$i])) {
2160
						$type = 'html';
2161
					}
2162
					if ($message[$i] === 'Content-Transfer-Encoding: ' . $charset) {
2163
						$flag = true;
2164
					}
2165
					++$i;
2166
				}
2167
				$result[$type] = $flag;
2168
			}
2169
		}
2170
		return $result['text'] && $result['html'];
2171
	}
2172
 
2173
/**
2174
 * Test CakeEmail::_encode function
2175
 *
2176
 * @return void
2177
 */
2178
	public function testEncode() {
2179
		$this->skipIf(!function_exists('mb_convert_encoding'));
2180
 
2181
		$this->CakeEmail->headerCharset = 'ISO-2022-JP';
2182
		$result = $this->CakeEmail->encode('日本語');
2183
		$expected = '=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?=';
2184
		$this->assertSame($expected, $result);
2185
 
2186
		$this->CakeEmail->headerCharset = 'ISO-2022-JP';
2187
		$result = $this->CakeEmail->encode('長い長い長いSubjectの場合はfoldingするのが正しいんだけどいったいどうなるんだろう?');
2188
		$expected = "=?ISO-2022-JP?B?GyRCRDkkJEQ5JCREOSQkGyhCU3ViamVjdBskQiROPmw5ZyRPGyhCZm9s?=\r\n" .
2189
			" =?ISO-2022-JP?B?ZGluZxskQiQ5JGskTiQsQDUkNyQkJHMkQCQxJEkkJCRDJD8kJCRJGyhC?=\r\n" .
2190
			" =?ISO-2022-JP?B?GyRCJCYkSiRrJHMkQCRtJCYhKRsoQg==?=";
2191
		$this->assertSame($expected, $result);
2192
	}
2193
 
2194
/**
2195
 * Tests charset setter/getter
2196
 *
2197
 * @return void
2198
 */
2199
	public function testCharset() {
2200
		$this->CakeEmail->charset('UTF-8');
2201
		$this->assertSame($this->CakeEmail->charset(), 'UTF-8');
2202
 
2203
		$this->CakeEmail->charset('ISO-2022-JP');
2204
		$this->assertSame($this->CakeEmail->charset(), 'ISO-2022-JP');
2205
 
2206
		$charset = $this->CakeEmail->charset('Shift_JIS');
2207
		$this->assertSame($charset, 'Shift_JIS');
2208
	}
2209
 
2210
/**
2211
 * Tests headerCharset setter/getter
2212
 *
2213
 * @return void
2214
 */
2215
	public function testHeaderCharset() {
2216
		$this->CakeEmail->headerCharset('UTF-8');
2217
		$this->assertSame($this->CakeEmail->headerCharset(), 'UTF-8');
2218
 
2219
		$this->CakeEmail->headerCharset('ISO-2022-JP');
2220
		$this->assertSame($this->CakeEmail->headerCharset(), 'ISO-2022-JP');
2221
 
2222
		$charset = $this->CakeEmail->headerCharset('Shift_JIS');
2223
		$this->assertSame($charset, 'Shift_JIS');
2224
	}
2225
 
2226
/**
2227
 * Tests for compatible check.
2228
 *          charset property and       charset() method.
2229
 *    headerCharset property and headerCharset() method.
2230
 *
2231
 * @return void
2232
 */
2233
	public function testCharsetsCompatible() {
2234
		$this->skipIf(!function_exists('mb_convert_encoding'));
2235
 
2236
		$checkHeaders = array(
2237
			'from' => true,
2238
			'to' => true,
2239
			'cc' => true,
2240
			'subject' => true,
2241
		);
2242
 
2243
		// Header Charset : null (used by default UTF-8)
2244
		//   Body Charset : ISO-2022-JP
2245
		$oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', null);
2246
		$oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);
2247
 
2248
		$newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', null);
2249
		$newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);
2250
 
2251
		$this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
2252
		$this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
2253
		$this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
2254
		$this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
2255
 
2256
		// Header Charset : UTF-8
2257
		//   Boby Charset : ISO-2022-JP
2258
		$oldStyleEmail = $this->_getEmailByOldStyleCharset('iso-2022-jp', 'utf-8');
2259
		$oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);
2260
 
2261
		$newStyleEmail = $this->_getEmailByNewStyleCharset('iso-2022-jp', 'utf-8');
2262
		$newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);
2263
 
2264
		$this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
2265
		$this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
2266
		$this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
2267
		$this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
2268
 
2269
		// Header Charset : ISO-2022-JP
2270
		//   Boby Charset : UTF-8
2271
		$oldStyleEmail = $this->_getEmailByOldStyleCharset('utf-8', 'iso-2022-jp');
2272
		$oldStyleHeaders = $oldStyleEmail->getHeaders($checkHeaders);
2273
 
2274
		$newStyleEmail = $this->_getEmailByNewStyleCharset('utf-8', 'iso-2022-jp');
2275
		$newStyleHeaders = $newStyleEmail->getHeaders($checkHeaders);
2276
 
2277
		$this->assertSame($oldStyleHeaders['From'], $newStyleHeaders['From']);
2278
		$this->assertSame($oldStyleHeaders['To'], $newStyleHeaders['To']);
2279
		$this->assertSame($oldStyleHeaders['Cc'], $newStyleHeaders['Cc']);
2280
		$this->assertSame($oldStyleHeaders['Subject'], $newStyleHeaders['Subject']);
2281
	}
2282
 
2283
/**
2284
 * @param mixed $charset
2285
 * @param mixed $headerCharset
2286
 * @return CakeEmail
2287
 */
2288
	protected function _getEmailByOldStyleCharset($charset, $headerCharset) {
2289
		$email = new CakeEmail(array('transport' => 'Debug'));
2290
 
2291
		if (! empty($charset)) {
2292
			$email->charset = $charset;
2293
		}
2294
		if (! empty($headerCharset)) {
2295
			$email->headerCharset = $headerCharset;
2296
		}
2297
 
2298
		$email->from('someone@example.com', 'どこかの誰か');
2299
		$email->to('someperson@example.jp', 'どこかのどなたか');
2300
		$email->cc('miku@example.net', 'ミク');
2301
		$email->subject('テストメール');
2302
		$email->send('テストメールの本文');
2303
 
2304
		return $email;
2305
	}
2306
 
2307
/**
2308
 * @param mixed $charset
2309
 * @param mixed $headerCharset
2310
 * @return CakeEmail
2311
 */
2312
	protected function _getEmailByNewStyleCharset($charset, $headerCharset) {
2313
		$email = new CakeEmail(array('transport' => 'Debug'));
2314
 
2315
		if (! empty($charset)) {
2316
			$email->charset($charset);
2317
		}
2318
		if (! empty($headerCharset)) {
2319
			$email->headerCharset($headerCharset);
2320
		}
2321
 
2322
		$email->from('someone@example.com', 'どこかの誰か');
2323
		$email->to('someperson@example.jp', 'どこかのどなたか');
2324
		$email->cc('miku@example.net', 'ミク');
2325
		$email->subject('テストメール');
2326
		$email->send('テストメールの本文');
2327
 
2328
		return $email;
2329
	}
2330
 
2331
/**
2332
 * testWrapLongLine()
2333
 *
2334
 * @return void
2335
 */
2336
	public function testWrapLongLine() {
2337
		$message = '<a href="http://cakephp.org">' . str_repeat('x', CakeEmail::LINE_LENGTH_MUST) . "</a>";
2338
 
2339
		$this->CakeEmail->reset();
2340
		$this->CakeEmail->transport('Debug');
2341
		$this->CakeEmail->from('cake@cakephp.org');
2342
		$this->CakeEmail->to('cake@cakephp.org');
2343
		$this->CakeEmail->subject('Wordwrap Test');
2344
		$this->CakeEmail->config(array('empty'));
2345
		$result = $this->CakeEmail->send($message);
2346
		$expected = "<a\r\n" . 'href="http://cakephp.org">' . str_repeat('x', CakeEmail::LINE_LENGTH_MUST - 26) . "\r\n" .
2347
			str_repeat('x', 26) . "\r\n</a>\r\n\r\n";
2348
		$this->assertEquals($expected, $result['message']);
2349
		$this->assertLineLengths($result['message']);
2350
 
2351
		$str1 = "a ";
2352
		$str2 = " b";
2353
		$length = strlen($str1) + strlen($str2);
2354
		$message = $str1 . str_repeat('x', CakeEmail::LINE_LENGTH_MUST - $length - 1) . $str2;
2355
 
2356
		$result = $this->CakeEmail->send($message);
2357
		$expected = "{$message}\r\n\r\n";
2358
		$this->assertEquals($expected, $result['message']);
2359
		$this->assertLineLengths($result['message']);
2360
 
2361
		$message = $str1 . str_repeat('x', CakeEmail::LINE_LENGTH_MUST - $length) . $str2;
2362
 
2363
		$result = $this->CakeEmail->send($message);
2364
		$expected = "{$message}\r\n\r\n";
2365
		$this->assertEquals($expected, $result['message']);
2366
		$this->assertLineLengths($result['message']);
2367
 
2368
		$message = $str1 . str_repeat('x', CakeEmail::LINE_LENGTH_MUST - $length + 1) . $str2;
2369
 
2370
		$result = $this->CakeEmail->send($message);
2371
		$expected = $str1 . str_repeat('x', CakeEmail::LINE_LENGTH_MUST - $length + 1) . sprintf("\r\n%s\r\n\r\n", trim($str2));
2372
		$this->assertEquals($expected, $result['message']);
2373
		$this->assertLineLengths($result['message']);
2374
	}
2375
 
2376
/**
2377
 * testWrapWithTagsAcrossLines()
2378
 *
2379
 * @return void
2380
 */
2381
	public function testWrapWithTagsAcrossLines() {
2382
		$str = <<<HTML
2383
<table>
2384
<th align="right" valign="top"
2385
        style="font-weight: bold">The tag is across multiple lines</th>
2386
</table>
2387
HTML;
2388
		$length = strlen($str);
2389
		$message = $str . str_repeat('x', CakeEmail::LINE_LENGTH_MUST + 1);
2390
 
2391
		$this->CakeEmail->reset();
2392
		$this->CakeEmail->transport('Debug');
2393
		$this->CakeEmail->from('cake@cakephp.org');
2394
		$this->CakeEmail->to('cake@cakephp.org');
2395
		$this->CakeEmail->subject('Wordwrap Test');
2396
		$this->CakeEmail->config(array('empty'));
2397
		$result = $this->CakeEmail->send($message);
2398
		$message = str_replace("\r\n", "\n", substr($message, 0, -9));
2399
		$message = str_replace("\n", "\r\n", $message);
2400
		$expected = "{$message}\r\nxxxxxxxxx\r\n\r\n";
2401
		$this->assertEquals($expected, $result['message']);
2402
		$this->assertLineLengths($result['message']);
2403
	}
2404
 
2405
/**
2406
 * CakeEmailTest::testWrapIncludeLessThanSign()
2407
 *
2408
 * @return void
2409
 */
2410
	public function testWrapIncludeLessThanSign() {
2411
		$str = 'foo<bar';
2412
		$length = strlen($str);
2413
		$message = $str . str_repeat('x', CakeEmail::LINE_LENGTH_MUST - $length + 1);
2414
 
2415
		$this->CakeEmail->reset();
2416
		$this->CakeEmail->transport('Debug');
2417
		$this->CakeEmail->from('cake@cakephp.org');
2418
		$this->CakeEmail->to('cake@cakephp.org');
2419
		$this->CakeEmail->subject('Wordwrap Test');
2420
		$this->CakeEmail->config(array('empty'));
2421
		$result = $this->CakeEmail->send($message);
2422
		$message = substr($message, 0, -1);
2423
		$expected = "{$message}\r\nx\r\n\r\n";
2424
		$this->assertEquals($expected, $result['message']);
2425
		$this->assertLineLengths($result['message']);
2426
	}
2427
 
2428
/**
2429
 * CakeEmailTest::testWrapForJapaneseEncoding()
2430
 *
2431
 * @return void
2432
 */
2433
	public function testWrapForJapaneseEncoding() {
2434
		$this->skipIf(!function_exists('mb_convert_encoding'));
2435
 
2436
		$message = mb_convert_encoding('受け付けました', 'iso-2022-jp', 'UTF-8');
2437
 
2438
		$this->CakeEmail->reset();
2439
		$this->CakeEmail->transport('Debug');
2440
		$this->CakeEmail->from('cake@cakephp.org');
2441
		$this->CakeEmail->to('cake@cakephp.org');
2442
		$this->CakeEmail->subject('Wordwrap Test');
2443
		$this->CakeEmail->config(array('empty'));
2444
		$this->CakeEmail->charset('iso-2022-jp');
2445
		$this->CakeEmail->headerCharset('iso-2022-jp');
2446
		$result = $this->CakeEmail->send($message);
2447
		$expected = "{$message}\r\n\r\n";
2448
		$this->assertEquals($expected, $result['message']);
2449
	}
2450
 
2451
/**
2452
 * testZeroOnlyLinesNotBeingEmptied()
2453
 *
2454
 * @return void
2455
 */
2456
	public function testZeroOnlyLinesNotBeingEmptied() {
2457
		$message = "Lorem\r\n0\r\n0\r\nipsum";
2458
 
2459
		$this->CakeEmail->reset();
2460
		$this->CakeEmail->transport('Debug');
2461
		$this->CakeEmail->from('cake@cakephp.org');
2462
		$this->CakeEmail->to('cake@cakephp.org');
2463
		$this->CakeEmail->subject('Wordwrap Test');
2464
		$this->CakeEmail->config(array('empty'));
2465
		$result = $this->CakeEmail->send($message);
2466
		$expected = "{$message}\r\n\r\n";
2467
		$this->assertEquals($expected, $result['message']);
2468
	}
2469
 
2470
/**
2471
 * Test that really long lines don't cause errors.
2472
 *
2473
 * @return void
2474
 */
2475
	public function testReallyLongLine() {
2476
		$this->CakeEmail->reset();
2477
		$this->CakeEmail->config(array('empty'));
2478
		$this->CakeEmail->transport('Debug');
2479
		$this->CakeEmail->from('cake@cakephp.org');
2480
		$this->CakeEmail->to('cake@cakephp.org');
2481
		$this->CakeEmail->subject('Wordwrap Test');
2482
		$this->CakeEmail->emailFormat('html');
2483
		$this->CakeEmail->template('long_line', null);
2484
		$result = $this->CakeEmail->send();
2485
		$this->assertContains('<a>', $result['message'], 'First bits are included');
2486
		$this->assertContains('x', $result['message'], 'Last byte are included');
2487
	}
2488
 
2489
/**
2490
 * CakeEmailTest::assertLineLengths()
2491
 *
2492
 * @param string $message
2493
 * @return void
2494
 */
2495
	public function assertLineLengths($message) {
2496
		$lines = explode("\r\n", $message);
2497
		foreach ($lines as $line) {
2498
			$this->assertTrue(strlen($line) <= CakeEmail::LINE_LENGTH_MUST,
2499
				'Line length exceeds the max. limit of CakeEmail::LINE_LENGTH_MUST');
2500
		}
2501
	}
2502
 
2503
}