require "vnd.dovecot.testsuite";
require "relational";
require "comparator-i;ascii-numeric";

require "body";

/*
 *
 */

test_set "message" text:
From: justin@example.com
To: carl@example.nl
Subject: Frop
Content-Type: multipart/mixed; boundary=donkey

This is a multi-part message in MIME format.

--donkey
Content-Type: text/plain

Plain Text

--donkey
Content-Type: text/stupid

Stupid Text

--donkey
Content-Type: text/plain/stupid

Plain Stupid Text

--donkey--
.
;

test "Basic Match" {
	if not body :text :contains "Plain Text" {
		test_fail "failed to match (1)";
	}

	if not body :text :contains "Stupid Text" {
		test_fail "failed to match (2)";
	}
}

test "Double Slash" {
	if body :text :contains "Plain Stupid Text" {
		test_fail "matched \"text/plain/stupid\"";
	}
}

/*
 *
 */

test_set "message" text:
From: justin@example.com
To: carl@example.nl
Subject: Frop
Content-Type: multipart/mixed; boundary=limit

This is a multi-part message in MIME format.

--limit
Content-Type: text/plain

This is a text message.

--limit
Content-Type: text/html

<html><body>This is HTML</body></html>

--limit
Content-Type: application/sieve

keep;

--limit--
.
;

test "Full Content Type" {
	if not body :text :contains "This is a text message" {
		test_fail "failed to match text/plain content";
	}

	if not body :text :contains "This is HTML" {
		test_fail "failed to match text/html content";
	}

	if body :text :contains "<html>" {
		test_fail "erroneously matched text/html markup";
	}

	if body :text :contains "keep;" {
		test_fail "body :text test matched non-text content";
	}
}

/*
 *
 */

test_set "message" text:
From: Whomever <whoever@example.com>
To: Someone <someone@example.com>
Date: Sat, 10 Oct 2009 00:30:04 +0200
Subject: whatever
Content-Type: multipart/mixed; boundary=outer

This is a multi-part message in MIME format.

--outer
Content-Type: multipart/alternative; boundary=inner

This is a nested multi-part message in MIME format.

--inner
Content-Type: text/plain; charset="us-ascii"

Hello

--inner
Content-Type: text/html; charset="us-ascii"

<html><body>HTML Hello</body></html>

--inner
Content-Type: application/xhtml+xml; charset="us-ascii"

<html><body>XHTML Hello</body></html>

--inner--

This is the end of the inner MIME multipart.

--outer
Content-Type: message/rfc822

From: Someone Else
Subject: Hello, this is an elaborate request for you to finally say hello
 already!

Please say Hello

--outer--

This is the end of the outer MIME multipart.
.
;

/* RFC5173, Section 5.2:
 *
 *  The search for MIME parts matching the :content specification is
 *  recursive and automatically descends into multipart and
 *  message/rfc822 MIME parts.  All MIME parts with matching types are
 *  searched for the key strings.  The test returns true if any
 *  combination of a searched MIME part and key-list argument match.
 */

test "Nested Search" {
	if not body :text :contains "Hello" {
		test_fail "failed to match text/plain content";
	}
	if not body :text :contains "HTML Hello" {
		test_fail "failed to match text/html content";
	}
	if not body :text :contains "XHTML Hello" {
		test_fail "failed to match application/xhtml+xml content";
	}
	if body :text :contains ["<html>", "body"] {
		test_fail "erroneously matched text/html markup";
	}
	if not body :text :contains "Please say Hello" {
		test_fail "failed to match message/rfc822 body";
	}
	if body :text :contains "MIME" {
		test_fail "erroneously matched multipart prologue/epilogue text";
	}
}

/*
 * Broken/Empty parts
 */

test_set "message" text:
From: Whomever <whoever@example.com>
To: Someone <someone@example.com>
Date: Sat, 10 Oct 2009 00:30:04 +0200
Subject: whatever
Content-Type: multipart/mixed; boundary=outer

This is a multi-part message in MIME format.

--outer
Content-Type: text/html

--outer
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: multipart/related
Content-Disposition: inline

<html><body>Please say Hello</body></html>

--outer--

This is the end of the outer MIME multipart.
.
;

test "Nested Search" {
	if body :text :contains "Hello" {
		test_fail "Cannot match empty/broken part";
	}
	if body :text :contains ["<html>", "body"] {
		test_fail "erroneously matched text/html markup";
	}
	if body :text :contains "MIME" {
		test_fail "erroneously matched multipart prologue/epilogue text";
	}
}

