This commit is contained in:
2020-03-27 10:13:51 +07:00
commit da1024a5b3
16614 changed files with 3274282 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,318 @@
<?php
class Swift_Mime_AttachmentTest extends Swift_Mime_AbstractMimeEntityTest
{
public function testNestingLevelIsAttachment()
{
$attachment = $this->_createAttachment($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(
Swift_Mime_MimeEntity::LEVEL_MIXED, $attachment->getNestingLevel()
);
}
public function testDispositionIsReturnedFromHeader()
{
/* -- RFC 2183, 2.1, 2.2.
*/
$disposition = $this->_createHeader('Content-Disposition', 'attachment');
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('attachment', $attachment->getDisposition());
}
public function testDispositionIsSetInHeader()
{
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array(), false
);
$disposition->shouldReceive('setFieldBodyModel')
->once()
->with('inline');
$disposition->shouldReceive('setFieldBodyModel')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$attachment->setDisposition('inline');
}
public function testDispositionIsAddedIfNonePresent()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addParameterizedHeader')
->once()
->with('Content-Disposition', 'inline');
$headers->shouldReceive('addParameterizedHeader')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($headers, $this->_createEncoder(),
$this->_createCache()
);
$attachment->setDisposition('inline');
}
public function testDispositionIsAutoDefaultedToAttachment()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addParameterizedHeader')
->once()
->with('Content-Disposition', 'attachment');
$headers->shouldReceive('addParameterizedHeader')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($headers, $this->_createEncoder(),
$this->_createCache()
);
}
public function testDefaultContentTypeInitializedToOctetStream()
{
$cType = $this->_createHeader('Content-Type', '',
array(), false
);
$cType->shouldReceive('setFieldBodyModel')
->once()
->with('application/octet-stream');
$cType->shouldReceive('setFieldBodyModel')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
}
public function testFilenameIsReturnedFromHeader()
{
/* -- RFC 2183, 2.3.
*/
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array('filename' => 'foo.txt')
);
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('foo.txt', $attachment->getFilename());
}
public function testFilenameIsSetInHeader()
{
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array('filename' => 'foo.txt'), false
);
$disposition->shouldReceive('setParameter')
->once()
->with('filename', 'bar.txt');
$disposition->shouldReceive('setParameter')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$attachment->setFilename('bar.txt');
}
public function testSettingFilenameSetsNameInContentType()
{
/*
This is a legacy requirement which isn't covered by up-to-date RFCs.
*/
$cType = $this->_createHeader('Content-Type', 'text/plain',
array(), false
);
$cType->shouldReceive('setParameter')
->once()
->with('name', 'bar.txt');
$cType->shouldReceive('setParameter')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$attachment->setFilename('bar.txt');
}
public function testSizeIsReturnedFromHeader()
{
/* -- RFC 2183, 2.7.
*/
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array('size' => 1234)
);
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(1234, $attachment->getSize());
}
public function testSizeIsSetInHeader()
{
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array(), false
);
$disposition->shouldReceive('setParameter')
->once()
->with('size', 12345);
$disposition->shouldReceive('setParameter')
->zeroOrMoreTimes();
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$attachment->setSize(12345);
}
public function testFilnameCanBeReadFromFileStream()
{
$file = $this->_createFileStream('/bar/file.ext', '');
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array('filename' => 'foo.txt'), false
);
$disposition->shouldReceive('setParameter')
->once()
->with('filename', 'file.ext');
$attachment = $this->_createAttachment($this->_createHeaderSet(array(
'Content-Disposition' => $disposition, )),
$this->_createEncoder(), $this->_createCache()
);
$attachment->setFile($file);
}
public function testContentTypeCanBeSetViaSetFile()
{
$file = $this->_createFileStream('/bar/file.ext', '');
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array('filename' => 'foo.txt'), false
);
$disposition->shouldReceive('setParameter')
->once()
->with('filename', 'file.ext');
$ctype = $this->_createHeader('Content-Type', 'text/plain', array(), false);
$ctype->shouldReceive('setFieldBodyModel')
->once()
->with('text/html');
$ctype->shouldReceive('setFieldBodyModel')
->zeroOrMoreTimes();
$headers = $this->_createHeaderSet(array(
'Content-Disposition' => $disposition,
'Content-Type' => $ctype,
));
$attachment = $this->_createAttachment($headers, $this->_createEncoder(),
$this->_createCache()
);
$attachment->setFile($file, 'text/html');
}
public function XtestContentTypeCanBeLookedUpFromCommonListIfNotProvided()
{
$file = $this->_createFileStream('/bar/file.zip', '');
$disposition = $this->_createHeader('Content-Disposition', 'attachment',
array('filename' => 'foo.zip'), false
);
$disposition->shouldReceive('setParameter')
->once()
->with('filename', 'file.zip');
$ctype = $this->_createHeader('Content-Type', 'text/plain', array(), false);
$ctype->shouldReceive('setFieldBodyModel')
->once()
->with('application/zip');
$ctype->shouldReceive('setFieldBodyModel')
->zeroOrMoreTimes();
$headers = $this->_createHeaderSet(array(
'Content-Disposition' => $disposition,
'Content-Type' => $ctype,
));
$attachment = $this->_createAttachment($headers, $this->_createEncoder(),
$this->_createCache(), array('zip' => 'application/zip', 'txt' => 'text/plain')
);
$attachment->setFile($file);
}
public function testDataCanBeReadFromFile()
{
$file = $this->_createFileStream('/foo/file.ext', '<some data>');
$attachment = $this->_createAttachment($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$attachment->setFile($file);
$this->assertEquals('<some data>', $attachment->getBody());
}
public function testFluidInterface()
{
$attachment = $this->_createAttachment($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertSame($attachment,
$attachment
->setContentType('application/pdf')
->setEncoder($this->_createEncoder())
->setId('foo@bar')
->setDescription('my pdf')
->setMaxLineLength(998)
->setBody('xx')
->setBoundary('xyz')
->setChildren(array())
->setDisposition('inline')
->setFilename('afile.txt')
->setSize(123)
->setFile($this->_createFileStream('foo.txt', ''))
);
}
protected function _createEntity($headers, $encoder, $cache)
{
return $this->_createAttachment($headers, $encoder, $cache);
}
protected function _createAttachment($headers, $encoder, $cache, $mimeTypes = array())
{
return new Swift_Mime_Attachment($headers, $encoder, $cache, new Swift_Mime_Grammar(), $mimeTypes);
}
protected function _createFileStream($path, $data, $stub = true)
{
$file = $this->getMockery('Swift_FileStream');
$file->shouldReceive('getPath')
->zeroOrMoreTimes()
->andReturn($path);
$file->shouldReceive('read')
->zeroOrMoreTimes()
->andReturnUsing(function () use ($data) {
static $first = true;
if (!$first) {
return false;
}
$first = false;
return $data;
});
$file->shouldReceive('setReadPointer')
->zeroOrMoreTimes();
return $file;
}
}

View File

@@ -0,0 +1,323 @@
<?php
class Swift_Mime_ContentEncoder_Base64ContentEncoderTest extends \SwiftMailerTestCase
{
private $_encoder;
protected function setUp()
{
$this->_encoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
}
public function testNameIsBase64()
{
$this->assertEquals('base64', $this->_encoder->getName());
}
/*
There's really no point in testing the entire base64 encoding to the
level QP encoding has been tested. base64_encode() has been in PHP for
years.
*/
public function testInputOutputRatioIs3to4Bytes()
{
/*
RFC 2045, 6.8
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
*/
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn('123');
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is);
$this->assertEquals('MTIz', $collection->content);
}
public function testPadLength()
{
/*
RFC 2045, 6.8
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a body. When fewer than 24 input bits
are available in an input group, zero bits are added (on the right)
to form an integral number of 6-bit groups. Padding at the end of
the data is performed using the "=" character. Since all base64
input is an integral number of octets, only the following cases can
arise: (1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded output will be
an integral multiple of 4 characters with no "=" padding, (2) the
final quantum of encoding input is exactly 8 bits; here, the final
unit of encoded output will be two characters followed by two "="
padding characters, or (3) the final quantum of encoding input is
exactly 16 bits; here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
for ($i = 0; $i < 30; ++$i) {
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn(pack('C', rand(0, 255)));
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is);
$this->assertRegExp('~^[a-zA-Z0-9/\+]{2}==$~', $collection->content,
'%s: A single byte should have 2 bytes of padding'
);
}
for ($i = 0; $i < 30; ++$i) {
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn(pack('C*', rand(0, 255), rand(0, 255)));
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is);
$this->assertRegExp('~^[a-zA-Z0-9/\+]{3}=$~', $collection->content,
'%s: Two bytes should have 1 byte of padding'
);
}
for ($i = 0; $i < 30; ++$i) {
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn(pack('C*', rand(0, 255), rand(0, 255), rand(0, 255)));
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is);
$this->assertRegExp('~^[a-zA-Z0-9/\+]{4}$~', $collection->content,
'%s: Three bytes should have no padding'
);
}
}
public function testMaximumLineLengthIs76Characters()
{
/*
The encoded output stream must be represented in lines of no more
than 76 characters each. All line breaks or other characters not
found in Table 1 must be ignored by decoding software.
*/
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //12
$os->shouldReceive('read')
->once()
->andReturn('mnopqrstuvwx'); //24
$os->shouldReceive('read')
->once()
->andReturn('yzabc1234567'); //36
$os->shouldReceive('read')
->once()
->andReturn('890ABCDEFGHI'); //48
$os->shouldReceive('read')
->once()
->andReturn('JKLMNOPQRSTU'); //60
$os->shouldReceive('read')
->once()
->andReturn('VWXYZ1234567'); //72
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //84
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is);
$this->assertEquals(
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmMxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFS\r\n".
'U1RVVldYWVoxMjM0NTY3YWJjZGVmZ2hpamts',
$collection->content
);
}
public function testMaximumLineLengthCanBeDifferent()
{
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //12
$os->shouldReceive('read')
->once()
->andReturn('mnopqrstuvwx'); //24
$os->shouldReceive('read')
->once()
->andReturn('yzabc1234567'); //36
$os->shouldReceive('read')
->once()
->andReturn('890ABCDEFGHI'); //48
$os->shouldReceive('read')
->once()
->andReturn('JKLMNOPQRSTU'); //60
$os->shouldReceive('read')
->once()
->andReturn('VWXYZ1234567'); //72
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //84
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is, 0, 50);
$this->assertEquals(
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmMxMjM0NTY3OD\r\n".
"kwQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVoxMjM0NTY3YWJj\r\n".
'ZGVmZ2hpamts',
$collection->content
);
}
public function testMaximumLineLengthIsNeverMoreThan76Chars()
{
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //12
$os->shouldReceive('read')
->once()
->andReturn('mnopqrstuvwx'); //24
$os->shouldReceive('read')
->once()
->andReturn('yzabc1234567'); //36
$os->shouldReceive('read')
->once()
->andReturn('890ABCDEFGHI'); //48
$os->shouldReceive('read')
->once()
->andReturn('JKLMNOPQRSTU'); //60
$os->shouldReceive('read')
->once()
->andReturn('VWXYZ1234567'); //72
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //84
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is, 0, 100);
$this->assertEquals(
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmMxMjM0NTY3ODkwQUJDREVGR0hJSktMTU5PUFFS\r\n".
'U1RVVldYWVoxMjM0NTY3YWJjZGVmZ2hpamts',
$collection->content
);
}
public function testFirstLineLengthCanBeDifferent()
{
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //12
$os->shouldReceive('read')
->once()
->andReturn('mnopqrstuvwx'); //24
$os->shouldReceive('read')
->once()
->andReturn('yzabc1234567'); //36
$os->shouldReceive('read')
->once()
->andReturn('890ABCDEFGHI'); //48
$os->shouldReceive('read')
->once()
->andReturn('JKLMNOPQRSTU'); //60
$os->shouldReceive('read')
->once()
->andReturn('VWXYZ1234567'); //72
$os->shouldReceive('read')
->once()
->andReturn('abcdefghijkl'); //84
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$this->_encoder->encodeByteStream($os, $is, 19);
$this->assertEquals(
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXphYmMxMjM0NTY3ODkwQUJDR\r\n".
'EVGR0hJSktMTU5PUFFSU1RVVldYWVoxMjM0NTY3YWJjZGVmZ2hpamts',
$collection->content
);
}
private function _createOutputByteStream($stub = false)
{
return $this->getMockery('Swift_OutputByteStream')->shouldIgnoreMissing();
}
private function _createInputByteStream($stub = false)
{
return $this->getMockery('Swift_InputByteStream')->shouldIgnoreMissing();
}
}

View File

