1require "vnd.dovecot.testsuite";
2require "variables";
3require "foreverypart";
4require "mime";
5
6/*
7 * Basic functionality
8 */
9
10test_set "message" text:
11From: stephan@example.com
12To: nico@nl.example.com, harry@de.example.com
13Subject: Frobnitzm
14Comments: This is nonsense.
15Keywords: nonsense, strange, testing
16X-Spam: Yes
17
18Test.
19.
20;
21
22test "Basic functionality" {
23	/* Must match */
24	if not header :mime :anychild :contains ["Subject", "Comments"] "Frobnitzm" {
25		test_fail "failed to match header (1)";
26	}
27
28	if not header :mime :anychild :contains ["Subject", "Comments"] "nonsense" {
29		test_fail "failed to match header(2)";
30	}
31
32	if not header :mime :anychild :matches "Keywords" "*, strange, *" {
33		test_fail "failed to match header (3)";
34	}
35
36	if not header :mime :anychild :is "Comments" "This is nonsense." {
37		test_fail "failed to match header (4)";
38	}
39
40	/* Must not match */
41	if header :mime :anychild ["subject", "comments", "keywords"] "idiotic" {
42		test_fail "matched nonsense";
43	}
44
45	/* Match first key */
46	if not header :mime :anychild :contains ["keywords"] ["strange", "snot", "vreemd"] {
47		test_fail "failed to match first key";
48	}
49
50	/* Match second key */
51	if not header :mime :anychild :contains ["keywords"] ["raar", "strange", "vreemd"] {
52		test_fail "failed to match second key";
53	}
54
55	/* Match last key */
56	if not header :mime :anychild :contains ["keywords"] ["raar", "snot", "strange"] {
57		test_fail "failed to match last key";
58	}
59
60	/* First header */
61	if not header :mime :anychild :contains ["keywords", "subject"]
62		["raar", "strange", "vreemd"] {
63		test_fail "failed to match first header";
64	}
65
66	/* Second header */
67	if not header :mime :anychild :contains ["subject", "keywords"]
68		["raar", "strange", "vreemd"] {
69		test_fail "failed to match second header";
70	}
71}
72
73/*
74 * Basic functionality - foreverypart
75 */
76
77test "Basic functionality - foreverypart" {
78	foreverypart {
79		/* Must match */
80		if not header :mime :anychild :contains ["Subject", "Comments"] "Frobnitzm" {
81			test_fail "failed to match header (1)";
82		}
83
84		if not header :mime :anychild :contains ["Subject", "Comments"] "nonsense" {
85			test_fail "failed to match header(2)";
86		}
87
88		if not header :mime :anychild :matches "Keywords" "*, strange, *" {
89			test_fail "failed to match header (3)";
90		}
91
92		if not header :mime :anychild :is "Comments" "This is nonsense." {
93			test_fail "failed to match header (4)";
94		}
95
96		/* Must not match */
97		if header :mime :anychild ["subject", "comments", "keywords"] "idiotic" {
98			test_fail "matched nonsense";
99		}
100
101		/* Match first key */
102		if not header :mime :anychild :contains ["keywords"] ["strange", "snot", "vreemd"] {
103			test_fail "failed to match first key";
104		}
105
106		/* Match second key */
107		if not header :mime :anychild :contains ["keywords"] ["raar", "strange", "vreemd"] {
108			test_fail "failed to match second key";
109		}
110
111		/* Match last key */
112		if not header :mime :anychild :contains ["keywords"] ["raar", "snot", "strange"] {
113			test_fail "failed to match last key";
114		}
115
116		/* First header */
117		if not header :mime :anychild :contains ["keywords", "subject"]
118			["raar", "strange", "vreemd"] {
119			test_fail "failed to match first header";
120		}
121
122		/* Second header */
123		if not header :mime :anychild :contains ["subject", "keywords"]
124			["raar", "strange", "vreemd"] {
125			test_fail "failed to match second header";
126		}
127	}
128}
129
130/*
131 * Matching empty key
132 */
133
134test_set "message" text:
135From: stephan@example.org
136To: nico@frop.example.com
137X-Caffeine: C8H10N4O2
138Subject: I need coffee!
139Comments:
140
141Text
142.
143;
144
145test "Matching empty key" {
146	if header :mime :anychild :is "X-Caffeine" "" {
147		test_fail ":is-matched non-empty header with empty string";
148	}
149
150	if not header :mime :anychild :contains "X-Caffeine" "" {
151		test_fail "failed to match existing header with empty string";
152	}
153
154	if not header :mime :anychild :is "comments" "" {
155		test_fail "failed to match empty header :mime :anychild with empty string";
156	}
157
158	if header :mime :anychild :contains "X-Nonsense" "" {
159		test_fail ":contains-matched non-existent header with empty string";
160	}
161}
162
163/*
164 * Matching empty key - foreverypart
165 */
166
167test "Matching empty key - foreverypart" {
168	foreverypart {
169		if header :mime :anychild :is "X-Caffeine" "" {
170			test_fail ":is-matched non-empty header with empty string";
171		}
172
173		if not header :mime :anychild :contains "X-Caffeine" "" {
174			test_fail "failed to match existing header with empty string";
175		}
176
177		if not header :mime :anychild :is "comments" "" {
178			test_fail "failed to match empty header :mime :anychild with empty string";
179		}
180
181		if header :mime :anychild :contains "X-Nonsense" "" {
182			test_fail ":contains-matched non-existent header with empty string";
183		}
184	}
185}
186
187/*
188 * Ignoring whitespace
189 */
190
191test_set "message" text:
192From: stephan@example.org
193To: nico@frop.example.com
194Subject:         Help
195X-A:     Text
196X-B: Text
197
198Text
199.
200;
201
202test "Ignoring whitespace" {
203	if not header :mime :anychild :is "x-a" "Text" {
204		if header :mime :anychild :matches "x-a" "*" {
205			set "header" "${1}";
206		}
207		test_fail "header :mime :anychild test does not strip leading whitespace (header=`${header}`)";
208	}
209
210	if not header :mime :anychild :is "x-b" "Text" {
211		if header :mime :anychild :matches "x-b" "*" {
212			set "header" "${1}";
213		}
214		test_fail "header :mime :anychild test does not strip trailing whitespace (header=`${header}`)";
215	}
216
217	if not header :mime :anychild :is "subject" "Help" {
218		if header :mime :anychild :matches "subject" "*" {
219			set "header" "${1}";
220		}
221		test_fail "header :mime :anychild test does not strip both leading and trailing whitespace (header=`${header}`)";
222	}
223}
224
225/*
226 * Ignoring whitespace - foreverypart
227 */
228
229test "Ignoring whitespace - foreverypart" {
230	foreverypart {
231		if not header :mime :anychild :is "x-a" "Text" {
232			if header :mime :anychild :matches "x-a" "*" {
233				set "header" "${1}";
234			}
235			test_fail "header :mime :anychild test does not strip leading whitespace (header=`${header}`)";
236		}
237
238		if not header :mime :anychild :is "x-b" "Text" {
239			if header :mime :anychild :matches "x-b" "*" {
240				set "header" "${1}";
241			}
242			test_fail "header :mime :anychild test does not strip trailing whitespace (header=`${header}`)";
243		}
244
245		if not header :mime :anychild :is "subject" "Help" {
246			if header :mime :anychild :matches "subject" "*" {
247				set "header" "${1}";
248			}
249			test_fail "header :mime :anychild test does not strip both leading and trailing whitespace (header=`${header}`)";
250		}
251	}
252}
253
254/*
255 * Absent or empty header
256 */
257
258test_set "message" text:
259From: stephan@example.org
260To: nico@frop.example.com
261CC: harry@nonsense.ex
262Subject:
263Comments:
264
265Text
266.
267;
268
269test "Absent or empty header" {
270	if not header :mime :anychild :matches "Cc" "?*" {
271		test_fail "CC header is not absent or empty";
272	}
273
274	if header :mime :anychild :matches "Subject" "?*" {
275		test_fail "Subject header is empty, but matched otherwise";
276	}
277
278	if header :mime :anychild :matches "Comment" "?*" {
279		test_fail "Comment header is empty, but matched otherwise";
280	}
281}
282
283/*
284 * Absent or empty header - foreverypart
285 */
286
287test "Absent or empty header - foreverypart" {
288	foreverypart {
289		if not header :mime :anychild :matches "Cc" "?*" {
290			test_fail "CC header is not absent or empty";
291		}
292
293		if header :mime :anychild :matches "Subject" "?*" {
294			test_fail "Subject header is empty, but matched otherwise";
295		}
296
297		if header :mime :anychild :matches "Comment" "?*" {
298			test_fail "Comment header is empty, but matched otherwise";
299		}
300	}
301}
302
303
304/*
305 * Invalid header name
306 */
307
308test_set "message" text:
309From: stephan@example.org
310To: nico@frop.example.com
311Subject: Valid message
312X-Multiline: This is a multi-line
313 header body, which should be
314 unfolded correctly.
315
316Text
317.
318;
319
320test "Invalid header name" {
321	if header :mime :anychild :contains "subject:" "" {
322		test_fail "matched invalid header name";
323	}
324
325	if header :mime :anychild :contains "to!" "" {
326		test_fail "matched invalid header name";
327	}
328}
329
330/*
331 * Invalid header name - foreverypart
332 */
333
334test "Invalid header name - foreverypart" {
335	foreverypart {
336		if header :mime :anychild :contains "subject:" "" {
337			test_fail "matched invalid header name";
338		}
339
340		if header :mime :anychild :contains "to!" "" {
341			test_fail "matched invalid header name";
342		}
343	}
344}
345
346/*
347 * Folded headers
348 */
349
350test_set "message" text:
351From: stephan@example.org
352To: nico@frop.example.com
353Subject: Not enough space on a line!
354X-Multiline: This is a multi-line
355 header body, which should be
356 unfolded correctly.
357
358Text
359.
360;
361
362test "Folded headers" {
363	if not header :mime :anychild :is "x-multiline"
364		"This is a multi-line header body, which should be unfolded correctly." {
365		test_fail "failed to properly unfold folded header.";
366	}
367}
368
369/*
370 * Folded headers - foreverypart
371 */
372
373test "Folded headers - foreverypart" {
374	foreverypart {
375		if not header :mime :anychild :is "x-multiline"
376			"This is a multi-line header body, which should be unfolded correctly." {
377			test_fail "failed to properly unfold folded header.";
378		}
379	}
380}
381
382/*
383 * Multipart anychild
384 */
385
386test_set "message" text:
387From: Hendrik <hendrik@example.com>
388To: Harrie <harrie@example.com>
389Date: Sat, 11 Oct 2010 00:31:44 +0200
390Subject: Harrie is een prutser
391Content-Type: multipart/mixed; boundary=AA
392X-Test: AA
393
394This is a multi-part message in MIME format.
395--AA
396Content-Type: multipart/mixed; boundary=BB
397X-Test: BB
398
399This is a multi-part message in MIME format.
400--BB
401Content-Type: text/plain; charset="us-ascii"
402X-Test: CC
403
404Hello
405
406--BB
407Content-Type: text/plain; charset="us-ascii"
408X-Test: DD
409
410Hello again
411
412--BB--
413This is the end of MIME multipart.
414
415--AA
416Content-Type: text/plain; charset="us-ascii"
417X-Test: EE
418
419And again
420
421--AA--
422This is the end of  MIME multipart.
423.
424;
425
426test "Multipart anychild" {
427	if not header :mime :anychild "X-Test" "AA" {
428		test_fail "No AA";
429	}
430	if not header :mime :anychild "X-Test" "BB" {
431		test_fail "No BB";
432	}
433	if not header :mime :anychild "X-Test" "CC" {
434		test_fail "No CC";
435	}
436	if not header :mime :anychild "X-Test" "DD" {
437		test_fail "No DD";
438	}
439	if not header :mime :anychild "X-Test" "EE" {
440		test_fail "No EE";
441	}
442}
443
444
445