|
ferencd@0
|
1 //
|
|
ferencd@0
|
2 // VMime library (http://www.vmime.org)
|
|
ferencd@0
|
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
|
ferencd@0
|
4 //
|
|
ferencd@0
|
5 // This program is free software; you can redistribute it and/or
|
|
ferencd@0
|
6 // modify it under the terms of the GNU General Public License as
|
|
ferencd@0
|
7 // published by the Free Software Foundation; either version 3 of
|
|
ferencd@0
|
8 // the License, or (at your option) any later version.
|
|
ferencd@0
|
9 //
|
|
ferencd@0
|
10 // This program is distributed in the hope that it will be useful,
|
|
ferencd@0
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
ferencd@0
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
ferencd@0
|
13 // General Public License for more details.
|
|
ferencd@0
|
14 //
|
|
ferencd@0
|
15 // You should have received a copy of the GNU General Public License along
|
|
ferencd@0
|
16 // with this program; if not, write to the Free Software Foundation, Inc.,
|
|
ferencd@0
|
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
ferencd@0
|
18 //
|
|
ferencd@0
|
19 // Linking this library statically or dynamically with other modules is making
|
|
ferencd@0
|
20 // a combined work based on this library. Thus, the terms and conditions of
|
|
ferencd@0
|
21 // the GNU General Public License cover the whole combination.
|
|
ferencd@0
|
22 //
|
|
ferencd@0
|
23
|
|
ferencd@0
|
24 #include "tests/testUtils.hpp"
|
|
ferencd@0
|
25
|
|
ferencd@0
|
26
|
|
ferencd@0
|
27 VMIME_TEST_SUITE_BEGIN(attachmentHelperTest)
|
|
ferencd@0
|
28
|
|
ferencd@0
|
29 VMIME_TEST_LIST_BEGIN
|
|
ferencd@0
|
30 VMIME_TEST(testAddAttachment1)
|
|
ferencd@0
|
31 VMIME_TEST(testAddAttachment2)
|
|
ferencd@0
|
32 VMIME_TEST(testAddAttachment3)
|
|
ferencd@0
|
33 VMIME_TEST(testIsBodyPartAnAttachment1)
|
|
ferencd@0
|
34 VMIME_TEST(testIsBodyPartAnAttachment2)
|
|
ferencd@0
|
35 VMIME_TEST(testIsBodyPartAnAttachment3)
|
|
ferencd@0
|
36 VMIME_TEST(testGetBodyPartAttachment)
|
|
ferencd@0
|
37 VMIME_TEST(testAddAttachmentMessage1)
|
|
ferencd@0
|
38 VMIME_TEST(testGetBodyPartAttachmentMessage)
|
|
ferencd@0
|
39 VMIME_TEST_LIST_END
|
|
ferencd@0
|
40
|
|
ferencd@0
|
41
|
|
ferencd@0
|
42 static const vmime::string getStructure(vmime::shared_ptr <vmime::bodyPart> part)
|
|
ferencd@0
|
43 {
|
|
ferencd@0
|
44 vmime::shared_ptr <vmime::body> bdy = part->getBody();
|
|
ferencd@0
|
45
|
|
ferencd@0
|
46 vmime::string res = part->getBody()->getContentType().generate();
|
|
ferencd@0
|
47
|
|
ferencd@0
|
48 if (bdy->getPartCount() == 0)
|
|
ferencd@0
|
49 return res;
|
|
ferencd@0
|
50
|
|
ferencd@0
|
51 res += "[";
|
|
ferencd@0
|
52
|
|
ferencd@0
|
53 for (size_t i = 0 ; i < bdy->getPartCount() ; ++i)
|
|
ferencd@0
|
54 {
|
|
ferencd@0
|
55 vmime::shared_ptr <vmime::bodyPart> subPart = bdy->getPartAt(i);
|
|
ferencd@0
|
56
|
|
ferencd@0
|
57 if (i != 0)
|
|
ferencd@0
|
58 res += ",";
|
|
ferencd@0
|
59
|
|
ferencd@0
|
60 res += getStructure(subPart);
|
|
ferencd@0
|
61 }
|
|
ferencd@0
|
62
|
|
ferencd@0
|
63 return res + "]";
|
|
ferencd@0
|
64 }
|
|
ferencd@0
|
65
|
|
ferencd@0
|
66 static const vmime::string extractBodyContents(vmime::shared_ptr <const vmime::bodyPart> part)
|
|
ferencd@0
|
67 {
|
|
ferencd@0
|
68 vmime::shared_ptr <const vmime::contentHandler> cth = part->getBody()->getContents();
|
|
ferencd@0
|
69
|
|
ferencd@0
|
70 vmime::string data;
|
|
ferencd@0
|
71 vmime::utility::outputStreamStringAdapter os(data);
|
|
ferencd@0
|
72
|
|
ferencd@0
|
73 cth->extract(os);
|
|
ferencd@0
|
74
|
|
ferencd@0
|
75 return data;
|
|
ferencd@0
|
76 }
|
|
ferencd@0
|
77
|
|
ferencd@0
|
78 void testAddAttachment1()
|
|
ferencd@0
|
79 {
|
|
ferencd@0
|
80 vmime::string data =
|
|
ferencd@0
|
81 "Content-Type: text/plain\r\n"
|
|
ferencd@0
|
82 "\r\n"
|
|
ferencd@0
|
83 "The text\r\n"
|
|
ferencd@0
|
84 "";
|
|
ferencd@0
|
85
|
|
ferencd@0
|
86 vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
87 msg->parse(data);
|
|
ferencd@0
|
88
|
|
ferencd@0
|
89 vmime::shared_ptr <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>
|
|
ferencd@0
|
90 (vmime::make_shared <vmime::stringContentHandler>("test"),
|
|
ferencd@0
|
91 vmime::mediaType("image/jpeg"));
|
|
ferencd@0
|
92
|
|
ferencd@0
|
93 vmime::attachmentHelper::addAttachment(msg, att);
|
|
ferencd@0
|
94
|
|
ferencd@0
|
95 VASSERT_EQ("1", "multipart/mixed[text/plain,image/jpeg]", getStructure(msg));
|
|
ferencd@0
|
96 VASSERT_EQ("2", "The text\r\n", extractBodyContents(msg->getBody()->getPartAt(0)));
|
|
ferencd@0
|
97 }
|
|
ferencd@0
|
98
|
|
ferencd@0
|
99 void testAddAttachment2()
|
|
ferencd@0
|
100 {
|
|
ferencd@0
|
101 vmime::string data =
|
|
ferencd@0
|
102 "Content-Type: multipart/mixed; boundary=\"foo\"\r\n"
|
|
ferencd@0
|
103 "\r\n"
|
|
ferencd@0
|
104 "--foo\r\n"
|
|
ferencd@0
|
105 "Content-Type: text/plain\r\n"
|
|
ferencd@0
|
106 "\r\n"
|
|
ferencd@0
|
107 "The text\r\n"
|
|
ferencd@0
|
108 "--foo\r\n"
|
|
ferencd@0
|
109 "Content-Type: application/octet-stream\r\n"
|
|
ferencd@0
|
110 "\r\n"
|
|
ferencd@0
|
111 "Blah\r\n"
|
|
ferencd@0
|
112 "--foo--\r\n"
|
|
ferencd@0
|
113 "";
|
|
ferencd@0
|
114
|
|
ferencd@0
|
115 vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
116 msg->parse(data);
|
|
ferencd@0
|
117
|
|
ferencd@0
|
118 vmime::shared_ptr <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>
|
|
ferencd@0
|
119 (vmime::make_shared <vmime::stringContentHandler>("test"),
|
|
ferencd@0
|
120 vmime::mediaType("image/jpeg"));
|
|
ferencd@0
|
121
|
|
ferencd@0
|
122 vmime::attachmentHelper::addAttachment(msg, att);
|
|
ferencd@0
|
123
|
|
ferencd@0
|
124 VASSERT_EQ("1", "multipart/mixed[text/plain,application/octet-stream,image/jpeg]", getStructure(msg));
|
|
ferencd@0
|
125 VASSERT_EQ("2", "The text", extractBodyContents(msg->getBody()->getPartAt(0)));
|
|
ferencd@0
|
126 VASSERT_EQ("3", "Blah", extractBodyContents(msg->getBody()->getPartAt(1)));
|
|
ferencd@0
|
127 VASSERT_EQ("4", "test", extractBodyContents(msg->getBody()->getPartAt(2)));
|
|
ferencd@0
|
128 }
|
|
ferencd@0
|
129
|
|
ferencd@0
|
130 // Initial part is encoded
|
|
ferencd@0
|
131 void testAddAttachment3()
|
|
ferencd@0
|
132 {
|
|
ferencd@0
|
133 vmime::string data =
|
|
ferencd@0
|
134 "Content-Type: text/plain\r\n"
|
|
ferencd@0
|
135 "Content-Transfer-Encoding: base64\r\n"
|
|
ferencd@0
|
136 "\r\n"
|
|
ferencd@0
|
137 "TWVzc2FnZSBib2R5";
|
|
ferencd@0
|
138
|
|
ferencd@0
|
139 vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
140 msg->parse(data);
|
|
ferencd@0
|
141
|
|
ferencd@0
|
142 vmime::shared_ptr <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>
|
|
ferencd@0
|
143 (vmime::make_shared <vmime::stringContentHandler>("test"),
|
|
ferencd@0
|
144 vmime::mediaType("image/jpeg"));
|
|
ferencd@0
|
145
|
|
ferencd@0
|
146 vmime::attachmentHelper::addAttachment(msg, att);
|
|
ferencd@0
|
147
|
|
ferencd@0
|
148 VASSERT_EQ("1", "multipart/mixed[text/plain,image/jpeg]", getStructure(msg));
|
|
ferencd@0
|
149 VASSERT_EQ("2", "Message body", extractBodyContents(msg->getBody()->getPartAt(0)));
|
|
ferencd@0
|
150 }
|
|
ferencd@0
|
151
|
|
ferencd@0
|
152 // Content-Disposition: attachment
|
|
ferencd@0
|
153 // No other field
|
|
ferencd@0
|
154 void testIsBodyPartAnAttachment1()
|
|
ferencd@0
|
155 {
|
|
ferencd@0
|
156 vmime::string data = "Content-Disposition: attachment\r\n\r\nFoo\r\n";
|
|
ferencd@0
|
157
|
|
ferencd@0
|
158 vmime::shared_ptr <vmime::bodyPart> p = vmime::make_shared <vmime::bodyPart>();
|
|
ferencd@0
|
159 p->parse(data);
|
|
ferencd@0
|
160
|
|
ferencd@0
|
161 VASSERT_EQ("1", true, vmime::attachmentHelper::isBodyPartAnAttachment(p));
|
|
ferencd@0
|
162 }
|
|
ferencd@0
|
163
|
|
ferencd@0
|
164 // No Content-Disposition field
|
|
ferencd@0
|
165 // Content-Type: multipart/* or text/*
|
|
ferencd@0
|
166 void testIsBodyPartAnAttachment2()
|
|
ferencd@0
|
167 {
|
|
ferencd@0
|
168 vmime::string data = "Content-Type: multipart/*\r\n\r\nFoo\r\n";
|
|
ferencd@0
|
169
|
|
ferencd@0
|
170 vmime::shared_ptr <vmime::bodyPart> p = vmime::make_shared <vmime::bodyPart>();
|
|
ferencd@0
|
171 p->parse(data);
|
|
ferencd@0
|
172
|
|
ferencd@0
|
173 VASSERT_EQ("1", false, vmime::attachmentHelper::isBodyPartAnAttachment(p));
|
|
ferencd@0
|
174
|
|
ferencd@0
|
175 data = "Content-Type: text/*\r\n\r\nFoo\r\n";
|
|
ferencd@0
|
176
|
|
ferencd@0
|
177 p->parse(data);
|
|
ferencd@0
|
178
|
|
ferencd@0
|
179 VASSERT_EQ("2", false, vmime::attachmentHelper::isBodyPartAnAttachment(p));
|
|
ferencd@0
|
180 }
|
|
ferencd@0
|
181
|
|
ferencd@0
|
182 // No Content-Disposition field
|
|
ferencd@0
|
183 void testIsBodyPartAnAttachment3()
|
|
ferencd@0
|
184 {
|
|
ferencd@0
|
185 vmime::string data = "Content-Type: application/octet-stream\r\n\r\nFoo\r\n";
|
|
ferencd@0
|
186
|
|
ferencd@0
|
187 vmime::shared_ptr <vmime::bodyPart> p = vmime::make_shared <vmime::bodyPart>();
|
|
ferencd@0
|
188 p->parse(data);
|
|
ferencd@0
|
189
|
|
ferencd@0
|
190 VASSERT_EQ("1", true, vmime::attachmentHelper::isBodyPartAnAttachment(p));
|
|
ferencd@0
|
191 }
|
|
ferencd@0
|
192
|
|
ferencd@0
|
193 // Content-Disposition: attachment
|
|
ferencd@0
|
194 // Content-Id field present
|
|
ferencd@0
|
195 void testIsBodyPartAnAttachment4()
|
|
ferencd@0
|
196 {
|
|
ferencd@0
|
197 vmime::string data = "Content-Disposition: attachment\r\n"
|
|
ferencd@0
|
198 "Content-Type: application/octet-stream\r\n"
|
|
ferencd@0
|
199 "Content-Id: bar\r\n"
|
|
ferencd@0
|
200 "\r\nFoo\r\n";
|
|
ferencd@0
|
201
|
|
ferencd@0
|
202 vmime::shared_ptr <vmime::bodyPart> p = vmime::make_shared <vmime::bodyPart>();
|
|
ferencd@0
|
203 p->parse(data);
|
|
ferencd@0
|
204
|
|
ferencd@0
|
205 VASSERT_EQ("1", false, vmime::attachmentHelper::isBodyPartAnAttachment(p));
|
|
ferencd@0
|
206 }
|
|
ferencd@0
|
207
|
|
ferencd@0
|
208 void testGetBodyPartAttachment()
|
|
ferencd@0
|
209 {
|
|
ferencd@0
|
210 vmime::string data =
|
|
ferencd@0
|
211 "Content-Type: image/jpeg\r\n"
|
|
ferencd@0
|
212 "Content-Description: foobar\r\n"
|
|
ferencd@0
|
213 "Content-Transfer-Encoding: x-baz\r\n"
|
|
ferencd@0
|
214 "Content-Disposition: attachment; filename=\"foobar.baz\"\r\n"
|
|
ferencd@0
|
215 "\r\n"
|
|
ferencd@0
|
216 "Foo bar baz";
|
|
ferencd@0
|
217
|
|
ferencd@0
|
218 vmime::shared_ptr <vmime::bodyPart> part = vmime::make_shared <vmime::bodyPart>();
|
|
ferencd@0
|
219 part->parse(data);
|
|
ferencd@0
|
220
|
|
ferencd@0
|
221 vmime::shared_ptr <const vmime::attachment> att =
|
|
ferencd@0
|
222 vmime::attachmentHelper::getBodyPartAttachment(part);
|
|
ferencd@0
|
223
|
|
ferencd@0
|
224 VASSERT_EQ("1", "image/jpeg", att->getType().generate());
|
|
ferencd@0
|
225 VASSERT_EQ("2", "foobar", att->getDescription().generate());
|
|
ferencd@0
|
226 VASSERT_EQ("3", "x-baz", att->getEncoding().generate());
|
|
ferencd@0
|
227 VASSERT_EQ("4", "foobar.baz", att->getName().generate());
|
|
ferencd@0
|
228
|
|
ferencd@0
|
229 vmime::string attData;
|
|
ferencd@0
|
230 vmime::utility::outputStreamStringAdapter out(attData);
|
|
ferencd@0
|
231 att->getData()->extractRaw(out); // 'x-baz' encoding not supported
|
|
ferencd@0
|
232
|
|
ferencd@0
|
233 VASSERT_EQ("5", "Foo bar baz", attData);
|
|
ferencd@0
|
234
|
|
ferencd@0
|
235 //VASSERT_EQ("6", part, att->getPart());
|
|
ferencd@0
|
236 VASSERT_EQ("6", part->generate(), vmime::dynamicCast <const vmime::component>(att->getPart())->generate());
|
|
ferencd@0
|
237 //VASSERT_EQ("7", part->getHeader(), att->getHeader());
|
|
ferencd@0
|
238 VASSERT_EQ("7", part->getHeader()->generate(), att->getHeader()->generate());
|
|
ferencd@0
|
239 }
|
|
ferencd@0
|
240
|
|
ferencd@0
|
241 void testAddAttachmentMessage1()
|
|
ferencd@0
|
242 {
|
|
ferencd@0
|
243 const vmime::string data =
|
|
ferencd@0
|
244 "Subject: Test message\r\n"
|
|
ferencd@0
|
245 "Content-Type: text/plain\r\n"
|
|
ferencd@0
|
246 "\r\n"
|
|
ferencd@0
|
247 "Message body";
|
|
ferencd@0
|
248
|
|
ferencd@0
|
249 vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
250 msg->parse(data);
|
|
ferencd@0
|
251
|
|
ferencd@0
|
252 const vmime::string attData =
|
|
ferencd@0
|
253 "Subject: Attached message\r\n"
|
|
ferencd@0
|
254 "Content-Type: text/plain\r\n"
|
|
ferencd@0
|
255 "Content-Transfer-Encoding: base64\r\n"
|
|
ferencd@0
|
256 "\r\n"
|
|
ferencd@0
|
257 "QXR0YWNoZWQgbWVzc2FnZSBib2R5";
|
|
ferencd@0
|
258
|
|
ferencd@0
|
259 vmime::shared_ptr <vmime::message> amsg = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
260 amsg->parse(attData);
|
|
ferencd@0
|
261
|
|
ferencd@0
|
262 vmime::attachmentHelper::addAttachment(msg, amsg);
|
|
ferencd@0
|
263
|
|
ferencd@0
|
264 VASSERT_EQ("1", "multipart/mixed[text/plain,message/rfc822]", getStructure(msg));
|
|
ferencd@0
|
265 VASSERT_EQ("2", "Message body", extractBodyContents(msg->getBody()->getPartAt(0)));
|
|
ferencd@0
|
266
|
|
ferencd@0
|
267 // Ensure message has been encoded properly
|
|
ferencd@0
|
268 vmime::shared_ptr <const vmime::bodyPart> attPart = msg->getBody()->getPartAt(1);
|
|
ferencd@0
|
269 vmime::shared_ptr <const vmime::contentHandler> attCth = attPart->getBody()->getContents();
|
|
ferencd@0
|
270
|
|
ferencd@0
|
271 vmime::string attDataOut;
|
|
ferencd@0
|
272 vmime::utility::outputStreamStringAdapter attDataOutOs(attDataOut);
|
|
ferencd@0
|
273
|
|
ferencd@0
|
274 attCth->extract(attDataOutOs);
|
|
ferencd@0
|
275
|
|
ferencd@0
|
276 vmime::shared_ptr <vmime::message> amsgOut = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
277 amsgOut->parse(attDataOut);
|
|
ferencd@0
|
278
|
|
ferencd@0
|
279 vmime::shared_ptr <vmime::header> hdr = amsgOut->getHeader();
|
|
ferencd@0
|
280
|
|
ferencd@0
|
281 VASSERT_EQ("3", "Attached message", hdr->Subject()->getValue <vmime::text>()->generate());
|
|
ferencd@0
|
282 VASSERT_EQ("4", "Attached message body", extractBodyContents(amsgOut));
|
|
ferencd@0
|
283 }
|
|
ferencd@0
|
284
|
|
ferencd@0
|
285 void testGetBodyPartAttachmentMessage()
|
|
ferencd@0
|
286 {
|
|
ferencd@0
|
287 const vmime::string data =
|
|
ferencd@0
|
288 "Subject: Test message\r\n"
|
|
ferencd@0
|
289 "Content-Type: multipart/mixed; boundary=\"foo\"\r\n"
|
|
ferencd@0
|
290 "\r\n"
|
|
ferencd@0
|
291 "--foo\r\n"
|
|
ferencd@0
|
292 "Content-Type: message/rfc822\r\n"
|
|
ferencd@0
|
293 "\r\n"
|
|
ferencd@0
|
294 "Subject: Attached message\r\n"
|
|
ferencd@0
|
295 "\r\n"
|
|
ferencd@0
|
296 "Attached message body\r\n"
|
|
ferencd@0
|
297 "--foo\r\n"
|
|
ferencd@0
|
298 "Content-Type: text/plain\r\n"
|
|
ferencd@0
|
299 "\r\n"
|
|
ferencd@0
|
300 "FooBar\r\n"
|
|
ferencd@0
|
301 "--foo--\r\n";
|
|
ferencd@0
|
302
|
|
ferencd@0
|
303 vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
|
ferencd@0
|
304 msg->parse(data);
|
|
ferencd@0
|
305
|
|
ferencd@0
|
306 VASSERT_EQ("0", 2, msg->getBody()->getPartCount());
|
|
ferencd@0
|
307
|
|
ferencd@0
|
308 vmime::shared_ptr <const vmime::attachment> att = vmime::attachmentHelper::
|
|
ferencd@0
|
309 getBodyPartAttachment(msg->getBody()->getPartAt(0));
|
|
ferencd@0
|
310
|
|
ferencd@0
|
311 VASSERT("1", att != NULL);
|
|
ferencd@0
|
312
|
|
ferencd@0
|
313 vmime::shared_ptr <const vmime::messageAttachment> msgAtt =
|
|
ferencd@0
|
314 vmime::dynamicCast <const vmime::messageAttachment>(att);
|
|
ferencd@0
|
315
|
|
ferencd@0
|
316 VASSERT("2", msgAtt != NULL);
|
|
ferencd@0
|
317
|
|
ferencd@0
|
318 vmime::shared_ptr <vmime::message> amsg = msgAtt->getMessage();
|
|
ferencd@0
|
319 vmime::shared_ptr <vmime::header> hdr = amsg->getHeader();
|
|
ferencd@0
|
320
|
|
ferencd@0
|
321 VASSERT_EQ("3", "Attached message", hdr->Subject()->getValue <vmime::text>()->generate());
|
|
ferencd@0
|
322 VASSERT_EQ("4", "Attached message body", extractBodyContents(amsg));
|
|
ferencd@0
|
323 }
|
|
ferencd@0
|
324
|
|
ferencd@0
|
325 VMIME_TEST_SUITE_END
|
|
ferencd@0
|
326
|