@@ -0,0 +1,171 @@
<?php
class Swift_Mime_ContentEncoder_PlainContentEncoderTest extends \SwiftMailerTestCase
{
public function testNameCanBeSpecifiedInConstructor()
{
$encoder = $this->_getEncoder('7bit');
$this->assertEquals('7bit', $encoder->getName());
$encoder = $this->_getEncoder('8bit');
$this->assertEquals('8bit', $encoder->getName());
}
public function testNoOctetsAreModifiedInString()
{
$encoder = $this->_getEncoder('7bit');
foreach (range(0x00, 0xFF) as $octet) {
$byte = pack('C', $octet);
$this->assertIdenticalBinary($byte, $encoder->encodeString($byte));
}
}
public function testNoOctetsAreModifiedInByteStream()
{
$encoder = $this->_getEncoder('7bit');
foreach (range(0x00, 0xFF) as $octet) {
$byte = pack('C', $octet);
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn($byte);
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$encoder->encodeByteStream($os, $is);
$this->assertIdenticalBinary($byte, $collection->content);
}
}
public function testLineLengthCanBeSpecified()
{
$encoder = $this->_getEncoder('7bit');
$chars = array();
for ($i = 0; $i < 50; ++$i) {
$chars[] = 'a';
}
$input = implode(' ', $chars); //99 chars long
$this->assertEquals(
'a a a a a a a a a a a a a a a a a a a a a a a a a '."\r\n".//50 *
'a a a a a a a a a a a a a a a a a a a a a a a a a', //99
$encoder->encodeString($input, 0, 50),
'%s: Lines should be wrapped at 50 chars'
);
}
public function testLineLengthCanBeSpecifiedInByteStream()
{
$encoder = $this->_getEncoder('7bit');
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
for ($i = 0; $i < 50; ++$i) {
$os->shouldReceive('read')
->once()
->andReturn('a ');
}
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$encoder->encodeByteStream($os, $is, 0, 50);
$this->assertEquals(
str_repeat('a ', 25)."\r\n".str_repeat('a ', 25),
$collection->content
);
}
public function testencodeStringGeneratesCorrectCrlf()
{
$encoder = $this->_getEncoder('7bit', true);
$this->assertEquals("a\r\nb", $encoder->encodeString("a\rb"),
'%s: Line endings should be standardized'
);
$this->assertEquals("a\r\nb", $encoder->encodeString("a\nb"),
'%s: Line endings should be standardized'
);
$this->assertEquals("a\r\n\r\nb", $encoder->encodeString("a\n\rb"),
'%s: Line endings should be standardized'
);
$this->assertEquals("a\r\n\r\nb", $encoder->encodeString("a\r\rb"),
'%s: Line endings should be standardized'
);
$this->assertEquals("a\r\n\r\nb", $encoder->encodeString("a\n\nb"),
'%s: Line endings should be standardized'
);
}
public function crlfProvider()
{
return array(
array("\r", "a\r\nb"),
array("\n", "a\r\nb"),
array("\n\r", "a\r\n\r\nb"),
array("\n\n", "a\r\n\r\nb"),
array("\r\r", "a\r\n\r\nb"),
);
}
/**
* @dataProvider crlfProvider
*/
public function testCanonicEncodeByteStreamGeneratesCorrectCrlf($test, $expected)
{
$encoder = $this->_getEncoder('7bit', true);
$os = $this->_createOutputByteStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$os->shouldReceive('read')
->once()
->andReturn('a');
$os->shouldReceive('read')
->once()
->andReturn($test);
$os->shouldReceive('read')
->once()
->andReturn('b');
$os->shouldReceive('read')
->zeroOrMoreTimes()
->andReturn(false);
$encoder->encodeByteStream($os, $is);
$this->assertEquals($expected, $collection->content);
}
private function _getEncoder($name, $canonical = false)
{
return new Swift_Mime_ContentEncoder_PlainContentEncoder($name, $canonical);
}
private function _createOutputByteStream($stub = false)
{
return $this->getMockery('Swift_OutputByteStream')->shouldIgnoreMissing();
}
private function _createInputByteStream($stub = false)
{
return $this->getMockery('Swift_InputByteStream')->shouldIgnoreMissing();
}
}

View File

@@ -0,0 +1,516 @@
<?php
class Swift_Mime_ContentEncoder_QpContentEncoderTest extends \SwiftMailerTestCase
{
public function testNameIsQuotedPrintable()
{
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder(
$this->_createCharacterStream(true)
);
$this->assertEquals('quoted-printable', $encoder->getName());
}
/* -- RFC 2045, 6.7 --
(1) (General 8bit representation) Any octet, except a CR or
LF that is part of a CRLF line break of the canonical
(standard) form of the data being encoded, may be
represented by an "=" followed by a two digit
hexadecimal representation of the octet's value. The
digits of the hexadecimal alphabet, for this purpose,
are "0123456789ABCDEF". Uppercase letters must be
used; lowercase letters are not allowed. Thus, for
example, the decimal value 12 (US-ASCII form feed) can
be represented by "=0C", and the decimal value 61 (US-
ASCII EQUAL SIGN) can be represented by "=3D". This
rule must be followed except when the following rules
allow an alternative encoding.
*/
public function testPermittedCharactersAreNotEncoded()
{
/* -- RFC 2045, 6.7 --
(2) (Literal representation) Octets with decimal values of
33 through 60 inclusive, and 62 through 126, inclusive,
MAY be represented as the US-ASCII characters which
correspond to those octets (EXCLAMATION POINT through
LESS THAN, and GREATER THAN through TILDE,
respectively).
*/
foreach (array_merge(range(33, 60), range(62, 126)) as $ordinal) {
$char = chr($ordinal);
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array($ordinal));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertIdenticalBinary($char, $collection->content);
}
}
public function testLinearWhiteSpaceAtLineEndingIsEncoded()
{
/* -- RFC 2045, 6.7 --
(3) (White Space) Octets with values of 9 and 32 MAY be
represented as US-ASCII TAB (HT) and SPACE characters,
respectively, but MUST NOT be so represented at the end
of an encoded line. Any TAB (HT) or SPACE characters
on an encoded line MUST thus be followed on that line
by a printable character. In particular, an "=" at the
end of an encoded line, indicating a soft line break
(see rule #5) may follow one or more TAB (HT) or SPACE
characters. It follows that an octet with decimal
value 9 or 32 appearing at the end of an encoded line
must be represented according to Rule #1. This rule is
necessary because some MTAs (Message Transport Agents,
programs which transport messages from one user to
another, or perform a portion of such transfers) are
known to pad lines of text with SPACEs, and others are
known to remove "white space" characters from the end
of a line. Therefore, when decoding a Quoted-Printable
body, any trailing white space on a line must be
deleted, as it will necessarily have been added by
intermediate transport agents.
*/
$HT = chr(0x09); //9
$SPACE = chr(0x20); //32
//HT
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x09));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x09));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0D));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0A));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('b')));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals("a\t=09\r\nb", $collection->content);
//SPACE
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x20));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x20));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0D));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0A));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('b')));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals("a =20\r\nb", $collection->content);
}
public function testCRLFIsLeftAlone()
{
/*
(4) (Line Breaks) A line break in a text body, represented
as a CRLF sequence in the text canonical form, must be
represented by a (RFC 822) line break, which is also a
CRLF sequence, in the Quoted-Printable encoding. Since
the canonical representation of media types other than
text do not generally include the representation of
line breaks as CRLF sequences, no hard line breaks
(i.e. line breaks that are intended to be meaningful
and to be displayed to the user) can occur in the
quoted-printable encoding of such types. Sequences
like "=0D", "=0A", "=0A=0D" and "=0D=0A" will routinely
appear in non-text data represented in quoted-
printable, of course.
Note that many implementations may elect to encode the
local representation of various content types directly
rather than converting to canonical form first,
encoding, and then converting back to local
representation. In particular, this may apply to plain
text material on systems that use newline conventions
other than a CRLF terminator sequence. Such an
implementation optimization is permissible, but only
when the combined canonicalization-encoding step is
equivalent to performing the three steps separately.
*/
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0D));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0A));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('b')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0D));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0A));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('c')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0D));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x0A));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals("a\r\nb\r\nc\r\n", $collection->content);
}
public function testLinesLongerThan76CharactersAreSoftBroken()
{
/*
(5) (Soft Line Breaks) The Quoted-Printable encoding
REQUIRES that encoded lines be no more than 76
characters long. If longer lines are to be encoded
with the Quoted-Printable encoding, "soft" line breaks
must be used. An equal sign as the last character on a
encoded line indicates such a non-significant ("soft")
line break in the encoded text.
*/
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
for ($seq = 0; $seq <= 140; ++$seq) {
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
}
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals(str_repeat('a', 75)."=\r\n".str_repeat('a', 66), $collection->content);
}
public function testMaxLineLengthCanBeSpecified()
{
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
for ($seq = 0; $seq <= 100; ++$seq) {
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
}
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is, 0, 54);
$this->assertEquals(str_repeat('a', 53)."=\r\n".str_repeat('a', 48), $collection->content);
}
public function testBytesBelowPermittedRangeAreEncoded()
{
/*
According to Rule (1 & 2)
*/
foreach (range(0, 32) as $ordinal) {
$char = chr($ordinal);
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array($ordinal));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals(sprintf('=%02X', $ordinal), $collection->content);
}
}
public function testDecimalByte61IsEncoded()
{
/*
According to Rule (1 & 2)
*/
$char = chr(61);
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(61));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals(sprintf('=%02X', 61), $collection->content);
}
public function testBytesAbovePermittedRangeAreEncoded()
{
/*
According to Rule (1 & 2)
*/
foreach (range(127, 255) as $ordinal) {
$char = chr($ordinal);
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array($ordinal));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is);
$this->assertEquals(sprintf('=%02X', $ordinal), $collection->content);
}
}
public function testFirstLineLengthCanBeDifferent()
{
$os = $this->_createOutputByteStream(true);
$charStream = $this->_createCharacterStream();
$is = $this->_createInputByteStream();
$collection = new Swift_StreamCollector();
$is->shouldReceive('write')
->zeroOrMoreTimes()
->andReturnUsing($collection);
$charStream->shouldReceive('flushContents')
->once();
$charStream->shouldReceive('importByteStream')
->once()
->with($os);
for ($seq = 0; $seq <= 140; ++$seq) {
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
}
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
$encoder->encodeByteStream($os, $is, 22);
$this->assertEquals(
str_repeat('a', 53)."=\r\n".str_repeat('a', 75)."=\r\n".str_repeat('a', 13),
$collection->content
);
}
public function testObserverInterfaceCanChangeCharset()
{
$stream = $this->_createCharacterStream();
$stream->shouldReceive('setCharacterSet')
->once()
->with('windows-1252');
$encoder = new Swift_Mime_ContentEncoder_QpContentEncoder($stream);
$encoder->charsetChanged('windows-1252');
}
public function testTextIsPreWrapped()
{
$encoder = $this->createEncoder();
$input = str_repeat('a', 70)."\r\n".
str_repeat('a', 70)."\r\n".
str_repeat('a', 70);
$os = new Swift_ByteStream_ArrayByteStream();
$is = new Swift_ByteStream_ArrayByteStream();
$is->write($input);
$encoder->encodeByteStream($is, $os);
$this->assertEquals(
$input, $os->read(PHP_INT_MAX)
);
}
private function _createCharacterStream($stub = false)
{
return $this->getMockery('Swift_CharacterStream')->shouldIgnoreMissing();
}
private function createEncoder()
{
$factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
$charStream = new Swift_CharacterStream_NgCharacterStream($factory, 'utf-8');
return new Swift_Mime_ContentEncoder_QpContentEncoder($charStream);
}
private function _createOutputByteStream($stub = false)
{
return $this->getMockery('Swift_OutputByteStream')->shouldIgnoreMissing();
}
private function _createInputByteStream($stub = false)
{
return $this->getMockery('Swift_InputByteStream')->shouldIgnoreMissing();
}
}

View File

@@ -0,0 +1,55 @@
<?php
class Swift_Mime_EmbeddedFileTest extends Swift_Mime_AttachmentTest
{
public function testNestingLevelIsAttachment()
{
//Overridden
}
public function testNestingLevelIsEmbedded()
{
$file = $this->_createEmbeddedFile($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(
Swift_Mime_MimeEntity::LEVEL_RELATED, $file->getNestingLevel()
);
}
public function testIdIsAutoGenerated()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addIdHeader')
->once()
->with('Content-ID', '/^.*?@.*?$/D');
$file = $this->_createEmbeddedFile($headers, $this->_createEncoder(),
$this->_createCache()
);
}
public function testDefaultDispositionIsInline()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addParameterizedHeader')
->once()
->with('Content-Disposition', 'inline');
$headers->shouldReceive('addParameterizedHeader')
->zeroOrMoreTimes();
$file = $this->_createEmbeddedFile($headers, $this->_createEncoder(),
$this->_createCache()
);
}
protected function _createAttachment($headers, $encoder, $cache, $mimeTypes = array())
{
return $this->_createEmbeddedFile($headers, $encoder, $cache, $mimeTypes);
}
private function _createEmbeddedFile($headers, $encoder, $cache)
{
return new Swift_Mime_EmbeddedFile($headers, $encoder, $cache, new Swift_Mime_Grammar());
}
}

View File

@@ -0,0 +1,13 @@
<?php
class Swift_Mime_HeaderEncoder_Base64HeaderEncoderTest extends \PHPUnit_Framework_TestCase
{
//Most tests are already covered in Base64EncoderTest since this subclass only
// adds a getName() method
public function testNameIsB()
{
$encoder = new Swift_Mime_HeaderEncoder_Base64HeaderEncoder();
$this->assertEquals('B', $encoder->getName());
}
}

View File

