require "vnd.dovecot.testsuite";
require "envelope";

test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";

test "Redirect" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if not address :is "to" "tss@example.net" {
		test_fail "to address incorrect (strange forward)";
	}

	if not address :is "from" "stephan@example.org" {
		test_fail "from address incorrect (strange forward)";
	}

	if not envelope :is "to" "cras@example.net" {
		test_fail "envelope recipient incorrect";
	}

	if not envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "<>";
test_set "envelope.to" "timo@example.net";

test "Redirect from <>" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect (not changed)";
	}

	if not envelope :is "from" "" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";

test_config_set "sieve_redirect_envelope_from" " recipient ";
test_config_reload;

test "Redirect from [recipient]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect (not changed)";
	}

	if not envelope :is "from" "timo@example.net" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "orig_recipient ";
test_config_reload;

test "Redirect from [original recipient]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect (not changed)";
	}

	if not envelope :is "from" "tss@example.net" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "<backscatter@example.net> ";
test_config_reload;

test "Redirect from [<explicit>]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect (not changed)";
	}

	if not envelope :is "from" "backscatter@example.net" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";

test_config_set "sieve_redirect_envelope_from" "<>";
test_config_reload;

test "Redirect from [<>]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect (not changed)";
	}

	if not envelope :is "from" "" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "<>";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "<backscatter@example.net>";
test_config_reload;

test "Redirect from <> with [<explicit>]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "backscatter@example.net" {
		test_fail "envelope sender incorrect (erroneously changed)";
	}

	if not envelope :is "from" "" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "user_email";
test_config_reload;

test "Redirect from [user email - fallback default]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if not envelope :is "from" "timo@example.net" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"timo@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

test_result_reset;
test_set "message" text:
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "user_email";
test_config_set "sieve_user_email" "t.sirainen@example.net";
test_config_reload;

test "Redirect from [user email]" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	test_message :smtp 0;

	if envelope :is "from" "sirius@example.org" {
		test_fail "envelope sender incorrect (not changed)";
	}

	if not envelope :is "from" "t.sirainen@example.net" {
		test_fail "envelope sender incorrect";
	}

	if not header :contains "x-sieve-redirected-from"
		"t.sirainen@example.net" {
		test_fail "x-sieve-redirected-from header is incorrect";
	}
}

/*
 * Redirect mail loop (sieve_user_email)
 */

test_result_reset;
test_set "message" text:
X-Sieve-Redirected-From: t.sirainen@example.net
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "user_email";
test_config_set "sieve_user_email" "t.sirainen@example.net";
test_config_reload;

test "Redirect mail loop (sieve_user_email)" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	if test_message :smtp 0 {
		test_fail "failed to recognize mail loop";
	}
}

/*
 * Redirect mail loop (final recipient)
 */

test_result_reset;
test_set "message" text:
X-Sieve-Redirected-From: timo@example.net
From: stephan@example.org
To: tss@example.net
Subject: Frop!

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_reload;

test "Redirect mail loop (final recipient)" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	if test_message :smtp 0 {
		test_fail "failed to recognize mail loop";
	}
}

/*
 * Redirect mail loop (multiple headers)
 */

test_result_reset;
test_set "message" text:
X-Sieve-Redirected-From: stephan@example.net
From: stephan@example.org
To: tss@example.net
Subject: Frop!
X-Sieve-Redirected-From: t.sirainen@example.net
X-Sieve-Redirected-From: t.sirainen@example.com

Frop!
.
;
test_set "envelope.from" "sirius@example.org";
test_set "envelope.to" "timo@example.net";
test_set "envelope.orig_to" "tss@example.net";

test_config_set "sieve_redirect_envelope_from" "user_email";
test_config_set "sieve_user_email" "t.sirainen@example.net";
test_config_reload;

test "Redirect mail loop (sieve_user_email)" {
	redirect "cras@example.net";

	if not test_result_execute {
		test_fail "failed to execute redirect";
	}

	if test_message :smtp 0 {
		test_fail "failed to recognize mail loop";
	}
}
