diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2019-11-17 20:45:02 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2019-11-17 20:45:02 +0100 |
commit | 8df3db566a3a937b45ebf11adb90d265e6f5e2d4 (patch) | |
tree | 4d541098d751d5a9acf8c12f6fb9f308ace066ac /vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime | |
download | flyspray-8df3db566a3a937b45ebf11adb90d265e6f5e2d4.tar.xz |
initial checking of customized version 1.0rc9
Diffstat (limited to 'vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime')
19 files changed, 6094 insertions, 0 deletions
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AbstractMimeEntityTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AbstractMimeEntityTest.php new file mode 100644 index 0000000..3efe6ec --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AbstractMimeEntityTest.php @@ -0,0 +1,1092 @@ +<?php + +require_once dirname(dirname(dirname(__DIR__))).'/fixtures/MimeEntityFixture.php'; + +abstract class Swift_Mime_AbstractMimeEntityTest extends \SwiftMailerTestCase +{ + public function testGetHeadersReturnsHeaderSet() + { + $headers = $this->_createHeaderSet(); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $this->assertSame($headers, $entity->getHeaders()); + } + + public function testContentTypeIsReturnedFromHeader() + { + $ctype = $this->_createHeader('Content-Type', 'image/jpeg-test'); + $headers = $this->_createHeaderSet(array('Content-Type' => $ctype)); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $this->assertEquals('image/jpeg-test', $entity->getContentType()); + } + + public function testContentTypeIsSetInHeader() + { + $ctype = $this->_createHeader('Content-Type', 'text/plain', array(), false); + $headers = $this->_createHeaderSet(array('Content-Type' => $ctype)); + + $ctype->shouldReceive('setFieldBodyModel') + ->once() + ->with('image/jpeg'); + $ctype->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes() + ->with(\Mockery::not('image/jpeg')); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setContentType('image/jpeg'); + } + + public function testContentTypeHeaderIsAddedIfNoneSet() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('addParameterizedHeader') + ->once() + ->with('Content-Type', 'image/jpeg'); + $headers->shouldReceive('addParameterizedHeader') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setContentType('image/jpeg'); + } + + public function testContentTypeCanBeSetViaSetBody() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('addParameterizedHeader') + ->once() + ->with('Content-Type', 'text/html'); + $headers->shouldReceive('addParameterizedHeader') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBody('<b>foo</b>', 'text/html'); + } + + public function testGetEncoderFromConstructor() + { + $encoder = $this->_createEncoder('base64'); + $entity = $this->_createEntity($this->_createHeaderSet(), $encoder, + $this->_createCache() + ); + $this->assertSame($encoder, $entity->getEncoder()); + } + + public function testSetAndGetEncoder() + { + $encoder = $this->_createEncoder('base64'); + $headers = $this->_createHeaderSet(); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setEncoder($encoder); + $this->assertSame($encoder, $entity->getEncoder()); + } + + public function testSettingEncoderUpdatesTransferEncoding() + { + $encoder = $this->_createEncoder('base64'); + $encoding = $this->_createHeader( + 'Content-Transfer-Encoding', '8bit', array(), false + ); + $headers = $this->_createHeaderSet(array( + 'Content-Transfer-Encoding' => $encoding, + )); + $encoding->shouldReceive('setFieldBodyModel') + ->once() + ->with('base64'); + $encoding->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setEncoder($encoder); + } + + public function testSettingEncoderAddsEncodingHeaderIfNonePresent() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('addTextHeader') + ->once() + ->with('Content-Transfer-Encoding', 'something'); + $headers->shouldReceive('addTextHeader') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setEncoder($this->_createEncoder('something')); + } + + 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 + */ + + $cid = $this->_createHeader('Content-ID', 'zip@button'); + $headers = $this->_createHeaderSet(array('Content-ID' => $cid)); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $this->assertEquals('zip@button', $entity->getId()); + } + + public function testIdIsSetInHeader() + { + $cid = $this->_createHeader('Content-ID', 'zip@button', array(), false); + $headers = $this->_createHeaderSet(array('Content-ID' => $cid)); + + $cid->shouldReceive('setFieldBodyModel') + ->once() + ->with('foo@bar'); + $cid->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setId('foo@bar'); + } + + public function testIdIsAutoGenerated() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $this->assertRegExp('/^.*?@.*?$/D', $entity->getId()); + } + + public function testGenerateIdCreatesNewId() + { + $headers = $this->_createHeaderSet(); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $id1 = $entity->generateId(); + $id2 = $entity->generateId(); + $this->assertNotEquals($id1, $id2); + } + + public function testGenerateIdSetsNewId() + { + $headers = $this->_createHeaderSet(); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $id = $entity->generateId(); + $this->assertEquals($id, $entity->getId()); + } + + public function testDescriptionIsReadFromHeader() + { + /* -- RFC 2045, 8. + The ability to associate some descriptive information with a given + body is often desirable. For example, it may be useful to mark an + "image" body as "a picture of the Space Shuttle Endeavor." Such text + may be placed in the Content-Description header field. This header + field is always optional. + */ + + $desc = $this->_createHeader('Content-Description', 'something'); + $headers = $this->_createHeaderSet(array('Content-Description' => $desc)); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $this->assertEquals('something', $entity->getDescription()); + } + + public function testDescriptionIsSetInHeader() + { + $desc = $this->_createHeader('Content-Description', '', array(), false); + $desc->shouldReceive('setFieldBodyModel')->once()->with('whatever'); + + $headers = $this->_createHeaderSet(array('Content-Description' => $desc)); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setDescription('whatever'); + } + + public function testDescriptionHeaderIsAddedIfNotPresent() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('addTextHeader') + ->once() + ->with('Content-Description', 'whatever'); + $headers->shouldReceive('addTextHeader') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setDescription('whatever'); + } + + public function testSetAndGetMaxLineLength() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setMaxLineLength(60); + $this->assertEquals(60, $entity->getMaxLineLength()); + } + + public function testEncoderIsUsedForStringGeneration() + { + $encoder = $this->_createEncoder('base64', false); + $encoder->expects($this->once()) + ->method('encodeString') + ->with('blah'); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $encoder, $this->_createCache() + ); + $entity->setBody('blah'); + $entity->toString(); + } + + public function testMaxLineLengthIsProvidedWhenEncoding() + { + $encoder = $this->_createEncoder('base64', false); + $encoder->expects($this->once()) + ->method('encodeString') + ->with('blah', 0, 65); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $encoder, $this->_createCache() + ); + $entity->setBody('blah'); + $entity->setMaxLineLength(65); + $entity->toString(); + } + + public function testHeadersAppearInString() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->once() + ->andReturn( + "Content-Type: text/plain; charset=utf-8\r\n". + "X-MyHeader: foobar\r\n" + ); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $this->assertEquals( + "Content-Type: text/plain; charset=utf-8\r\n". + "X-MyHeader: foobar\r\n", + $entity->toString() + ); + } + + public function testSetAndGetBody() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setBody("blah\r\nblah!"); + $this->assertEquals("blah\r\nblah!", $entity->getBody()); + } + + public function testBodyIsAppended() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->once() + ->andReturn("Content-Type: text/plain; charset=utf-8\r\n"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBody("blah\r\nblah!"); + $this->assertEquals( + "Content-Type: text/plain; charset=utf-8\r\n". + "\r\n". + "blah\r\nblah!", + $entity->toString() + ); + } + + public function testGetBodyReturnsStringFromByteStream() + { + $os = $this->_createOutputStream('byte stream string'); + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setBody($os); + $this->assertEquals('byte stream string', $entity->getBody()); + } + + public function testByteStreamBodyIsAppended() + { + $headers = $this->_createHeaderSet(array(), false); + $os = $this->_createOutputStream('streamed'); + $headers->shouldReceive('toString') + ->once() + ->andReturn("Content-Type: text/plain; charset=utf-8\r\n"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBody($os); + $this->assertEquals( + "Content-Type: text/plain; charset=utf-8\r\n". + "\r\n". + 'streamed', + $entity->toString() + ); + } + + public function testBoundaryCanBeRetrieved() + { + /* -- RFC 2046, 5.1.1. + boundary := 0*69<bchars> bcharsnospace + + bchars := bcharsnospace / " " + + bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / + "+" / "_" / "," / "-" / "." / + "/" / ":" / "=" / "?" + */ + + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $this->assertRegExp( + '/^[a-zA-Z0-9\'\(\)\+_\-,\.\/:=\?\ ]{0,69}[a-zA-Z0-9\'\(\)\+_\-,\.\/:=\?]$/D', + $entity->getBoundary() + ); + } + + public function testBoundaryNeverChanges() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $firstBoundary = $entity->getBoundary(); + for ($i = 0; $i < 10; ++$i) { + $this->assertEquals($firstBoundary, $entity->getBoundary()); + } + } + + public function testBoundaryCanBeSet() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setBoundary('foobar'); + $this->assertEquals('foobar', $entity->getBoundary()); + } + + public function testAddingChildrenGeneratesBoundaryInHeaders() + { + $child = $this->_createChild(); + $cType = $this->_createHeader('Content-Type', 'text/plain', array(), false); + $cType->shouldReceive('setParameter') + ->once() + ->with('boundary', \Mockery::any()); + $cType->shouldReceive('setParameter') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($this->_createHeaderSet(array( + 'Content-Type' => $cType, + )), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + } + + public function testChildrenOfLevelAttachmentAndLessCauseMultipartMixed() + { + for ($level = Swift_Mime_MimeEntity::LEVEL_MIXED; + $level > Swift_Mime_MimeEntity::LEVEL_TOP; $level /= 2) { + $child = $this->_createChild($level); + $cType = $this->_createHeader( + 'Content-Type', 'text/plain', array(), false + ); + $cType->shouldReceive('setFieldBodyModel') + ->once() + ->with('multipart/mixed'); + $cType->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($this->_createHeaderSet(array( + 'Content-Type' => $cType, )), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + } + } + + public function testChildrenOfLevelAlternativeAndLessCauseMultipartAlternative() + { + for ($level = Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE; + $level > Swift_Mime_MimeEntity::LEVEL_MIXED; $level /= 2) { + $child = $this->_createChild($level); + $cType = $this->_createHeader( + 'Content-Type', 'text/plain', array(), false + ); + $cType->shouldReceive('setFieldBodyModel') + ->once() + ->with('multipart/alternative'); + $cType->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($this->_createHeaderSet(array( + 'Content-Type' => $cType, )), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + } + } + + public function testChildrenOfLevelRelatedAndLessCauseMultipartRelated() + { + for ($level = Swift_Mime_MimeEntity::LEVEL_RELATED; + $level > Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE; $level /= 2) { + $child = $this->_createChild($level); + $cType = $this->_createHeader( + 'Content-Type', 'text/plain', array(), false + ); + $cType->shouldReceive('setFieldBodyModel') + ->once() + ->with('multipart/related'); + $cType->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes(); + + $entity = $this->_createEntity($this->_createHeaderSet(array( + 'Content-Type' => $cType, )), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + } + } + + public function testHighestLevelChildDeterminesContentType() + { + $combinations = array( + array('levels' => array(Swift_Mime_MimeEntity::LEVEL_MIXED, + Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + Swift_Mime_MimeEntity::LEVEL_RELATED, + ), + 'type' => 'multipart/mixed', + ), + array('levels' => array(Swift_Mime_MimeEntity::LEVEL_MIXED, + Swift_Mime_MimeEntity::LEVEL_RELATED, + ), + 'type' => 'multipart/mixed', + ), + array('levels' => array(Swift_Mime_MimeEntity::LEVEL_MIXED, + Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + ), + 'type' => 'multipart/mixed', + ), + array('levels' => array(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + Swift_Mime_MimeEntity::LEVEL_RELATED, + ), + 'type' => 'multipart/alternative', + ), + ); + + foreach ($combinations as $combination) { + $children = array(); + foreach ($combination['levels'] as $level) { + $children[] = $this->_createChild($level); + } + + $cType = $this->_createHeader( + 'Content-Type', 'text/plain', array(), false + ); + $cType->shouldReceive('setFieldBodyModel') + ->once() + ->with($combination['type']); + + $headerSet = $this->_createHeaderSet(array('Content-Type' => $cType)); + $headerSet->shouldReceive('newInstance') + ->zeroOrMoreTimes() + ->andReturnUsing(function () use ($headerSet) { + return $headerSet; + }); + $entity = $this->_createEntity($headerSet, + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren($children); + } + } + + public function testChildrenAppearNestedInString() + { + /* -- RFC 2046, 5.1.1. + (excerpt too verbose to paste here) + */ + + $headers = $this->_createHeaderSet(array(), false); + + $child1 = new MimeEntityFixture(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/plain\r\n". + "\r\n". + 'foobar', 'text/plain' + ); + + $child2 = new MimeEntityFixture(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/html\r\n". + "\r\n". + '<b>foobar</b>', 'text/html' + ); + + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: multipart/alternative; boundary=\"xxx\"\r\n"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBoundary('xxx'); + $entity->setChildren(array($child1, $child2)); + + $this->assertEquals( + "Content-Type: multipart/alternative; boundary=\"xxx\"\r\n". + "\r\n". + "\r\n--xxx\r\n". + "Content-Type: text/plain\r\n". + "\r\n". + "foobar\r\n". + "\r\n--xxx\r\n". + "Content-Type: text/html\r\n". + "\r\n". + "<b>foobar</b>\r\n". + "\r\n--xxx--\r\n", + $entity->toString() + ); + } + + public function testMixingLevelsIsHierarchical() + { + $headers = $this->_createHeaderSet(array(), false); + $newHeaders = $this->_createHeaderSet(array(), false); + + $part = $this->_createChild(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/plain\r\n". + "\r\n". + 'foobar' + ); + + $attachment = $this->_createChild(Swift_Mime_MimeEntity::LEVEL_MIXED, + "Content-Type: application/octet-stream\r\n". + "\r\n". + 'data' + ); + + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: multipart/mixed; boundary=\"xxx\"\r\n"); + $headers->shouldReceive('newInstance') + ->zeroOrMoreTimes() + ->andReturn($newHeaders); + $newHeaders->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: multipart/alternative; boundary=\"yyy\"\r\n"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBoundary('xxx'); + $entity->setChildren(array($part, $attachment)); + + $this->assertRegExp( + '~^'. + "Content-Type: multipart/mixed; boundary=\"xxx\"\r\n". + "\r\n\r\n--xxx\r\n". + "Content-Type: multipart/alternative; boundary=\"yyy\"\r\n". + "\r\n\r\n--(.*?)\r\n". + "Content-Type: text/plain\r\n". + "\r\n". + 'foobar'. + "\r\n\r\n--\\1--\r\n". + "\r\n\r\n--xxx\r\n". + "Content-Type: application/octet-stream\r\n". + "\r\n". + 'data'. + "\r\n\r\n--xxx--\r\n". + '$~', + $entity->toString() + ); + } + + public function testSettingEncoderNotifiesChildren() + { + $child = $this->_createChild(0, '', false); + $encoder = $this->_createEncoder('base64'); + + $child->shouldReceive('encoderChanged') + ->once() + ->with($encoder); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + $entity->setEncoder($encoder); + } + + public function testReceiptOfEncoderChangeNotifiesChildren() + { + $child = $this->_createChild(0, '', false); + $encoder = $this->_createEncoder('base64'); + + $child->shouldReceive('encoderChanged') + ->once() + ->with($encoder); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + $entity->encoderChanged($encoder); + } + + public function testReceiptOfCharsetChangeNotifiesChildren() + { + $child = $this->_createChild(0, '', false); + $child->shouldReceive('charsetChanged') + ->once() + ->with('windows-874'); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $entity->setChildren(array($child)); + $entity->charsetChanged('windows-874'); + } + + public function testEntityIsWrittenToByteStream() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $is = $this->_createInputStream(false); + $is->expects($this->atLeastOnce()) + ->method('write'); + + $entity->toByteStream($is); + } + + public function testEntityHeadersAreComittedToByteStream() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + $is = $this->_createInputStream(false); + $is->expects($this->atLeastOnce()) + ->method('write'); + $is->expects($this->atLeastOnce()) + ->method('commit'); + + $entity->toByteStream($is); + } + + public function testOrderingTextBeforeHtml() + { + $htmlChild = new MimeEntityFixture(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/html\r\n". + "\r\n". + 'HTML PART', + 'text/html' + ); + $textChild = new MimeEntityFixture(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/plain\r\n". + "\r\n". + 'TEXT PART', + 'text/plain' + ); + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: multipart/alternative; boundary=\"xxx\"\r\n"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBoundary('xxx'); + $entity->setChildren(array($htmlChild, $textChild)); + + $this->assertEquals( + "Content-Type: multipart/alternative; boundary=\"xxx\"\r\n". + "\r\n\r\n--xxx\r\n". + "Content-Type: text/plain\r\n". + "\r\n". + 'TEXT PART'. + "\r\n\r\n--xxx\r\n". + "Content-Type: text/html\r\n". + "\r\n". + 'HTML PART'. + "\r\n\r\n--xxx--\r\n", + $entity->toString() + ); + } + + public function testOrderingEqualContentTypesMaintainsOriginalOrdering() + { + $firstChild = new MimeEntityFixture(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/plain\r\n". + "\r\n". + 'PART 1', + 'text/plain' + ); + $secondChild = new MimeEntityFixture(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE, + "Content-Type: text/plain\r\n". + "\r\n". + 'PART 2', + 'text/plain' + ); + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: multipart/alternative; boundary=\"xxx\"\r\n"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $this->_createCache() + ); + $entity->setBoundary('xxx'); + $entity->setChildren(array($firstChild, $secondChild)); + + $this->assertEquals( + "Content-Type: multipart/alternative; boundary=\"xxx\"\r\n". + "\r\n\r\n--xxx\r\n". + "Content-Type: text/plain\r\n". + "\r\n". + 'PART 1'. + "\r\n\r\n--xxx\r\n". + "Content-Type: text/plain\r\n". + "\r\n". + 'PART 2'. + "\r\n\r\n--xxx--\r\n", + $entity->toString() + ); + } + + public function testUnsettingChildrenRestoresContentType() + { + $cType = $this->_createHeader('Content-Type', 'text/plain', array(), false); + $child = $this->_createChild(Swift_Mime_MimeEntity::LEVEL_ALTERNATIVE); + + $cType->shouldReceive('setFieldBodyModel') + ->twice() + ->with('image/jpeg'); + $cType->shouldReceive('setFieldBodyModel') + ->once() + ->with('multipart/alternative'); + $cType->shouldReceive('setFieldBodyModel') + ->zeroOrMoreTimes() + ->with(\Mockery::not('multipart/alternative', 'image/jpeg')); + + $entity = $this->_createEntity($this->_createHeaderSet(array( + 'Content-Type' => $cType, + )), + $this->_createEncoder(), $this->_createCache() + ); + + $entity->setContentType('image/jpeg'); + $entity->setChildren(array($child)); + $entity->setChildren(array()); + } + + public function testBodyIsReadFromCacheWhenUsingToStringIfPresent() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: text/plain; charset=utf-8\r\n"); + + $cache = $this->_createCache(false); + $cache->shouldReceive('hasKey') + ->once() + ->with(\Mockery::any(), 'body') + ->andReturn(true); + $cache->shouldReceive('getString') + ->once() + ->with(\Mockery::any(), 'body') + ->andReturn("\r\ncache\r\ncache!"); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $cache + ); + + $entity->setBody("blah\r\nblah!"); + $this->assertEquals( + "Content-Type: text/plain; charset=utf-8\r\n". + "\r\n". + "cache\r\ncache!", + $entity->toString() + ); + } + + public function testBodyIsAddedToCacheWhenUsingToString() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: text/plain; charset=utf-8\r\n"); + + $cache = $this->_createCache(false); + $cache->shouldReceive('hasKey') + ->once() + ->with(\Mockery::any(), 'body') + ->andReturn(false); + $cache->shouldReceive('setString') + ->once() + ->with(\Mockery::any(), 'body', "\r\nblah\r\nblah!", Swift_KeyCache::MODE_WRITE); + + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $cache + ); + + $entity->setBody("blah\r\nblah!"); + $entity->toString(); + } + + public function testBodyIsClearedFromCacheIfNewBodySet() + { + $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(); + + // We set the expectation at this point because we only care what happens when calling setBody() + $cache->shouldReceive('clearKey') + ->once() + ->with(\Mockery::any(), 'body'); + + $entity->setBody("new\r\nnew!"); + } + + public function testBodyIsNotClearedFromCacheIfSameBodySet() + { + $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(); + + // We set the expectation at this point because we only care what happens when calling setBody() + $cache->shouldReceive('clearKey') + ->never(); + + $entity->setBody("blah\r\nblah!"); + } + + public function testBodyIsClearedFromCacheIfNewEncoderSet() + { + $headers = $this->_createHeaderSet(array(), false); + $headers->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn("Content-Type: text/plain; charset=utf-8\r\n"); + + $cache = $this->_createCache(false); + $otherEncoder = $this->_createEncoder(); + $entity = $this->_createEntity($headers, $this->_createEncoder(), + $cache + ); + + $entity->setBody("blah\r\nblah!"); + $entity->toString(); + + // We set the expectation at this point because we only care what happens when calling setEncoder() + $cache->shouldReceive('clearKey') + ->once() + ->with(\Mockery::any(), 'body'); + + $entity->setEncoder($otherEncoder); + } + + public function testBodyIsReadFromCacheWhenUsingToByteStreamIfPresent() + { + $is = $this->_createInputStream(); + $cache = $this->_createCache(false); + $cache->shouldReceive('hasKey') + ->once() + ->with(\Mockery::any(), 'body') + ->andReturn(true); + $cache->shouldReceive('exportToByteStream') + ->once() + ->with(\Mockery::any(), 'body', $is); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $cache + ); + $entity->setBody('foo'); + + $entity->toByteStream($is); + } + + public function testBodyIsAddedToCacheWhenUsingToByteStream() + { + $is = $this->_createInputStream(); + $cache = $this->_createCache(false); + $cache->shouldReceive('hasKey') + ->once() + ->with(\Mockery::any(), 'body') + ->andReturn(false); + $cache->shouldReceive('getInputByteStream') + ->once() + ->with(\Mockery::any(), 'body'); + + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $cache + ); + $entity->setBody('foo'); + + $entity->toByteStream($is); + } + + public function testFluidInterface() + { + $entity = $this->_createEntity($this->_createHeaderSet(), + $this->_createEncoder(), $this->_createCache() + ); + + $this->assertSame($entity, + $entity + ->setContentType('text/plain') + ->setEncoder($this->_createEncoder()) + ->setId('foo@bar') + ->setDescription('my description') + ->setMaxLineLength(998) + ->setBody('xx') + ->setBoundary('xyz') + ->setChildren(array()) + ); + } + + abstract protected function _createEntity($headers, $encoder, $cache); + + protected function _createChild($level = null, $string = '', $stub = true) + { + $child = $this->getMockery('Swift_Mime_MimeEntity')->shouldIgnoreMissing(); + if (isset($level)) { + $child->shouldReceive('getNestingLevel') + ->zeroOrMoreTimes() + ->andReturn($level); + } + $child->shouldReceive('toString') + ->zeroOrMoreTimes() + ->andReturn($string); + + return $child; + } + + protected function _createEncoder($name = 'quoted-printable', $stub = true) + { + $encoder = $this->getMockBuilder('Swift_Mime_ContentEncoder')->getMock(); + $encoder->expects($this->any()) + ->method('getName') + ->will($this->returnValue($name)); + $encoder->expects($this->any()) + ->method('encodeString') + ->will($this->returnCallback(function () { + $args = func_get_args(); + + return array_shift($args); + })); + + return $encoder; + } + + protected function _createCache($stub = true) + { + return $this->getMockery('Swift_KeyCache')->shouldIgnoreMissing(); + } + + protected function _createHeaderSet($headers = array(), $stub = true) + { + $set = $this->getMockery('Swift_Mime_HeaderSet')->shouldIgnoreMissing(); + $set->shouldReceive('get') + ->zeroOrMoreTimes() + ->andReturnUsing(function ($key) use ($headers) { + return $headers[$key]; + }); + $set->shouldReceive('has') + ->zeroOrMoreTimes() + ->andReturnUsing(function ($key) use ($headers) { + return array_key_exists($key, $headers); + }); + + return $set; + } + + protected function _createHeader($name, $model = null, $params = array(), $stub = true) + { + $header = $this->getMockery('Swift_Mime_ParameterizedHeader')->shouldIgnoreMissing(); + $header->shouldReceive('getFieldName') + ->zeroOrMoreTimes() + ->andReturn($name); + $header->shouldReceive('getFieldBodyModel') + ->zeroOrMoreTimes() + ->andReturn($model); + $header->shouldReceive('getParameter') + ->zeroOrMoreTimes() + ->andReturnUsing(function ($key) use ($params) { + return $params[$key]; + }); + + return $header; + } + + protected function _createOutputStream($data = null, $stub = true) + { + $os = $this->getMockery('Swift_OutputByteStream'); + if (isset($data)) { + $os->shouldReceive('read') + ->zeroOrMoreTimes() + ->andReturnUsing(function () use ($data) { + static $first = true; + if (!$first) { + return false; + } + + $first = false; + + return $data; + }); + $os->shouldReceive('setReadPointer') + ->zeroOrMoreTimes(); + } + + return $os; + } + + protected function _createInputStream($stub = true) + { + return $this->getMockBuilder('Swift_InputByteStream')->getMock(); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AttachmentTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AttachmentTest.php new file mode 100644 index 0000000..2c1e581 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/AttachmentTest.php @@ -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; + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/Base64ContentEncoderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/Base64ContentEncoderTest.php new file mode 100644 index 0000000..1571fce --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/Base64ContentEncoderTest.php @@ -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(); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/PlainContentEncoderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/PlainContentEncoderTest.php new file mode 100644 index 0000000..ca44e11 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/PlainContentEncoderTest.php @@ -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(); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/QpContentEncoderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/QpContentEncoderTest.php new file mode 100644 index 0000000..7762bbe --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/ContentEncoder/QpContentEncoderTest.php @@ -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(); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/EmbeddedFileTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/EmbeddedFileTest.php new file mode 100644 index 0000000..3a1fc51 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/EmbeddedFileTest.php @@ -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()); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/Base64HeaderEncoderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/Base64HeaderEncoderTest.php new file mode 100644 index 0000000..3580155 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/Base64HeaderEncoderTest.php @@ -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()); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/QpHeaderEncoderTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/QpHeaderEncoderTest.php new file mode 100644 index 0000000..b5a10fe --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/HeaderEncoder/QpHeaderEncoderTest.php @@ -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(); + } +} 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; + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/MimePartTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/MimePartTest.php new file mode 100644 index 0000000..738ac68 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/MimePartTest.php @@ -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()); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderFactoryTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderFactoryTest.php new file mode 100644 index 0000000..6a87abf --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderFactoryTest.php @@ -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(); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderSetTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderSetTest.php new file mode 100644 index 0000000..bed1c13 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleHeaderSetTest.php @@ -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; + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMessageTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMessageTest.php new file mode 100644 index 0000000..e5d225c --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMessageTest.php @@ -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()); + } +} diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMimeEntityTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMimeEntityTest.php new file mode 100644 index 0000000..fa2a8d4 --- /dev/null +++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Mime/SimpleMimeEntityTest.php @@ -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()); + } +} |