@@ -0,0 +1,221 @@
<?php
class Swift_Mime_HeaderEncoder_QpHeaderEncoderTest extends \SwiftMailerTestCase
{
//Most tests are already covered in QpEncoderTest since this subclass only
// adds a getName() method
public function testNameIsQ()
{
$encoder = $this->_createEncoder(
$this->_createCharacterStream(true)
);
$this->assertEquals('Q', $encoder->getName());
}
public function testSpaceAndTabNeverAppear()
{
/* -- RFC 2047, 4.
Only a subset of the printable ASCII characters may be used in
'encoded-text'. Space and tab characters are not allowed, so that
the beginning and end of an 'encoded-word' are obvious.
*/
$charStream = $this->_createCharacterStream();
$charStream->shouldReceive('readBytes')
->atLeast()->times(6)
->andReturn(array(ord('a')), array(0x20), array(0x09), array(0x20), array(ord('b')), false);
$encoder = $this->_createEncoder($charStream);
$this->assertNotRegExp('~[ \t]~', $encoder->encodeString("a \t b"),
'%s: encoded-words in headers cannot contain LWSP as per RFC 2047.'
);
}
public function testSpaceIsRepresentedByUnderscore()
{
/* -- RFC 2047, 4.2.
(2) The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be
represented as "_" (underscore, ASCII 95.). (This character may
not pass through some internetwork mail gateways, but its use
will greatly enhance readability of "Q" encoded data with mail
readers that do not support this encoding.) Note that the "_"
always represents hexadecimal 20, even if the SPACE character
occupies a different code position in the character set in use.
*/
$charStream = $this->_createCharacterStream();
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(0x20));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('b')));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = $this->_createEncoder($charStream);
$this->assertEquals('a_b', $encoder->encodeString('a b'),
'%s: Spaces can be represented by more readable underscores as per RFC 2047.'
);
}
public function testEqualsAndQuestionAndUnderscoreAreEncoded()
{
/* -- RFC 2047, 4.2.
(3) 8-bit values which correspond to printable ASCII characters other
than "=", "?", and "_" (underscore), MAY be represented as those
characters. (But see section 5 for restrictions.) In
particular, SPACE and TAB MUST NOT be represented as themselves
within encoded words.
*/
$charStream = $this->_createCharacterStream();
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('=')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('?')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('_')));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = $this->_createEncoder($charStream);
$this->assertEquals('=3D=3F=5F', $encoder->encodeString('=?_'),
'%s: Chars =, ? and _ (underscore) may not appear as per RFC 2047.'
);
}
public function testParensAndQuotesAreEncoded()
{
/* -- RFC 2047, 5 (2).
A "Q"-encoded 'encoded-word' which appears in a 'comment' MUST NOT
contain the characters "(", ")" or "
*/
$charStream = $this->_createCharacterStream();
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('(')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('"')));
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord(')')));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = $this->_createEncoder($charStream);
$this->assertEquals('=28=22=29', $encoder->encodeString('(")'),
'%s: Chars (, " (DQUOTE) and ) may not appear as per RFC 2047.'
);
}
public function testOnlyCharactersAllowedInPhrasesAreUsed()
{
/* -- RFC 2047, 5.
(3) As a replacement for a 'word' entity within a 'phrase', for example,
one that precedes an address in a From, To, or Cc header. The ABNF
definition for 'phrase' from RFC 822 thus becomes:
phrase = 1*( encoded-word / word )
In this case the set of characters that may be used in a "Q"-encoded
'encoded-word' is restricted to: <upper and lower case ASCII
letters, decimal digits, "!", "*", "+", "-", "/", "=", and "_"
(underscore, ASCII 95.)>. An 'encoded-word' that appears within a
'phrase' MUST be separated from any adjacent 'word', 'text' or
'special' by 'linear-white-space'.
*/
$allowedBytes = array_merge(
range(ord('a'), ord('z')), range(ord('A'), ord('Z')),
range(ord('0'), ord('9')),
array(ord('!'), ord('*'), ord('+'), ord('-'), ord('/'))
);
foreach (range(0x00, 0xFF) as $byte) {
$char = pack('C', $byte);
$charStream = $this->_createCharacterStream();
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array($byte));
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = $this->_createEncoder($charStream);
$encodedChar = $encoder->encodeString($char);
if (in_array($byte, $allowedBytes)) {
$this->assertEquals($char, $encodedChar,
'%s: Character '.$char.' should not be encoded.'
);
} elseif (0x20 == $byte) {
//Special case
$this->assertEquals('_', $encodedChar,
'%s: Space character should be replaced.'
);
} else {
$this->assertEquals(sprintf('=%02X', $byte), $encodedChar,
'%s: Byte '.$byte.' should be encoded.'
);
}
}
}
public function testEqualsNeverAppearsAtEndOfLine()
{
/* -- RFC 2047, 5 (3).
The 'encoded-text' in an 'encoded-word' must be self-contained;
'encoded-text' MUST NOT be continued from one 'encoded-word' to
another. This implies that the 'encoded-text' portion of a "B"
'encoded-word' will be a multiple of 4 characters long; for a "Q"
'encoded-word', any "=" character that appears in the 'encoded-text'
portion will be followed by two hexadecimal characters.
*/
$input = str_repeat('a', 140);
$charStream = $this->_createCharacterStream();
$output = '';
$seq = 0;
for (; $seq < 140; ++$seq) {
$charStream->shouldReceive('readBytes')
->once()
->andReturn(array(ord('a')));
if (75 == $seq) {
$output .= "\r\n"; // =\r\n
}
$output .= 'a';
}
$charStream->shouldReceive('readBytes')
->zeroOrMoreTimes()
->andReturn(false);
$encoder = $this->_createEncoder($charStream);
$this->assertEquals($output, $encoder->encodeString($input));
}
private function _createEncoder($charStream)
{
return new Swift_Mime_HeaderEncoder_QpHeaderEncoder($charStream);
}
private function _createCharacterStream($stub = false)
{
return $this->getMockery('Swift_CharacterStream')->shouldIgnoreMissing();
}
}

View File

@@ -0,0 +1,69 @@
<?php
class Swift_Mime_Headers_DateHeaderTest extends \PHPUnit_Framework_TestCase
{
/* --
The following tests refer to RFC 2822, section 3.6.1 and 3.3.
*/
public function testTypeIsDateHeader()
{
$header = $this->_getHeader('Date');
$this->assertEquals(Swift_Mime_Header::TYPE_DATE, $header->getFieldType());
}
public function testGetTimestamp()
{
$timestamp = time();
$header = $this->_getHeader('Date');
$header->setTimestamp($timestamp);
$this->assertSame($timestamp, $header->getTimestamp());
}
public function testTimestampCanBeSetBySetter()
{
$timestamp = time();
$header = $this->_getHeader('Date');
$header->setTimestamp($timestamp);
$this->assertSame($timestamp, $header->getTimestamp());
}
public function testIntegerTimestampIsConvertedToRfc2822Date()
{
$timestamp = time();
$header = $this->_getHeader('Date');
$header->setTimestamp($timestamp);
$this->assertEquals(date('r', $timestamp), $header->getFieldBody());
}
public function testSetBodyModel()
{
$timestamp = time();
$header = $this->_getHeader('Date');
$header->setFieldBodyModel($timestamp);
$this->assertEquals(date('r', $timestamp), $header->getFieldBody());
}
public function testGetBodyModel()
{
$timestamp = time();
$header = $this->_getHeader('Date');
$header->setTimestamp($timestamp);
$this->assertEquals($timestamp, $header->getFieldBodyModel());
}
public function testToString()
{
$timestamp = time();
$header = $this->_getHeader('Date');
$header->setTimestamp($timestamp);
$this->assertEquals('Date: '.date('r', $timestamp)."\r\n",
$header->toString()
);
}
private function _getHeader($name)
{
return new Swift_Mime_Headers_DateHeader($name, new Swift_Mime_Grammar());
}
}

View File

@@ -0,0 +1,189 @@
<?php
class Swift_Mime_Headers_IdentificationHeaderTest extends \PHPUnit_Framework_TestCase
{
public function testTypeIsIdHeader()
{
$header = $this->_getHeader('Message-ID');
$this->assertEquals(Swift_Mime_Header::TYPE_ID, $header->getFieldType());
}
public function testValueMatchesMsgIdSpec()
{
/* -- RFC 2822, 3.6.4.
message-id = "Message-ID:" msg-id CRLF
in-reply-to = "In-Reply-To:" 1*msg-id CRLF
references = "References:" 1*msg-id CRLF
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
id-left = dot-atom-text / no-fold-quote / obs-id-left
id-right = dot-atom-text / no-fold-literal / obs-id-right
no-fold-quote = DQUOTE *(qtext / quoted-pair) DQUOTE
no-fold-literal = "[" *(dtext / quoted-pair) "]"
*/
$header = $this->_getHeader('Message-ID');
$header->setId('id-left@id-right');
$this->assertEquals('<id-left@id-right>', $header->getFieldBody());
}
public function testIdCanBeRetrievedVerbatim()
{
$header = $this->_getHeader('Message-ID');
$header->setId('id-left@id-right');
$this->assertEquals('id-left@id-right', $header->getId());
}
public function testMultipleIdsCanBeSet()
{
$header = $this->_getHeader('References');
$header->setIds(array('a@b', 'x@y'));
$this->assertEquals(array('a@b', 'x@y'), $header->getIds());
}
public function testSettingMultipleIdsProducesAListValue()
{
/* -- RFC 2822, 3.6.4.
The "References:" and "In-Reply-To:" field each contain one or more
unique message identifiers, optionally separated by CFWS.
.. SNIP ..
in-reply-to = "In-Reply-To:" 1*msg-id CRLF
references = "References:" 1*msg-id CRLF
*/
$header = $this->_getHeader('References');
$header->setIds(array('a@b', 'x@y'));
$this->assertEquals('<a@b> <x@y>', $header->getFieldBody());
}
public function testIdLeftCanBeQuoted()
{
/* -- RFC 2822, 3.6.4.
id-left = dot-atom-text / no-fold-quote / obs-id-left
*/
$header = $this->_getHeader('References');
$header->setId('"ab"@c');
$this->assertEquals('"ab"@c', $header->getId());
$this->assertEquals('<"ab"@c>', $header->getFieldBody());
}
public function testIdLeftCanContainAnglesAsQuotedPairs()
{
/* -- RFC 2822, 3.6.4.
no-fold-quote = DQUOTE *(qtext / quoted-pair) DQUOTE
*/
$header = $this->_getHeader('References');
$header->setId('"a\\<\\>b"@c');
$this->assertEquals('"a\\<\\>b"@c', $header->getId());
$this->assertEquals('<"a\\<\\>b"@c>', $header->getFieldBody());
}
public function testIdLeftCanBeDotAtom()
{
$header = $this->_getHeader('References');
$header->setId('a.b+&%$.c@d');
$this->assertEquals('a.b+&%$.c@d', $header->getId());
$this->assertEquals('<a.b+&%$.c@d>', $header->getFieldBody());
}
public function testInvalidIdLeftThrowsException()
{
try {
$header = $this->_getHeader('References');
$header->setId('a b c@d');
$this->fail(
'Exception should be thrown since "a b c" is not valid id-left.'
);
} catch (Exception $e) {
}
}
public function testIdRightCanBeDotAtom()
{
/* -- RFC 2822, 3.6.4.
id-right = dot-atom-text / no-fold-literal / obs-id-right
*/
$header = $this->_getHeader('References');
$header->setId('a@b.c+&%$.d');
$this->assertEquals('a@b.c+&%$.d', $header->getId());
$this->assertEquals('<a@b.c+&%$.d>', $header->getFieldBody());
}
public function testIdRightCanBeLiteral()
{
/* -- RFC 2822, 3.6.4.
no-fold-literal = "[" *(dtext / quoted-pair) "]"
*/
$header = $this->_getHeader('References');
$header->setId('a@[1.2.3.4]');
$this->assertEquals('a@[1.2.3.4]', $header->getId());
$this->assertEquals('<a@[1.2.3.4]>', $header->getFieldBody());
}
public function testInvalidIdRightThrowsException()
{
try {
$header = $this->_getHeader('References');
$header->setId('a@b c d');
$this->fail(
'Exception should be thrown since "b c d" is not valid id-right.'
);
} catch (Exception $e) {
}
}
public function testMissingAtSignThrowsException()
{
/* -- RFC 2822, 3.6.4.
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
*/
try {
$header = $this->_getHeader('References');
$header->setId('abc');
$this->fail(
'Exception should be thrown since "abc" is does not contain @.'
);
} catch (Exception $e) {
}
}
public function testSetBodyModel()
{
$header = $this->_getHeader('Message-ID');
$header->setFieldBodyModel('a@b');
$this->assertEquals(array('a@b'), $header->getIds());
}
public function testGetBodyModel()
{
$header = $this->_getHeader('Message-ID');
$header->setId('a@b');
$this->assertEquals(array('a@b'), $header->getFieldBodyModel());
}
public function testStringValue()
{
$header = $this->_getHeader('References');
$header->setIds(array('a@b', 'x@y'));
$this->assertEquals('References: <a@b> <x@y>'."\r\n", $header->toString());
}
private function _getHeader($name)
{
return new Swift_Mime_Headers_IdentificationHeader($name, new Swift_Mime_Grammar());
}
}

View File

