1<?php
2
3class Swift_Encoder_Rfc2231EncoderTest extends \SwiftMailerTestCase
4{
5    private $_rfc2045Token = '/^[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+$/D';
6
7    /* --
8    This algorithm is described in RFC 2231, but is barely touched upon except
9    for mentioning bytes can be represented as their octet values (e.g. %20 for
10    the SPACE character).
11
12    The tests here focus on how to use that representation to always generate text
13    which matches RFC 2045's definition of "token".
14    */
15
16    public function testEncodingAsciiCharactersProducesValidToken()
17    {
18        $charStream = $this->getMockery('Swift_CharacterStream');
19
20        $string = '';
21        foreach (range(0x00, 0x7F) as $octet) {
22            $char = pack('C', $octet);
23            $string .= $char;
24            $charStream->shouldReceive('read')
25                       ->once()
26                       ->andReturn($char);
27        }
28
29        $charStream->shouldReceive('flushContents')
30                    ->once();
31        $charStream->shouldReceive('importString')
32                    ->once()
33                    ->with($string);
34        $charStream->shouldReceive('read')
35                    ->atLeast()->times(1)
36                    ->andReturn(false);
37
38        $encoder = new Swift_Encoder_Rfc2231Encoder($charStream);
39        $encoded = $encoder->encodeString($string);
40
41        foreach (explode("\r\n", $encoded) as $line) {
42            $this->assertRegExp($this->_rfc2045Token, $line,
43                '%s: Encoder should always return a valid RFC 2045 token.');
44        }
45    }
46
47    public function testEncodingNonAsciiCharactersProducesValidToken()
48    {
49        $charStream = $this->getMockery('Swift_CharacterStream');
50
51        $string = '';
52        foreach (range(0x80, 0xFF) as $octet) {
53            $char = pack('C', $octet);
54            $string .= $char;
55            $charStream->shouldReceive('read')
56                       ->once()
57                       ->andReturn($char);
58        }
59        $charStream->shouldReceive('flushContents')
60                    ->once();
61        $charStream->shouldReceive('importString')
62                    ->once()
63                    ->with($string);
64        $charStream->shouldReceive('read')
65                    ->atLeast()->times(1)
66                    ->andReturn(false);
67        $encoder = new Swift_Encoder_Rfc2231Encoder($charStream);
68
69        $encoded = $encoder->encodeString($string);
70
71        foreach (explode("\r\n", $encoded) as $line) {
72            $this->assertRegExp($this->_rfc2045Token, $line,
73                '%s: Encoder should always return a valid RFC 2045 token.');
74        }
75    }
76
77    public function testMaximumLineLengthCanBeSet()
78    {
79        $charStream = $this->getMockery('Swift_CharacterStream');
80
81        $string = '';
82        for ($x = 0; $x < 200; ++$x) {
83            $char = 'a';
84            $string .= $char;
85            $charStream->shouldReceive('read')
86                       ->once()
87                       ->andReturn($char);
88        }
89        $charStream->shouldReceive('flushContents')
90                    ->once();
91        $charStream->shouldReceive('importString')
92                    ->once()
93                    ->with($string);
94        $charStream->shouldReceive('read')
95                    ->atLeast()->times(1)
96                    ->andReturn(false);
97        $encoder = new Swift_Encoder_Rfc2231Encoder($charStream);
98
99        $encoded = $encoder->encodeString($string, 0, 75);
100
101        $this->assertEquals(
102            str_repeat('a', 75)."\r\n".
103            str_repeat('a', 75)."\r\n".
104            str_repeat('a', 50),
105            $encoded,
106            '%s: Lines should be wrapped at each 75 characters'
107            );
108    }
109
110    public function testFirstLineCanHaveShorterLength()
111    {
112        $charStream = $this->getMockery('Swift_CharacterStream');
113
114        $string = '';
115        for ($x = 0; $x < 200; ++$x) {
116            $char = 'a';
117            $string .= $char;
118            $charStream->shouldReceive('read')
119                       ->once()
120                       ->andReturn($char);
121        }
122        $charStream->shouldReceive('flushContents')
123                    ->once();
124        $charStream->shouldReceive('importString')
125                    ->once()
126                    ->with($string);
127        $charStream->shouldReceive('read')
128                    ->atLeast()->times(1)
129                    ->andReturn(false);
130        $encoder = new Swift_Encoder_Rfc2231Encoder($charStream);
131        $encoded = $encoder->encodeString($string, 25, 75);
132
133        $this->assertEquals(
134            str_repeat('a', 50)."\r\n".
135            str_repeat('a', 75)."\r\n".
136            str_repeat('a', 75),
137            $encoded,
138            '%s: First line should be 25 bytes shorter than the others.'
139            );
140    }
141}
142