summaryrefslogtreecommitdiff
path: root/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers')
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/DateHeaderTest.php69
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/IdentificationHeaderTest.php189
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/MailboxHeaderTest.php327
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/ParameterizedHeaderTest.php398
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/PathHeaderTest.php77
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/UnstructuredHeaderTest.php355
6 files changed, 1415 insertions, 0 deletions
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/DateHeaderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/DateHeaderTest.php
new file mode 100644
index 0000000..1822ea6
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/DateHeaderTest.php
@@ -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());
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/IdentificationHeaderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/IdentificationHeaderTest.php
new file mode 100644
index 0000000..93b3f60
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/IdentificationHeaderTest.php
@@ -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());
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/MailboxHeaderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/MailboxHeaderTest.php
new file mode 100644
index 0000000..0713ff4
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/MailboxHeaderTest.php
@@ -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;
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/ParameterizedHeaderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/ParameterizedHeaderTest.php
new file mode 100644
index 0000000..cd027cc
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/ParameterizedHeaderTest.php
@@ -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();
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/PathHeaderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/PathHeaderTest.php
new file mode 100644
index 0000000..a9f35e9
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/PathHeaderTest.php
@@ -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());
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/UnstructuredHeaderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/UnstructuredHeaderTest.php
new file mode 100644
index 0000000..2e1dc8c
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/Headers/UnstructuredHeaderTest.php
@@ -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;
+ }
+}