@@ -0,0 +1,327 @@
<?php
class Swift_Mime_Headers_MailboxHeaderTest extends \SwiftMailerTestCase
{
/* -- RFC 2822, 3.6.2 for all tests.
*/
private $_charset = 'utf-8';
public function testTypeIsMailboxHeader()
{
$header = $this->_getHeader('To', $this->_getEncoder('Q', true));
$this->assertEquals(Swift_Mime_Header::TYPE_MAILBOX, $header->getFieldType());
}
public function testMailboxIsSetForAddress()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setAddresses('chris@swiftmailer.org');
$this->assertEquals(array('chris@swiftmailer.org'),
$header->getNameAddressStrings()
);
}
public function testMailboxIsRenderedForNameAddress()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array('chris@swiftmailer.org' => 'Chris Corbyn'));
$this->assertEquals(
array('Chris Corbyn <chris@swiftmailer.org>'), $header->getNameAddressStrings()
);
}
public function testAddressCanBeReturnedForAddress()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setAddresses('chris@swiftmailer.org');
$this->assertEquals(array('chris@swiftmailer.org'), $header->getAddresses());
}
public function testAddressCanBeReturnedForNameAddress()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array('chris@swiftmailer.org' => 'Chris Corbyn'));
$this->assertEquals(array('chris@swiftmailer.org'), $header->getAddresses());
}
public function testQuotesInNameAreQuoted()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn, "DHE"',
));
$this->assertEquals(
array('"Chris Corbyn, \"DHE\"" <chris@swiftmailer.org>'),
$header->getNameAddressStrings()
);
}
public function testEscapeCharsInNameAreQuoted()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn, \\escaped\\',
));
$this->assertEquals(
array('"Chris Corbyn, \\\\escaped\\\\" <chris@swiftmailer.org>'),
$header->getNameAddressStrings()
);
}
public function testGetMailboxesReturnsNameValuePairs()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn, DHE',
));
$this->assertEquals(
array('chris@swiftmailer.org' => 'Chris Corbyn, DHE'), $header->getNameAddresses()
);
}
public function testMultipleAddressesCanBeSetAndFetched()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setAddresses(array(
'chris@swiftmailer.org', 'mark@swiftmailer.org',
));
$this->assertEquals(
array('chris@swiftmailer.org', 'mark@swiftmailer.org'),
$header->getAddresses()
);
}
public function testMultipleAddressesAsMailboxes()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setAddresses(array(
'chris@swiftmailer.org', 'mark@swiftmailer.org',
));
$this->assertEquals(
array('chris@swiftmailer.org' => null, 'mark@swiftmailer.org' => null),
$header->getNameAddresses()
);
}
public function testMultipleAddressesAsMailboxStrings()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setAddresses(array(
'chris@swiftmailer.org', 'mark@swiftmailer.org',
));
$this->assertEquals(
array('chris@swiftmailer.org', 'mark@swiftmailer.org'),
$header->getNameAddressStrings()
);
}
public function testMultipleNamedMailboxesReturnsMultipleAddresses()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$this->assertEquals(
array('chris@swiftmailer.org', 'mark@swiftmailer.org'),
$header->getAddresses()
);
}
public function testMultipleNamedMailboxesReturnsMultipleMailboxes()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$this->assertEquals(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
),
$header->getNameAddresses()
);
}
public function testMultipleMailboxesProducesMultipleMailboxStrings()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$this->assertEquals(array(
'Chris Corbyn <chris@swiftmailer.org>',
'Mark Corbyn <mark@swiftmailer.org>',
),
$header->getNameAddressStrings()
);
}
public function testSetAddressesOverwritesAnyMailboxes()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$this->assertEquals(
array('chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn', ),
$header->getNameAddresses()
);
$this->assertEquals(
array('chris@swiftmailer.org', 'mark@swiftmailer.org'),
$header->getAddresses()
);
$header->setAddresses(array('chris@swiftmailer.org', 'mark@swiftmailer.org'));
$this->assertEquals(
array('chris@swiftmailer.org' => null, 'mark@swiftmailer.org' => null),
$header->getNameAddresses()
);
$this->assertEquals(
array('chris@swiftmailer.org', 'mark@swiftmailer.org'),
$header->getAddresses()
);
}
public function testNameIsEncodedIfNonAscii()
{
$name = 'C'.pack('C', 0x8F).'rbyn';
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($name, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('C=8Frbyn');
$header = $this->_getHeader('From', $encoder);
$header->setNameAddresses(array('chris@swiftmailer.org' => 'Chris '.$name));
$addresses = $header->getNameAddressStrings();
$this->assertEquals(
'Chris =?'.$this->_charset.'?Q?C=8Frbyn?= <chris@swiftmailer.org>',
array_shift($addresses)
);
}
public function testEncodingLineLengthCalculations()
{
/* -- RFC 2047, 2.
An 'encoded-word' may not be more than 75 characters long, including
'charset', 'encoding', 'encoded-text', and delimiters.
*/
$name = 'C'.pack('C', 0x8F).'rbyn';
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($name, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('C=8Frbyn');
$header = $this->_getHeader('From', $encoder);
$header->setNameAddresses(array('chris@swiftmailer.org' => 'Chris '.$name));
$header->getNameAddressStrings();
}
public function testGetValueReturnsMailboxStringValue()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
));
$this->assertEquals(
'Chris Corbyn <chris@swiftmailer.org>', $header->getFieldBody()
);
}
public function testGetValueReturnsMailboxStringValueForMultipleMailboxes()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$this->assertEquals(
'Chris Corbyn <chris@swiftmailer.org>, Mark Corbyn <mark@swiftmailer.org>',
$header->getFieldBody()
);
}
public function testRemoveAddressesWithSingleValue()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$header->removeAddresses('chris@swiftmailer.org');
$this->assertEquals(array('mark@swiftmailer.org'),
$header->getAddresses()
);
}
public function testRemoveAddressesWithList()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$header->removeAddresses(
array('chris@swiftmailer.org', 'mark@swiftmailer.org')
);
$this->assertEquals(array(), $header->getAddresses());
}
public function testSetBodyModel()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setFieldBodyModel('chris@swiftmailer.org');
$this->assertEquals(array('chris@swiftmailer.org' => null), $header->getNameAddresses());
}
public function testGetBodyModel()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setAddresses(array('chris@swiftmailer.org'));
$this->assertEquals(array('chris@swiftmailer.org' => null), $header->getFieldBodyModel());
}
public function testToString()
{
$header = $this->_getHeader('From', $this->_getEncoder('Q', true));
$header->setNameAddresses(array(
'chris@swiftmailer.org' => 'Chris Corbyn',
'mark@swiftmailer.org' => 'Mark Corbyn',
));
$this->assertEquals(
'From: Chris Corbyn <chris@swiftmailer.org>, '.
'Mark Corbyn <mark@swiftmailer.org>'."\r\n",
$header->toString()
);
}
private function _getHeader($name, $encoder)
{
$header = new Swift_Mime_Headers_MailboxHeader($name, $encoder, new Swift_Mime_Grammar());
$header->setCharset($this->_charset);
return $header;
}
private function _getEncoder($type, $stub = false)
{
$encoder = $this->getMockery('Swift_Mime_HeaderEncoder')->shouldIgnoreMissing();
$encoder->shouldReceive('getName')
->zeroOrMoreTimes()
->andReturn($type);
return $encoder;
}
}

View File

@@ -0,0 +1,398 @@
<?php
class Swift_Mime_Headers_ParameterizedHeaderTest extends \SwiftMailerTestCase
{
private $_charset = 'utf-8';
private $_lang = 'en-us';
public function testTypeIsParameterizedHeader()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$this->assertEquals(Swift_Mime_Header::TYPE_PARAMETERIZED, $header->getFieldType());
}
public function testValueIsReturnedVerbatim()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setValue('text/plain');
$this->assertEquals('text/plain', $header->getValue());
}
public function testParametersAreAppended()
{
/* -- RFC 2045, 5.1
parameter := attribute "=" value
attribute := token
; Matching of attributes
; is ALWAYS case-insensitive.
value := token / quoted-string
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
or tspecials>
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
*/
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setValue('text/plain');
$header->setParameters(array('charset' => 'utf-8'));
$this->assertEquals('text/plain; charset=utf-8', $header->getFieldBody());
}
public function testSpaceInParamResultsInQuotedString()
{
$header = $this->_getHeader('Content-Disposition',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setValue('attachment');
$header->setParameters(array('filename' => 'my file.txt'));
$this->assertEquals('attachment; filename="my file.txt"',
$header->getFieldBody()
);
}
public function testLongParamsAreBrokenIntoMultipleAttributeStrings()
{
/* -- RFC 2231, 3.
The asterisk character ("*") followed
by a decimal count is employed to indicate that multiple parameters
are being used to encapsulate a single parameter value. The count
starts at 0 and increments by 1 for each subsequent section of the
parameter value. Decimal values are used and neither leading zeroes
nor gaps in the sequence are allowed.
The original parameter value is recovered by concatenating the
various sections of the parameter, in order. For example, the
content-type field
Content-Type: message/external-body; access-type=URL;
URL*0="ftp://";
URL*1="cs.utk.edu/pub/moore/bulk-mailer/bulk-mailer.tar"
is semantically identical to
Content-Type: message/external-body; access-type=URL;
URL="ftp://cs.utk.edu/pub/moore/bulk-mailer/bulk-mailer.tar"
Note that quotes around parameter values are part of the value
syntax; they are NOT part of the value itself. Furthermore, it is
explicitly permitted to have a mixture of quoted and unquoted
continuation fields.
*/
$value = str_repeat('a', 180);
$encoder = $this->_getParameterEncoder();
$encoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), 63, \Mockery::any())
->andReturn(str_repeat('a', 63)."\r\n".
str_repeat('a', 63)."\r\n".str_repeat('a', 54));
$header = $this->_getHeader('Content-Disposition',
$this->_getHeaderEncoder('Q', true), $encoder
);
$header->setValue('attachment');
$header->setParameters(array('filename' => $value));
$header->setMaxLineLength(78);
$this->assertEquals(
'attachment; '.
'filename*0*=utf-8\'\''.str_repeat('a', 63).";\r\n ".
'filename*1*='.str_repeat('a', 63).";\r\n ".
'filename*2*='.str_repeat('a', 54),
$header->getFieldBody()
);
}
public function testEncodedParamDataIncludesCharsetAndLanguage()
{
/* -- RFC 2231, 4.
Asterisks ("*") are reused to provide the indicator that language and
character set information is present and encoding is being used. A
single quote ("'") is used to delimit the character set and language
information at the beginning of the parameter value. Percent signs
("%") are used as the encoding flag, which agrees with RFC 2047.
Specifically, an asterisk at the end of a parameter name acts as an
indicator that character set and language information may appear at
the beginning of the parameter value. A single quote is used to
separate the character set, language, and actual value information in
the parameter value string, and an percent sign is used to flag
octets encoded in hexadecimal. For example:
Content-Type: application/x-stuff;
title*=us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A
Note that it is perfectly permissible to leave either the character
set or language field blank. Note also that the single quote
delimiters MUST be present even when one of the field values is
omitted.
*/
$value = str_repeat('a', 20).pack('C', 0x8F).str_repeat('a', 10);
$encoder = $this->_getParameterEncoder();
$encoder->shouldReceive('encodeString')
->once()
->with($value, 12, 62, \Mockery::any())
->andReturn(str_repeat('a', 20).'%8F'.str_repeat('a', 10));
$header = $this->_getHeader('Content-Disposition',
$this->_getHeaderEncoder('Q', true), $encoder
);
$header->setValue('attachment');
$header->setParameters(array('filename' => $value));
$header->setMaxLineLength(78);
$header->setLanguage($this->_lang);
$this->assertEquals(
'attachment; filename*='.$this->_charset."'".$this->_lang."'".
str_repeat('a', 20).'%8F'.str_repeat('a', 10),
$header->getFieldBody()
);
}
public function testMultipleEncodedParamLinesAreFormattedCorrectly()
{
/* -- RFC 2231, 4.1.
Character set and language information may be combined with the
parameter continuation mechanism. For example:
Content-Type: application/x-stuff
title*0*=us-ascii'en'This%20is%20even%20more%20
title*1*=%2A%2A%2Afun%2A%2A%2A%20
title*2="isn't it!"
Note that:
(1) Language and character set information only appear at
the beginning of a given parameter value.
(2) Continuations do not provide a facility for using more
than one character set or language in the same
parameter value.
(3) A value presented using multiple continuations may
contain a mixture of encoded and unencoded segments.
(4) The first segment of a continuation MUST be encoded if
language and character set information are given.
(5) If the first segment of a continued parameter value is
encoded the language and character set field delimiters
MUST be present even when the fields are left blank.
*/
$value = str_repeat('a', 20).pack('C', 0x8F).str_repeat('a', 60);
$encoder = $this->_getParameterEncoder();
$encoder->shouldReceive('encodeString')
->once()
->with($value, 12, 62, \Mockery::any())
->andReturn(str_repeat('a', 20).'%8F'.str_repeat('a', 28)."\r\n".
str_repeat('a', 32));
$header = $this->_getHeader('Content-Disposition',
$this->_getHeaderEncoder('Q', true), $encoder
);
$header->setValue('attachment');
$header->setParameters(array('filename' => $value));
$header->setMaxLineLength(78);
$header->setLanguage($this->_lang);
$this->assertEquals(
'attachment; filename*0*='.$this->_charset."'".$this->_lang."'".
str_repeat('a', 20).'%8F'.str_repeat('a', 28).";\r\n ".
'filename*1*='.str_repeat('a', 32),
$header->getFieldBody()
);
}
public function testToString()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setValue('text/html');
$header->setParameters(array('charset' => 'utf-8'));
$this->assertEquals('Content-Type: text/html; charset=utf-8'."\r\n",
$header->toString()
);
}
public function testValueCanBeEncodedIfNonAscii()
{
$value = 'fo'.pack('C', 0x8F).'bar';
$encoder = $this->_getHeaderEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo=8Fbar');
$header = $this->_getHeader('X-Foo', $encoder, $this->_getParameterEncoder(true));
$header->setValue($value);
$header->setParameters(array('lookslike' => 'foobar'));
$this->assertEquals('X-Foo: =?utf-8?Q?fo=8Fbar?=; lookslike=foobar'."\r\n",
$header->toString()
);
}
public function testValueAndParamCanBeEncodedIfNonAscii()
{
$value = 'fo'.pack('C', 0x8F).'bar';
$encoder = $this->_getHeaderEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo=8Fbar');
$paramEncoder = $this->_getParameterEncoder();
$paramEncoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo%8Fbar');
$header = $this->_getHeader('X-Foo', $encoder, $paramEncoder);
$header->setValue($value);
$header->setParameters(array('says' => $value));
$this->assertEquals("X-Foo: =?utf-8?Q?fo=8Fbar?=; says*=utf-8''fo%8Fbar\r\n",
$header->toString()
);
}
public function testParamsAreEncodedWithEncodedWordsIfNoParamEncoderSet()
{
$value = 'fo'.pack('C', 0x8F).'bar';
$encoder = $this->_getHeaderEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo=8Fbar');
$header = $this->_getHeader('X-Foo', $encoder, null);
$header->setValue('bar');
$header->setParameters(array('says' => $value));
$this->assertEquals("X-Foo: bar; says=\"=?utf-8?Q?fo=8Fbar?=\"\r\n",
$header->toString()
);
}
public function testLanguageInformationAppearsInEncodedWords()
{
/* -- RFC 2231, 5.
5. Language specification in Encoded Words
RFC 2047 provides support for non-US-ASCII character sets in RFC 822
message header comments, phrases, and any unstructured text field.
This is done by defining an encoded word construct which can appear
in any of these places. Given that these are fields intended for
display, it is sometimes necessary to associate language information
with encoded words as well as just the character set. This
specification extends the definition of an encoded word to allow the
inclusion of such information. This is simply done by suffixing the
character set specification with an asterisk followed by the language
tag. For example:
From: =?US-ASCII*EN?Q?Keith_Moore?= <moore@cs.utk.edu>
*/
$value = 'fo'.pack('C', 0x8F).'bar';
$encoder = $this->_getHeaderEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo=8Fbar');
$paramEncoder = $this->_getParameterEncoder();
$paramEncoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo%8Fbar');
$header = $this->_getHeader('X-Foo', $encoder, $paramEncoder);
$header->setLanguage('en');
$header->setValue($value);
$header->setParameters(array('says' => $value));
$this->assertEquals("X-Foo: =?utf-8*en?Q?fo=8Fbar?=; says*=utf-8'en'fo%8Fbar\r\n",
$header->toString()
);
}
public function testSetBodyModel()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setFieldBodyModel('text/html');
$this->assertEquals('text/html', $header->getValue());
}
public function testGetBodyModel()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setValue('text/plain');
$this->assertEquals('text/plain', $header->getFieldBodyModel());
}
public function testSetParameter()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setParameters(array('charset' => 'utf-8', 'delsp' => 'yes'));
$header->setParameter('delsp', 'no');
$this->assertEquals(array('charset' => 'utf-8', 'delsp' => 'no'),
$header->getParameters()
);
}
public function testGetParameter()
{
$header = $this->_getHeader('Content-Type',
$this->_getHeaderEncoder('Q', true), $this->_getParameterEncoder(true)
);
$header->setParameters(array('charset' => 'utf-8', 'delsp' => 'yes'));
$this->assertEquals('utf-8', $header->getParameter('charset'));
}
private function _getHeader($name, $encoder, $paramEncoder)
{
$header = new Swift_Mime_Headers_ParameterizedHeader($name, $encoder,
$paramEncoder, new Swift_Mime_Grammar()
);
$header->setCharset($this->_charset);
return $header;
}
private function _getHeaderEncoder($type, $stub = false)
{
$encoder = $this->getMockery('Swift_Mime_HeaderEncoder')->shouldIgnoreMissing();
$encoder->shouldReceive('getName')
->zeroOrMoreTimes()
->andReturn($type);
return $encoder;
}
private function _getParameterEncoder($stub = false)
{
return $this->getMockery('Swift_Encoder')->shouldIgnoreMissing();
}
}

View File

@@ -0,0 +1,77 @@
<?php
class Swift_Mime_Headers_PathHeaderTest extends \PHPUnit_Framework_TestCase
{
public function testTypeIsPathHeader()
{
$header = $this->_getHeader('Return-Path');
$this->assertEquals(Swift_Mime_Header::TYPE_PATH, $header->getFieldType());
}
public function testSingleAddressCanBeSetAndFetched()
{
$header = $this->_getHeader('Return-Path');
$header->setAddress('chris@swiftmailer.org');
$this->assertEquals('chris@swiftmailer.org', $header->getAddress());
}
public function testAddressMustComplyWithRfc2822()
{
try {
$header = $this->_getHeader('Return-Path');
$header->setAddress('chr is@swiftmailer.org');
$this->fail('Addresses not valid according to RFC 2822 addr-spec grammar must be rejected.');
} catch (Exception $e) {
}
}
public function testValueIsAngleAddrWithValidAddress()
{
/* -- RFC 2822, 3.6.7.
return = "Return-Path:" path CRLF
path = ([CFWS] "<" ([CFWS] / addr-spec) ">" [CFWS]) /
obs-path
*/
$header = $this->_getHeader('Return-Path');
$header->setAddress('chris@swiftmailer.org');
$this->assertEquals('<chris@swiftmailer.org>', $header->getFieldBody());
}
public function testValueIsEmptyAngleBracketsIfEmptyAddressSet()
{
$header = $this->_getHeader('Return-Path');
$header->setAddress('');
$this->assertEquals('<>', $header->getFieldBody());
}
public function testSetBodyModel()
{
$header = $this->_getHeader('Return-Path');
$header->setFieldBodyModel('foo@bar.tld');
$this->assertEquals('foo@bar.tld', $header->getAddress());
}
public function testGetBodyModel()
{
$header = $this->_getHeader('Return-Path');
$header->setAddress('foo@bar.tld');
$this->assertEquals('foo@bar.tld', $header->getFieldBodyModel());
}
public function testToString()
{
$header = $this->_getHeader('Return-Path');
$header->setAddress('chris@swiftmailer.org');
$this->assertEquals('Return-Path: <chris@swiftmailer.org>'."\r\n",
$header->toString()
);
}
private function _getHeader($name)
{
return new Swift_Mime_Headers_PathHeader($name, new Swift_Mime_Grammar());
}
}

View File

@@ -0,0 +1,355 @@
<?php
class Swift_Mime_Headers_UnstructuredHeaderTest extends \SwiftMailerTestCase
{
private $_charset = 'utf-8';
public function testTypeIsTextHeader()
{
$header = $this->_getHeader('Subject', $this->_getEncoder('Q', true));
$this->assertEquals(Swift_Mime_Header::TYPE_TEXT, $header->getFieldType());
}
public function testGetNameReturnsNameVerbatim()
{
$header = $this->_getHeader('Subject', $this->_getEncoder('Q', true));
$this->assertEquals('Subject', $header->getFieldName());
}
public function testGetValueReturnsValueVerbatim()
{
$header = $this->_getHeader('Subject', $this->_getEncoder('Q', true));
$header->setValue('Test');
$this->assertEquals('Test', $header->getValue());
}
public function testBasicStructureIsKeyValuePair()
{
/* -- RFC 2822, 2.2
Header fields are lines composed of a field name, followed by a colon
(":"), followed by a field body, and terminated by CRLF.
*/
$header = $this->_getHeader('Subject', $this->_getEncoder('Q', true));
$header->setValue('Test');
$this->assertEquals('Subject: Test'."\r\n", $header->toString());
}
public function testLongHeadersAreFoldedAtWordBoundary()
{
/* -- RFC 2822, 2.2.3
Each header field is logically a single line of characters comprising
the field name, the colon, and the field body. For convenience
however, and to deal with the 998/78 character limitations per line,
the field body portion of a header field can be split into a multiple
line representation; this is called "folding". The general rule is
that wherever this standard allows for folding white space (not
simply WSP characters), a CRLF may be inserted before any WSP.
*/
$value = 'The quick brown fox jumped over the fence, he was a very very '.
'scary brown fox with a bushy tail';
$header = $this->_getHeader('X-Custom-Header',
$this->_getEncoder('Q', true)
);
$header->setValue($value);
$header->setMaxLineLength(78); //A safe [RFC 2822, 2.2.3] default
/*
X-Custom-Header: The quick brown fox jumped over the fence, he was a very very
scary brown fox with a bushy tail
*/
$this->assertEquals(
'X-Custom-Header: The quick brown fox jumped over the fence, he was a'.
' very very'."\r\n".//Folding
' scary brown fox with a bushy tail'."\r\n",
$header->toString(), '%s: The header should have been folded at 78th char'
);
}
public function testPrintableAsciiOnlyAppearsInHeaders()
{
/* -- RFC 2822, 2.2.
A field name MUST be composed of printable US-ASCII characters (i.e.,
characters that have values between 33 and 126, inclusive), except
colon. A field body may be composed of any US-ASCII characters,
except for CR and LF.
*/
$nonAsciiChar = pack('C', 0x8F);
$header = $this->_getHeader('X-Test', $this->_getEncoder('Q', true));
$header->setValue($nonAsciiChar);
$this->assertRegExp(
'~^[^:\x00-\x20\x80-\xFF]+: [^\x80-\xFF\r\n]+\r\n$~s',
$header->toString()
);
}
public function testEncodedWordsFollowGeneralStructure()
{
/* -- RFC 2047, 1.
Generally, an "encoded-word" is a sequence of printable ASCII
characters that begins with "=?", ends with "?=", and has two "?"s in
between.
*/
$nonAsciiChar = pack('C', 0x8F);
$header = $this->_getHeader('X-Test', $this->_getEncoder('Q', true));
$header->setValue($nonAsciiChar);
$this->assertRegExp(
'~^X-Test: \=?.*?\?.*?\?.*?\?=\r\n$~s',
$header->toString()
);
}
public function testEncodedWordIncludesCharsetAndEncodingMethodAndText()
{
/* -- RFC 2047, 2.
An 'encoded-word' is defined by the following ABNF grammar. The
notation of RFC 822 is used, with the exception that white space
characters MUST NOT appear between components of an 'encoded-word'.
encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
*/
$nonAsciiChar = pack('C', 0x8F);
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($nonAsciiChar, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('=8F');
$header = $this->_getHeader('X-Test', $encoder);
$header->setValue($nonAsciiChar);
$this->assertEquals(
'X-Test: =?'.$this->_charset.'?Q?=8F?='."\r\n",
$header->toString()
);
}
public function testEncodedWordsAreUsedToEncodedNonPrintableAscii()
{
//SPACE and TAB permitted
$nonPrintableBytes = array_merge(
range(0x00, 0x08), range(0x10, 0x19), array(0x7F)
);
foreach ($nonPrintableBytes as $byte) {
$char = pack('C', $byte);
$encodedChar = sprintf('=%02X', $byte);
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($char, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn($encodedChar);
$header = $this->_getHeader('X-A', $encoder);
$header->setValue($char);
$this->assertEquals(
'X-A: =?'.$this->_charset.'?Q?'.$encodedChar.'?='."\r\n",
$header->toString(), '%s: Non-printable ascii should be encoded'
);
}
}
public function testEncodedWordsAreUsedToEncode8BitOctets()
{
$_8BitBytes = range(0x80, 0xFF);
foreach ($_8BitBytes as $byte) {
$char = pack('C', $byte);
$encodedChar = sprintf('=%02X', $byte);
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($char, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn($encodedChar);
$header = $this->_getHeader('X-A', $encoder);
$header->setValue($char);
$this->assertEquals(
'X-A: =?'.$this->_charset.'?Q?'.$encodedChar.'?='."\r\n",
$header->toString(), '%s: 8-bit octets should be encoded'
);
}
}
public function testEncodedWordsAreNoMoreThan75CharsPerLine()
{
/* -- RFC 2047, 2.
An 'encoded-word' may not be more than 75 characters long, including
'charset', 'encoding', 'encoded-text', and delimiters.
... SNIP ...
While there is no limit to the length of a multiple-line header
field, each line of a header field that contains one or more
'encoded-word's is limited to 76 characters.
*/
$nonAsciiChar = pack('C', 0x8F);
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($nonAsciiChar, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('=8F');
//Note that multi-line headers begin with LWSP which makes 75 + 1 = 76
//Note also that =?utf-8?q??= is 12 chars which makes 75 - 12 = 63
//* X-Test: is 8 chars
$header = $this->_getHeader('X-Test', $encoder);
$header->setValue($nonAsciiChar);
$this->assertEquals(
'X-Test: =?'.$this->_charset.'?Q?=8F?='."\r\n",
$header->toString()
);
}
public function testFWSPIsUsedWhenEncoderReturnsMultipleLines()
{
/* --RFC 2047, 2.
If it is desirable to encode more text than will fit in an 'encoded-word' of
75 characters, multiple 'encoded-word's (separated by CRLF SPACE) may
be used.
*/
//Note the Mock does NOT return 8F encoded, the 8F merely triggers
// encoding for the sake of testing
$nonAsciiChar = pack('C', 0x8F);
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($nonAsciiChar, 8, 63, \Mockery::any())
->andReturn('line_one_here'."\r\n".'line_two_here');
//Note that multi-line headers begin with LWSP which makes 75 + 1 = 76
//Note also that =?utf-8?q??= is 12 chars which makes 75 - 12 = 63
//* X-Test: is 8 chars
$header = $this->_getHeader('X-Test', $encoder);
$header->setValue($nonAsciiChar);
$this->assertEquals(
'X-Test: =?'.$this->_charset.'?Q?line_one_here?='."\r\n".
' =?'.$this->_charset.'?Q?line_two_here?='."\r\n",
$header->toString()
);
}
public function testAdjacentWordsAreEncodedTogether()
{
/* -- RFC 2047, 5 (1)
Ordinary ASCII text and 'encoded-word's may appear together in the
same header field. However, an 'encoded-word' that appears in a
header field defined as '*text' MUST be separated from any adjacent
'encoded-word' or 'text' by 'linear-white-space'.
-- RFC 2047, 2.
IMPORTANT: 'encoded-word's are designed to be recognized as 'atom's
by an RFC 822 parser. As a consequence, unencoded white space
characters (such as SPACE and HTAB) are FORBIDDEN within an
'encoded-word'.
*/
//It would be valid to encode all words needed, however it's probably
// easiest to encode the longest amount required at a time
$word = 'w'.pack('C', 0x8F).'rd';
$text = 'start '.$word.' '.$word.' then end '.$word;
// 'start', ' word word', ' and end', ' word'
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($word.' '.$word, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('w=8Frd_w=8Frd');
$encoder->shouldReceive('encodeString')
->once()
->with($word, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('w=8Frd');
$header = $this->_getHeader('X-Test', $encoder);
$header->setValue($text);
$headerString = $header->toString();
$this->assertEquals('X-Test: start =?'.$this->_charset.'?Q?'.
'w=8Frd_w=8Frd?= then end =?'.$this->_charset.'?Q?'.
'w=8Frd?='."\r\n", $headerString,
'%s: Adjacent encoded words should appear grouped with WSP encoded'
);
}
public function testLanguageInformationAppearsInEncodedWords()
{
/* -- RFC 2231, 5.
5. Language specification in Encoded Words
RFC 2047 provides support for non-US-ASCII character sets in RFC 822
message header comments, phrases, and any unstructured text field.
This is done by defining an encoded word construct which can appear
in any of these places. Given that these are fields intended for
display, it is sometimes necessary to associate language information
with encoded words as well as just the character set. This
specification extends the definition of an encoded word to allow the
inclusion of such information. This is simply done by suffixing the
character set specification with an asterisk followed by the language
tag. For example:
From: =?US-ASCII*EN?Q?Keith_Moore?= <moore@cs.utk.edu>
*/
$value = 'fo'.pack('C', 0x8F).'bar';
$encoder = $this->_getEncoder('Q');
$encoder->shouldReceive('encodeString')
->once()
->with($value, \Mockery::any(), \Mockery::any(), \Mockery::any())
->andReturn('fo=8Fbar');
$header = $this->_getHeader('Subject', $encoder);
$header->setLanguage('en');
$header->setValue($value);
$this->assertEquals("Subject: =?utf-8*en?Q?fo=8Fbar?=\r\n",
$header->toString()
);
}
public function testSetBodyModel()
{
$header = $this->_getHeader('Subject', $this->_getEncoder('Q', true));
$header->setFieldBodyModel('test');
$this->assertEquals('test', $header->getValue());
}
public function testGetBodyModel()
{
$header = $this->_getHeader('Subject', $this->_getEncoder('Q', true));
$header->setValue('test');
$this->assertEquals('test', $header->getFieldBodyModel());
}
private function _getHeader($name, $encoder)
{
$header = new Swift_Mime_Headers_UnstructuredHeader($name, $encoder, new Swift_Mime_Grammar());
$header->setCharset($this->_charset);
return $header;
}
private function _getEncoder($type, $stub = false)
{
$encoder = $this->getMockery('Swift_Mime_HeaderEncoder')->shouldIgnoreMissing();
$encoder->shouldReceive('getName')
->zeroOrMoreTimes()
->andReturn($type);
return $encoder;
}
}

View File

@@ -0,0 +1,231 @@
<?php
class Swift_Mime_MimePartTest extends Swift_Mime_AbstractMimeEntityTest
{
public function testNestingLevelIsSubpart()
{
$part = $this->_createMimePart($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(
Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, $part->getNestingLevel()
);
}
public function testCharsetIsReturnedFromHeader()
{
/* -- RFC 2046, 4.1.2.
A critical parameter that may be specified in the Content-Type field
for "text/plain" data is the character set. This is specified with a
"charset" parameter, as in:
Content-type: text/plain; charset=iso-8859-1
Unlike some other parameter values, the values of the charset
parameter are NOT case sensitive. The default character set, which
must be assumed in the absence of a charset parameter, is US-ASCII.
*/
$cType = $this->_createHeader('Content-Type', 'text/plain',
array('charset' => 'iso-8859-1')
);
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('iso-8859-1', $part->getCharset());
}
public function testCharsetIsSetInHeader()
{
$cType = $this->_createHeader('Content-Type', 'text/plain',
array('charset' => 'iso-8859-1'), false
);
$cType->shouldReceive('setParameter')->once()->with('charset', 'utf-8');
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$part->setCharset('utf-8');
}
public function testCharsetIsSetInHeaderIfPassedToSetBody()
{
$cType = $this->_createHeader('Content-Type', 'text/plain',
array('charset' => 'iso-8859-1'), false
);
$cType->shouldReceive('setParameter')->once()->with('charset', 'utf-8');
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$part->setBody('', 'text/plian', 'utf-8');
}
public function testSettingCharsetNotifiesEncoder()
{
$encoder = $this->_createEncoder('quoted-printable', false);
$encoder->expects($this->once())
->method('charsetChanged')
->with('utf-8');
$part = $this->_createMimePart($this->_createHeaderSet(),
$encoder, $this->_createCache()
);
$part->setCharset('utf-8');
}
public function testSettingCharsetNotifiesHeaders()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('charsetChanged')
->zeroOrMoreTimes()
->with('utf-8');
$part = $this->_createMimePart($headers, $this->_createEncoder(),
$this->_createCache()
);
$part->setCharset('utf-8');
}
public function testSettingCharsetNotifiesChildren()
{
$child = $this->_createChild(0, '', false);
$child->shouldReceive('charsetChanged')
->once()
->with('windows-874');
$part = $this->_createMimePart($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$part->setChildren(array($child));
$part->setCharset('windows-874');
}
public function testCharsetChangeUpdatesCharset()
{
$cType = $this->_createHeader('Content-Type', 'text/plain',
array('charset' => 'iso-8859-1'), false
);
$cType->shouldReceive('setParameter')->once()->with('charset', 'utf-8');
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$part->charsetChanged('utf-8');
}
public function testSettingCharsetClearsCache()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('toString')
->zeroOrMoreTimes()
->andReturn("Content-Type: text/plain; charset=utf-8\r\n");
$cache = $this->_createCache(false);
$entity = $this->_createEntity($headers, $this->_createEncoder(),
$cache
);
$entity->setBody("blah\r\nblah!");
$entity->toString();
// Initialize the expectation here because we only care about what happens in setCharset()
$cache->shouldReceive('clearKey')
->once()
->with(\Mockery::any(), 'body');
$entity->setCharset('iso-2022');
}
public function testFormatIsReturnedFromHeader()
{
/* -- RFC 3676.
*/
$cType = $this->_createHeader('Content-Type', 'text/plain',
array('format' => 'flowed')
);
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('flowed', $part->getFormat());
}
public function testFormatIsSetInHeader()
{
$cType = $this->_createHeader('Content-Type', 'text/plain', array(), false);
$cType->shouldReceive('setParameter')->once()->with('format', 'fixed');
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$part->setFormat('fixed');
}
public function testDelSpIsReturnedFromHeader()
{
/* -- RFC 3676.
*/
$cType = $this->_createHeader('Content-Type', 'text/plain',
array('delsp' => 'no')
);
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$this->assertFalse($part->getDelSp());
}
public function testDelSpIsSetInHeader()
{
$cType = $this->_createHeader('Content-Type', 'text/plain', array(), false);
$cType->shouldReceive('setParameter')->once()->with('delsp', 'yes');
$part = $this->_createMimePart($this->_createHeaderSet(array(
'Content-Type' => $cType, )),
$this->_createEncoder(), $this->_createCache()
);
$part->setDelSp(true);
}
public function testFluidInterface()
{
$part = $this->_createMimePart($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertSame($part,
$part
->setContentType('text/plain')
->setEncoder($this->_createEncoder())
->setId('foo@bar')
->setDescription('my description')
->setMaxLineLength(998)
->setBody('xx')
->setBoundary('xyz')
->setChildren(array())
->setCharset('utf-8')
->setFormat('flowed')
->setDelSp(true)
);
}
//abstract
protected function _createEntity($headers, $encoder, $cache)
{
return $this->_createMimePart($headers, $encoder, $cache);
}
protected function _createMimePart($headers, $encoder, $cache)
{
return new Swift_Mime_MimePart($headers, $encoder, $cache, new Swift_Mime_Grammar());
}
}

View File

@@ -0,0 +1,166 @@
<?php
class Swift_Mime_SimpleHeaderFactoryTest extends \PHPUnit_Framework_TestCase
{
private $_factory;
protected function setUp()
{
$this->_factory = $this->_createFactory();
}
public function testMailboxHeaderIsCorrectType()
{
$header = $this->_factory->createMailboxHeader('X-Foo');
$this->assertInstanceOf('Swift_Mime_Headers_MailboxHeader', $header);
}
public function testMailboxHeaderHasCorrectName()
{
$header = $this->_factory->createMailboxHeader('X-Foo');
$this->assertEquals('X-Foo', $header->getFieldName());
}
public function testMailboxHeaderHasCorrectModel()
{
$header = $this->_factory->createMailboxHeader('X-Foo',
array('foo@bar' => 'FooBar')
);
$this->assertEquals(array('foo@bar' => 'FooBar'), $header->getFieldBodyModel());
}
public function testDateHeaderHasCorrectType()
{
$header = $this->_factory->createDateHeader('X-Date');
$this->assertInstanceOf('Swift_Mime_Headers_DateHeader', $header);
}
public function testDateHeaderHasCorrectName()
{
$header = $this->_factory->createDateHeader('X-Date');
$this->assertEquals('X-Date', $header->getFieldName());
}
public function testDateHeaderHasCorrectModel()
{
$header = $this->_factory->createDateHeader('X-Date', 123);
$this->assertEquals(123, $header->getFieldBodyModel());
}
public function testTextHeaderHasCorrectType()
{
$header = $this->_factory->createTextHeader('X-Foo');
$this->assertInstanceOf('Swift_Mime_Headers_UnstructuredHeader', $header);
}
public function testTextHeaderHasCorrectName()
{
$header = $this->_factory->createTextHeader('X-Foo');
$this->assertEquals('X-Foo', $header->getFieldName());
}
public function testTextHeaderHasCorrectModel()
{
$header = $this->_factory->createTextHeader('X-Foo', 'bar');
$this->assertEquals('bar', $header->getFieldBodyModel());
}
public function testParameterizedHeaderHasCorrectType()
{
$header = $this->_factory->createParameterizedHeader('X-Foo');
$this->assertInstanceOf('Swift_Mime_Headers_ParameterizedHeader', $header);
}
public function testParameterizedHeaderHasCorrectName()
{
$header = $this->_factory->createParameterizedHeader('X-Foo');
$this->assertEquals('X-Foo', $header->getFieldName());
}
public function testParameterizedHeaderHasCorrectModel()
{
$header = $this->_factory->createParameterizedHeader('X-Foo', 'bar');
$this->assertEquals('bar', $header->getFieldBodyModel());
}
public function testParameterizedHeaderHasCorrectParams()
{
$header = $this->_factory->createParameterizedHeader('X-Foo', 'bar',
array('zip' => 'button')
);
$this->assertEquals(array('zip' => 'button'), $header->getParameters());
}
public function testIdHeaderHasCorrectType()
{
$header = $this->_factory->createIdHeader('X-ID');
$this->assertInstanceOf('Swift_Mime_Headers_IdentificationHeader', $header);
}
public function testIdHeaderHasCorrectName()
{
$header = $this->_factory->createIdHeader('X-ID');
$this->assertEquals('X-ID', $header->getFieldName());
}
public function testIdHeaderHasCorrectModel()
{
$header = $this->_factory->createIdHeader('X-ID', 'xyz@abc');
$this->assertEquals(array('xyz@abc'), $header->getFieldBodyModel());
}
public function testPathHeaderHasCorrectType()
{
$header = $this->_factory->createPathHeader('X-Path');
$this->assertInstanceOf('Swift_Mime_Headers_PathHeader', $header);
}
public function testPathHeaderHasCorrectName()
{
$header = $this->_factory->createPathHeader('X-Path');
$this->assertEquals('X-Path', $header->getFieldName());
}
public function testPathHeaderHasCorrectModel()
{
$header = $this->_factory->createPathHeader('X-Path', 'foo@bar');
$this->assertEquals('foo@bar', $header->getFieldBodyModel());
}
public function testCharsetChangeNotificationNotifiesEncoders()
{
$encoder = $this->_createHeaderEncoder();
$encoder->expects($this->once())
->method('charsetChanged')
->with('utf-8');
$paramEncoder = $this->_createParamEncoder();
$paramEncoder->expects($this->once())
->method('charsetChanged')
->with('utf-8');
$factory = $this->_createFactory($encoder, $paramEncoder);
$factory->charsetChanged('utf-8');
}
private function _createFactory($encoder = null, $paramEncoder = null)
{
return new Swift_Mime_SimpleHeaderFactory(
$encoder
? $encoder : $this->_createHeaderEncoder(),
$paramEncoder
? $paramEncoder : $this->_createParamEncoder(),
new Swift_Mime_Grammar()
);
}
private function _createHeaderEncoder()
{
return $this->getMockBuilder('Swift_Mime_HeaderEncoder')->getMock();
}
private function _createParamEncoder()
{
return $this->getMockBuilder('Swift_Encoder')->getMock();
}
}

View File

@@ -0,0 +1,737 @@
<?php
class Swift_Mime_SimpleHeaderSetTest extends \PHPUnit_Framework_TestCase
{
public function testAddMailboxHeaderDelegatesToFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createMailboxHeader')
->with('From', array('person@domain' => 'Person'))
->will($this->returnValue($this->_createHeader('From')));
$set = $this->_createSet($factory);
$set->addMailboxHeader('From', array('person@domain' => 'Person'));
}
public function testAddDateHeaderDelegatesToFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createDateHeader')
->with('Date', 1234)
->will($this->returnValue($this->_createHeader('Date')));
$set = $this->_createSet($factory);
$set->addDateHeader('Date', 1234);
}
public function testAddTextHeaderDelegatesToFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createTextHeader')
->with('Subject', 'some text')
->will($this->returnValue($this->_createHeader('Subject')));
$set = $this->_createSet($factory);
$set->addTextHeader('Subject', 'some text');
}
public function testAddParameterizedHeaderDelegatesToFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createParameterizedHeader')
->with('Content-Type', 'text/plain', array('charset' => 'utf-8'))
->will($this->returnValue($this->_createHeader('Content-Type')));
$set = $this->_createSet($factory);
$set->addParameterizedHeader('Content-Type', 'text/plain',
array('charset' => 'utf-8')
);
}
public function testAddIdHeaderDelegatesToFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($this->_createHeader('Message-ID')));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
}
public function testAddPathHeaderDelegatesToFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createPathHeader')
->with('Return-Path', 'some@path')
->will($this->returnValue($this->_createHeader('Return-Path')));
$set = $this->_createSet($factory);
$set->addPathHeader('Return-Path', 'some@path');
}
public function testHasReturnsFalseWhenNoHeaders()
{
$set = $this->_createSet($this->_createFactory());
$this->assertFalse($set->has('Some-Header'));
}
public function testAddedMailboxHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createMailboxHeader')
->with('From', array('person@domain' => 'Person'))
->will($this->returnValue($this->_createHeader('From')));
$set = $this->_createSet($factory);
$set->addMailboxHeader('From', array('person@domain' => 'Person'));
$this->assertTrue($set->has('From'));
}
public function testAddedDateHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createDateHeader')
->with('Date', 1234)
->will($this->returnValue($this->_createHeader('Date')));
$set = $this->_createSet($factory);
$set->addDateHeader('Date', 1234);
$this->assertTrue($set->has('Date'));
}
public function testAddedTextHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createTextHeader')
->with('Subject', 'some text')
->will($this->returnValue($this->_createHeader('Subject')));
$set = $this->_createSet($factory);
$set->addTextHeader('Subject', 'some text');
$this->assertTrue($set->has('Subject'));
}
public function testAddedParameterizedHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createParameterizedHeader')
->with('Content-Type', 'text/plain', array('charset' => 'utf-8'))
->will($this->returnValue($this->_createHeader('Content-Type')));
$set = $this->_createSet($factory);
$set->addParameterizedHeader('Content-Type', 'text/plain',
array('charset' => 'utf-8')
);
$this->assertTrue($set->has('Content-Type'));
}
public function testAddedIdHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($this->_createHeader('Message-ID')));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertTrue($set->has('Message-ID'));
}
public function testAddedPathHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createPathHeader')
->with('Return-Path', 'some@path')
->will($this->returnValue($this->_createHeader('Return-Path')));
$set = $this->_createSet($factory);
$set->addPathHeader('Return-Path', 'some@path');
$this->assertTrue($set->has('Return-Path'));
}
public function testNewlySetHeaderIsSeenByHas()
{
$factory = $this->_createFactory();
$header = $this->_createHeader('X-Foo', 'bar');
$set = $this->_createSet($factory);
$set->set($header);
$this->assertTrue($set->has('X-Foo'));
}
public function testHasCanAcceptOffset()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($this->_createHeader('Message-ID')));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertTrue($set->has('Message-ID', 0));
}
public function testHasWithIllegalOffsetReturnsFalse()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($this->_createHeader('Message-ID')));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertFalse($set->has('Message-ID', 1));
}
public function testHasCanDistinguishMultipleHeaders()
{
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($this->_createHeader('Message-ID')));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Message-ID', 'other@id')
->will($this->returnValue($this->_createHeader('Message-ID')));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Message-ID', 'other@id');
$this->assertTrue($set->has('Message-ID', 1));
}
public function testGetWithUnspecifiedOffset()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertSame($header, $set->get('Message-ID'));
}
public function testGetWithSpeiciedOffset()
{
$header0 = $this->_createHeader('Message-ID');
$header1 = $this->_createHeader('Message-ID');
$header2 = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header0));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Message-ID', 'other@id')
->will($this->returnValue($header1));
$factory->expects($this->at(2))
->method('createIdHeader')
->with('Message-ID', 'more@id')
->will($this->returnValue($header2));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Message-ID', 'other@id');
$set->addIdHeader('Message-ID', 'more@id');
$this->assertSame($header1, $set->get('Message-ID', 1));
}
public function testGetReturnsNullIfHeaderNotSet()
{
$set = $this->_createSet($this->_createFactory());
$this->assertNull($set->get('Message-ID', 99));
}
public function testGetAllReturnsAllHeadersMatchingName()
{
$header0 = $this->_createHeader('Message-ID');
$header1 = $this->_createHeader('Message-ID');
$header2 = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header0));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Message-ID', 'other@id')
->will($this->returnValue($header1));
$factory->expects($this->at(2))
->method('createIdHeader')
->with('Message-ID', 'more@id')
->will($this->returnValue($header2));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Message-ID', 'other@id');
$set->addIdHeader('Message-ID', 'more@id');
$this->assertEquals(array($header0, $header1, $header2),
$set->getAll('Message-ID')
);
}
public function testGetAllReturnsAllHeadersIfNoArguments()
{
$header0 = $this->_createHeader('Message-ID');
$header1 = $this->_createHeader('Subject');
$header2 = $this->_createHeader('To');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header0));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Subject', 'thing')
->will($this->returnValue($header1));
$factory->expects($this->at(2))
->method('createIdHeader')
->with('To', 'person@example.org')
->will($this->returnValue($header2));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Subject', 'thing');
$set->addIdHeader('To', 'person@example.org');
$this->assertEquals(array($header0, $header1, $header2),
$set->getAll()
);
}
public function testGetAllReturnsEmptyArrayIfNoneSet()
{
$set = $this->_createSet($this->_createFactory());
$this->assertEquals(array(), $set->getAll('Received'));
}
public function testRemoveWithUnspecifiedOffset()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->remove('Message-ID');
$this->assertFalse($set->has('Message-ID'));
}
public function testRemoveWithSpecifiedIndexRemovesHeader()
{
$header0 = $this->_createHeader('Message-ID');
$header1 = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header0));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Message-ID', 'other@id')
->will($this->returnValue($header1));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Message-ID', 'other@id');
$set->remove('Message-ID', 0);
$this->assertFalse($set->has('Message-ID', 0));
$this->assertTrue($set->has('Message-ID', 1));
$this->assertTrue($set->has('Message-ID'));
$set->remove('Message-ID', 1);
$this->assertFalse($set->has('Message-ID', 1));
$this->assertFalse($set->has('Message-ID'));
}
public function testRemoveWithSpecifiedIndexLeavesOtherHeaders()
{
$header0 = $this->_createHeader('Message-ID');
$header1 = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header0));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Message-ID', 'other@id')
->will($this->returnValue($header1));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Message-ID', 'other@id');
$set->remove('Message-ID', 1);
$this->assertTrue($set->has('Message-ID', 0));
}
public function testRemoveWithInvalidOffsetDoesNothing()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->remove('Message-ID', 50);
$this->assertTrue($set->has('Message-ID'));
}
public function testRemoveAllRemovesAllHeadersWithName()
{
$header0 = $this->_createHeader('Message-ID');
$header1 = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header0));
$factory->expects($this->at(1))
->method('createIdHeader')
->with('Message-ID', 'other@id')
->will($this->returnValue($header1));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->addIdHeader('Message-ID', 'other@id');
$set->removeAll('Message-ID');
$this->assertFalse($set->has('Message-ID', 0));
$this->assertFalse($set->has('Message-ID', 1));
}
public function testHasIsNotCaseSensitive()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertTrue($set->has('message-id'));
}
public function testGetIsNotCaseSensitive()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertSame($header, $set->get('message-id'));
}
public function testGetAllIsNotCaseSensitive()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$this->assertEquals(array($header), $set->getAll('message-id'));
}
public function testRemoveIsNotCaseSensitive()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->remove('message-id');
$this->assertFalse($set->has('Message-ID'));
}
public function testRemoveAllIsNotCaseSensitive()
{
$header = $this->_createHeader('Message-ID');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createIdHeader')
->with('Message-ID', 'some@id')
->will($this->returnValue($header));
$set = $this->_createSet($factory);
$set->addIdHeader('Message-ID', 'some@id');
$set->removeAll('message-id');
$this->assertFalse($set->has('Message-ID'));
}
public function testNewInstance()
{
$set = $this->_createSet($this->_createFactory());
$instance = $set->newInstance();
$this->assertInstanceOf('Swift_Mime_HeaderSet', $instance);
}
public function testToStringJoinsHeadersTogether()
{
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Foo', 'bar')
->will($this->returnValue($this->_createHeader('Foo', 'bar')));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('Zip', 'buttons')
->will($this->returnValue($this->_createHeader('Zip', 'buttons')));
$set = $this->_createSet($factory);
$set->addTextHeader('Foo', 'bar');
$set->addTextHeader('Zip', 'buttons');
$this->assertEquals(
"Foo: bar\r\n".
"Zip: buttons\r\n",
$set->toString()
);
}
public function testHeadersWithoutBodiesAreNotDisplayed()
{
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Foo', 'bar')
->will($this->returnValue($this->_createHeader('Foo', 'bar')));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('Zip', '')
->will($this->returnValue($this->_createHeader('Zip', '')));
$set = $this->_createSet($factory);
$set->addTextHeader('Foo', 'bar');
$set->addTextHeader('Zip', '');
$this->assertEquals(
"Foo: bar\r\n",
$set->toString()
);
}
public function testHeadersWithoutBodiesCanBeForcedToDisplay()
{
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Foo', '')
->will($this->returnValue($this->_createHeader('Foo', '')));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('Zip', '')
->will($this->returnValue($this->_createHeader('Zip', '')));
$set = $this->_createSet($factory);
$set->addTextHeader('Foo', '');
$set->addTextHeader('Zip', '');
$set->setAlwaysDisplayed(array('Foo', 'Zip'));
$this->assertEquals(
"Foo: \r\n".
"Zip: \r\n",
$set->toString()
);
}
public function testHeaderSequencesCanBeSpecified()
{
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Third', 'three')
->will($this->returnValue($this->_createHeader('Third', 'three')));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('First', 'one')
->will($this->returnValue($this->_createHeader('First', 'one')));
$factory->expects($this->at(2))
->method('createTextHeader')
->with('Second', 'two')
->will($this->returnValue($this->_createHeader('Second', 'two')));
$set = $this->_createSet($factory);
$set->addTextHeader('Third', 'three');
$set->addTextHeader('First', 'one');
$set->addTextHeader('Second', 'two');
$set->defineOrdering(array('First', 'Second', 'Third'));
$this->assertEquals(
"First: one\r\n".
"Second: two\r\n".
"Third: three\r\n",
$set->toString()
);
}
public function testUnsortedHeadersAppearAtEnd()
{
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Fourth', 'four')
->will($this->returnValue($this->_createHeader('Fourth', 'four')));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('Fifth', 'five')
->will($this->returnValue($this->_createHeader('Fifth', 'five')));
$factory->expects($this->at(2))
->method('createTextHeader')
->with('Third', 'three')
->will($this->returnValue($this->_createHeader('Third', 'three')));
$factory->expects($this->at(3))
->method('createTextHeader')
->with('First', 'one')
->will($this->returnValue($this->_createHeader('First', 'one')));
$factory->expects($this->at(4))
->method('createTextHeader')
->with('Second', 'two')
->will($this->returnValue($this->_createHeader('Second', 'two')));
$set = $this->_createSet($factory);
$set->addTextHeader('Fourth', 'four');
$set->addTextHeader('Fifth', 'five');
$set->addTextHeader('Third', 'three');
$set->addTextHeader('First', 'one');
$set->addTextHeader('Second', 'two');
$set->defineOrdering(array('First', 'Second', 'Third'));
$this->assertEquals(
"First: one\r\n".
"Second: two\r\n".
"Third: three\r\n".
"Fourth: four\r\n".
"Fifth: five\r\n",
$set->toString()
);
}
public function testSettingCharsetNotifiesAlreadyExistingHeaders()
{
$subject = $this->_createHeader('Subject', 'some text');
$xHeader = $this->_createHeader('X-Header', 'some text');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Subject', 'some text')
->will($this->returnValue($subject));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('X-Header', 'some text')
->will($this->returnValue($xHeader));
$subject->expects($this->once())
->method('setCharset')
->with('utf-8');
$xHeader->expects($this->once())
->method('setCharset')
->with('utf-8');
$set = $this->_createSet($factory);
$set->addTextHeader('Subject', 'some text');
$set->addTextHeader('X-Header', 'some text');
$set->setCharset('utf-8');
}
public function testCharsetChangeNotifiesAlreadyExistingHeaders()
{
$subject = $this->_createHeader('Subject', 'some text');
$xHeader = $this->_createHeader('X-Header', 'some text');
$factory = $this->_createFactory();
$factory->expects($this->at(0))
->method('createTextHeader')
->with('Subject', 'some text')
->will($this->returnValue($subject));
$factory->expects($this->at(1))
->method('createTextHeader')
->with('X-Header', 'some text')
->will($this->returnValue($xHeader));
$subject->expects($this->once())
->method('setCharset')
->with('utf-8');
$xHeader->expects($this->once())
->method('setCharset')
->with('utf-8');
$set = $this->_createSet($factory);
$set->addTextHeader('Subject', 'some text');
$set->addTextHeader('X-Header', 'some text');
$set->charsetChanged('utf-8');
}
public function testCharsetChangeNotifiesFactory()
{
$factory = $this->_createFactory();
$factory->expects($this->once())
->method('charsetChanged')
->with('utf-8');
$set = $this->_createSet($factory);
$set->setCharset('utf-8');
}
private function _createSet($factory)
{
return new Swift_Mime_SimpleHeaderSet($factory);
}
private function _createFactory()
{
return $this->getMockBuilder('Swift_Mime_HeaderFactory')->getMock();
}
private function _createHeader($name, $body = '')
{
$header = $this->getMockBuilder('Swift_Mime_Header')->getMock();
$header->expects($this->any())
->method('getFieldName')
->will($this->returnValue($name));
$header->expects($this->any())
->method('toString')
->will($this->returnValue(sprintf("%s: %s\r\n", $name, $body)));
$header->expects($this->any())
->method('getFieldBody')
->will($this->returnValue($body));
return $header;
}
}

View File

@@ -0,0 +1,827 @@
<?php
class Swift_Mime_SimpleMessageTest extends Swift_Mime_MimePartTest
{
public function testNestingLevelIsSubpart()
{
//Overridden
}
public function testNestingLevelIsTop()
{
$message = $this->_createMessage($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(
Swift_Mime_MimeEntity::LEVEL_TOP, $message->getNestingLevel()
);
}
public function testDateIsReturnedFromHeader()
{
$date = $this->_createHeader('Date', 123);
$message = $this->_createMessage(
$this->_createHeaderSet(array('Date' => $date)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(123, $message->getDate());
}
public function testDateIsSetInHeader()
{
$date = $this->_createHeader('Date', 123, array(), false);
$date->shouldReceive('setFieldBodyModel')
->once()
->with(1234);
$date->shouldReceive('setFieldBodyModel')
->zeroOrMoreTimes();
$message = $this->_createMessage(
$this->_createHeaderSet(array('Date' => $date)),
$this->_createEncoder(), $this->_createCache()
);
$message->setDate(1234);
}
public function testDateHeaderIsCreatedIfNonePresent()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addDateHeader')
->once()
->with('Date', 1234);
$headers->shouldReceive('addDateHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setDate(1234);
}
public function testDateHeaderIsAddedDuringConstruction()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addDateHeader')
->once()
->with('Date', '/^[0-9]+$/D');
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
}
public function testIdIsReturnedFromHeader()
{
/* -- RFC 2045, 7.
In constructing a high-level user agent, it may be desirable to allow
one body to make reference to another. Accordingly, bodies may be
labelled using the "Content-ID" header field, which is syntactically
identical to the "Message-ID" header field
*/
$messageId = $this->_createHeader('Message-ID', 'a@b');
$message = $this->_createMessage(
$this->_createHeaderSet(array('Message-ID' => $messageId)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('a@b', $message->getId());
}
public function testIdIsSetInHeader()
{
$messageId = $this->_createHeader('Message-ID', 'a@b', array(), false);
$messageId->shouldReceive('setFieldBodyModel')
->once()
->with('x@y');
$messageId->shouldReceive('setFieldBodyModel')
->zeroOrMoreTimes();
$message = $this->_createMessage(
$this->_createHeaderSet(array('Message-ID' => $messageId)),
$this->_createEncoder(), $this->_createCache()
);
$message->setId('x@y');
}
public function testIdIsAutoGenerated()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addIdHeader')
->once()
->with('Message-ID', '/^.*?@.*?$/D');
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
}
public function testSubjectIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.5.
*/
$subject = $this->_createHeader('Subject', 'example subject');
$message = $this->_createMessage(
$this->_createHeaderSet(array('Subject' => $subject)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('example subject', $message->getSubject());
}
public function testSubjectIsSetInHeader()
{
$subject = $this->_createHeader('Subject', '', array(), false);
$subject->shouldReceive('setFieldBodyModel')
->once()
->with('foo');
$message = $this->_createMessage(
$this->_createHeaderSet(array('Subject' => $subject)),
$this->_createEncoder(), $this->_createCache()
);
$message->setSubject('foo');
}
public function testSubjectHeaderIsCreatedIfNotPresent()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addTextHeader')
->once()
->with('Subject', 'example subject');
$headers->shouldReceive('addTextHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setSubject('example subject');
}
public function testReturnPathIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.7.
*/
$path = $this->_createHeader('Return-Path', 'bounces@domain');
$message = $this->_createMessage(
$this->_createHeaderSet(array('Return-Path' => $path)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('bounces@domain', $message->getReturnPath());
}
public function testReturnPathIsSetInHeader()
{
$path = $this->_createHeader('Return-Path', '', array(), false);
$path->shouldReceive('setFieldBodyModel')
->once()
->with('bounces@domain');
$message = $this->_createMessage(
$this->_createHeaderSet(array('Return-Path' => $path)),
$this->_createEncoder(), $this->_createCache()
);
$message->setReturnPath('bounces@domain');
}
public function testReturnPathHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addPathHeader')
->once()
->with('Return-Path', 'bounces@domain');
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setReturnPath('bounces@domain');
}
public function testSenderIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.2.
*/
$sender = $this->_createHeader('Sender', array('sender@domain' => 'Name'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Sender' => $sender)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('sender@domain' => 'Name'), $message->getSender());
}
public function testSenderIsSetInHeader()
{
$sender = $this->_createHeader('Sender', array('sender@domain' => 'Name'),
array(), false
);
$sender->shouldReceive('setFieldBodyModel')
->once()
->with(array('other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Sender' => $sender)),
$this->_createEncoder(), $this->_createCache()
);
$message->setSender(array('other@domain' => 'Other'));
}
public function testSenderHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Sender', (array) 'sender@domain');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setSender('sender@domain');
}
public function testNameCanBeUsedInSenderHeader()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Sender', array('sender@domain' => 'Name'));
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setSender('sender@domain', 'Name');
}
public function testFromIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.2.
*/
$from = $this->_createHeader('From', array('from@domain' => 'Name'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('From' => $from)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('from@domain' => 'Name'), $message->getFrom());
}
public function testFromIsSetInHeader()
{
$from = $this->_createHeader('From', array('from@domain' => 'Name'),
array(), false
);
$from->shouldReceive('setFieldBodyModel')
->once()
->with(array('other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('From' => $from)),
$this->_createEncoder(), $this->_createCache()
);
$message->setFrom(array('other@domain' => 'Other'));
}
public function testFromIsAddedToHeadersDuringAddFrom()
{
$from = $this->_createHeader('From', array('from@domain' => 'Name'),
array(), false
);
$from->shouldReceive('setFieldBodyModel')
->once()
->with(array('from@domain' => 'Name', 'other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('From' => $from)),
$this->_createEncoder(), $this->_createCache()
);
$message->addFrom('other@domain', 'Other');
}
public function testFromHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('From', (array) 'from@domain');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setFrom('from@domain');
}
public function testPersonalNameCanBeUsedInFromAddress()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('From', array('from@domain' => 'Name'));
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setFrom('from@domain', 'Name');
}
public function testReplyToIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.2.
*/
$reply = $this->_createHeader('Reply-To', array('reply@domain' => 'Name'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Reply-To' => $reply)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('reply@domain' => 'Name'), $message->getReplyTo());
}
public function testReplyToIsSetInHeader()
{
$reply = $this->_createHeader('Reply-To', array('reply@domain' => 'Name'),
array(), false
);
$reply->shouldReceive('setFieldBodyModel')
->once()
->with(array('other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Reply-To' => $reply)),
$this->_createEncoder(), $this->_createCache()
);
$message->setReplyTo(array('other@domain' => 'Other'));
}
public function testReplyToIsAddedToHeadersDuringAddReplyTo()
{
$replyTo = $this->_createHeader('Reply-To', array('from@domain' => 'Name'),
array(), false
);
$replyTo->shouldReceive('setFieldBodyModel')
->once()
->with(array('from@domain' => 'Name', 'other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Reply-To' => $replyTo)),
$this->_createEncoder(), $this->_createCache()
);
$message->addReplyTo('other@domain', 'Other');
}
public function testReplyToHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Reply-To', (array) 'reply@domain');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setReplyTo('reply@domain');
}
public function testNameCanBeUsedInReplyTo()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Reply-To', array('reply@domain' => 'Name'));
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setReplyTo('reply@domain', 'Name');
}
public function testToIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.3.
*/
$to = $this->_createHeader('To', array('to@domain' => 'Name'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('To' => $to)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('to@domain' => 'Name'), $message->getTo());
}
public function testToIsSetInHeader()
{
$to = $this->_createHeader('To', array('to@domain' => 'Name'),
array(), false
);
$to->shouldReceive('setFieldBodyModel')
->once()
->with(array('other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('To' => $to)),
$this->_createEncoder(), $this->_createCache()
);
$message->setTo(array('other@domain' => 'Other'));
}
public function testToIsAddedToHeadersDuringAddTo()
{
$to = $this->_createHeader('To', array('from@domain' => 'Name'),
array(), false
);
$to->shouldReceive('setFieldBodyModel')
->once()
->with(array('from@domain' => 'Name', 'other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('To' => $to)),
$this->_createEncoder(), $this->_createCache()
);
$message->addTo('other@domain', 'Other');
}
public function testToHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('To', (array) 'to@domain');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setTo('to@domain');
}
public function testNameCanBeUsedInToHeader()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('To', array('to@domain' => 'Name'));
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setTo('to@domain', 'Name');
}
public function testCcIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.3.
*/
$cc = $this->_createHeader('Cc', array('cc@domain' => 'Name'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Cc' => $cc)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('cc@domain' => 'Name'), $message->getCc());
}
public function testCcIsSetInHeader()
{
$cc = $this->_createHeader('Cc', array('cc@domain' => 'Name'),
array(), false
);
$cc->shouldReceive('setFieldBodyModel')
->once()
->with(array('other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Cc' => $cc)),
$this->_createEncoder(), $this->_createCache()
);
$message->setCc(array('other@domain' => 'Other'));
}
public function testCcIsAddedToHeadersDuringAddCc()
{
$cc = $this->_createHeader('Cc', array('from@domain' => 'Name'),
array(), false
);
$cc->shouldReceive('setFieldBodyModel')
->once()
->with(array('from@domain' => 'Name', 'other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Cc' => $cc)),
$this->_createEncoder(), $this->_createCache()
);
$message->addCc('other@domain', 'Other');
}
public function testCcHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Cc', (array) 'cc@domain');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setCc('cc@domain');
}
public function testNameCanBeUsedInCcHeader()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Cc', array('cc@domain' => 'Name'));
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setCc('cc@domain', 'Name');
}
public function testBccIsReturnedFromHeader()
{
/* -- RFC 2822, 3.6.3.
*/
$bcc = $this->_createHeader('Bcc', array('bcc@domain' => 'Name'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Bcc' => $bcc)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('bcc@domain' => 'Name'), $message->getBcc());
}
public function testBccIsSetInHeader()
{
$bcc = $this->_createHeader('Bcc', array('bcc@domain' => 'Name'),
array(), false
);
$bcc->shouldReceive('setFieldBodyModel')
->once()
->with(array('other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Bcc' => $bcc)),
$this->_createEncoder(), $this->_createCache()
);
$message->setBcc(array('other@domain' => 'Other'));
}
public function testBccIsAddedToHeadersDuringAddBcc()
{
$bcc = $this->_createHeader('Bcc', array('from@domain' => 'Name'),
array(), false
);
$bcc->shouldReceive('setFieldBodyModel')
->once()
->with(array('from@domain' => 'Name', 'other@domain' => 'Other'));
$message = $this->_createMessage(
$this->_createHeaderSet(array('Bcc' => $bcc)),
$this->_createEncoder(), $this->_createCache()
);
$message->addBcc('other@domain', 'Other');
}
public function testBccHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Bcc', (array) 'bcc@domain');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setBcc('bcc@domain');
}
public function testNameCanBeUsedInBcc()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Bcc', array('bcc@domain' => 'Name'));
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setBcc('bcc@domain', 'Name');
}
public function testPriorityIsReadFromHeader()
{
$prio = $this->_createHeader('X-Priority', '2 (High)');
$message = $this->_createMessage(
$this->_createHeaderSet(array('X-Priority' => $prio)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(2, $message->getPriority());
}
public function testPriorityIsSetInHeader()
{
$prio = $this->_createHeader('X-Priority', '2 (High)', array(), false);
$prio->shouldReceive('setFieldBodyModel')
->once()
->with('5 (Lowest)');
$message = $this->_createMessage(
$this->_createHeaderSet(array('X-Priority' => $prio)),
$this->_createEncoder(), $this->_createCache()
);
$message->setPriority($message::PRIORITY_LOWEST);
}
public function testPriorityHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addTextHeader')
->once()
->with('X-Priority', '4 (Low)');
$headers->shouldReceive('addTextHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setPriority($message::PRIORITY_LOW);
}
public function testReadReceiptAddressReadFromHeader()
{
$rcpt = $this->_createHeader('Disposition-Notification-To',
array('chris@swiftmailer.org' => 'Chris')
);
$message = $this->_createMessage(
$this->_createHeaderSet(array('Disposition-Notification-To' => $rcpt)),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals(array('chris@swiftmailer.org' => 'Chris'),
$message->getReadReceiptTo()
);
}
public function testReadReceiptIsSetInHeader()
{
$rcpt = $this->_createHeader('Disposition-Notification-To', array(), array(), false);
$rcpt->shouldReceive('setFieldBodyModel')
->once()
->with('mark@swiftmailer.org');
$message = $this->_createMessage(
$this->_createHeaderSet(array('Disposition-Notification-To' => $rcpt)),
$this->_createEncoder(), $this->_createCache()
);
$message->setReadReceiptTo('mark@swiftmailer.org');
}
public function testReadReceiptHeaderIsAddedIfNoneSet()
{
$headers = $this->_createHeaderSet(array(), false);
$headers->shouldReceive('addMailboxHeader')
->once()
->with('Disposition-Notification-To', 'mark@swiftmailer.org');
$headers->shouldReceive('addMailboxHeader')
->zeroOrMoreTimes();
$message = $this->_createMessage($headers, $this->_createEncoder(),
$this->_createCache()
);
$message->setReadReceiptTo('mark@swiftmailer.org');
}
public function testChildrenCanBeAttached()
{
$child1 = $this->_createChild();
$child2 = $this->_createChild();
$message = $this->_createMessage($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$message->attach($child1);
$message->attach($child2);
$this->assertEquals(array($child1, $child2), $message->getChildren());
}
public function testChildrenCanBeDetached()
{
$child1 = $this->_createChild();
$child2 = $this->_createChild();
$message = $this->_createMessage($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$message->attach($child1);
$message->attach($child2);
$message->detach($child1);
$this->assertEquals(array($child2), $message->getChildren());
}
public function testEmbedAttachesChild()
{
$child = $this->_createChild();
$message = $this->_createMessage($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$message->embed($child);
$this->assertEquals(array($child), $message->getChildren());
}
public function testEmbedReturnsValidCid()
{
$child = $this->_createChild(Swift_Mime_MimeEntity::LEVEL_RELATED, '',
false
);
$child->shouldReceive('getId')
->zeroOrMoreTimes()
->andReturn('foo@bar');
$message = $this->_createMessage($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertEquals('cid:foo@bar', $message->embed($child));
}
public function testFluidInterface()
{
$child = $this->_createChild();
$message = $this->_createMessage($this->_createHeaderSet(),
$this->_createEncoder(), $this->_createCache()
);
$this->assertSame($message,
$message
->setContentType('text/plain')
->setEncoder($this->_createEncoder())
->setId('foo@bar')
->setDescription('my description')
->setMaxLineLength(998)
->setBody('xx')
->setBoundary('xyz')
->setChildren(array())
->setCharset('iso-8859-1')
->setFormat('flowed')
->setDelSp(false)
->setSubject('subj')
->setDate(123)
->setReturnPath('foo@bar')
->setSender('foo@bar')
->setFrom(array('x@y' => 'XY'))
->setReplyTo(array('ab@cd' => 'ABCD'))
->setTo(array('chris@site.tld', 'mark@site.tld'))
->setCc('john@somewhere.tld')
->setBcc(array('one@site', 'two@site' => 'Two'))
->setPriority($message::PRIORITY_LOW)
->setReadReceiptTo('a@b')
->attach($child)
->detach($child)
);
}
//abstract
protected function _createEntity($headers, $encoder, $cache)
{
return $this->_createMessage($headers, $encoder, $cache);
}
protected function _createMimePart($headers, $encoder, $cache)
{
return $this->_createMessage($headers, $encoder, $cache);
}
private function _createMessage($headers, $encoder, $cache)
{
return new Swift_Mime_SimpleMessage($headers, $encoder, $cache, new Swift_Mime_Grammar());
}
}

View File

@@ -0,0 +1,9 @@
<?php
class Swift_Mime_SimpleMimeEntityTest extends Swift_Mime_AbstractMimeEntityTest
{
protected function _createEntity($headerFactory, $encoder, $cache)
{
return new Swift_Mime_SimpleMimeEntity($headerFactory, $encoder, $cache, new Swift_Mime_Grammar());
}
}