summaryrefslogtreecommitdiffstats
path: root/pigeonhole/tests/extensions/enotify
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/tests/extensions/enotify')
-rw-r--r--pigeonhole/tests/extensions/enotify/basic.svtest15
-rw-r--r--pigeonhole/tests/extensions/enotify/encodeurl.svtest359
-rw-r--r--pigeonhole/tests/extensions/enotify/errors.svtest45
-rw-r--r--pigeonhole/tests/extensions/enotify/errors/from-mailto.sieve7
-rw-r--r--pigeonhole/tests/extensions/enotify/errors/options.sieve18
-rw-r--r--pigeonhole/tests/extensions/enotify/errors/uri-mailto.sieve20
-rw-r--r--pigeonhole/tests/extensions/enotify/errors/uri.sieve5
-rw-r--r--pigeonhole/tests/extensions/enotify/execute.svtest99
-rw-r--r--pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex1.sieve26
-rw-r--r--pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex2.sieve22
-rw-r--r--pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex3.sieve31
-rw-r--r--pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex5.sieve11
-rw-r--r--pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex6.sieve5
-rw-r--r--pigeonhole/tests/extensions/enotify/execute/duplicates.sieve4
-rw-r--r--pigeonhole/tests/extensions/enotify/mailto.svtest541
-rw-r--r--pigeonhole/tests/extensions/enotify/notify_method_capability.svtest12
-rw-r--r--pigeonhole/tests/extensions/enotify/valid_notify_method.svtest31
17 files changed, 1251 insertions, 0 deletions
diff --git a/pigeonhole/tests/extensions/enotify/basic.svtest b/pigeonhole/tests/extensions/enotify/basic.svtest
new file mode 100644
index 0000000..2a03aee
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/basic.svtest
@@ -0,0 +1,15 @@
+require "vnd.dovecot.testsuite";
+require "enotify";
+
+test "Execute" {
+ /* Test to catch runtime segfaults */
+ if valid_notify_method
+ "mailto:stephan@example.com" {
+
+ /* Test to catch runtime segfaults */
+ notify
+ :message "This is probably very important"
+ :importance "1"
+ "mailto:stephan@example.com%2cstephan@example.org?subject=Important%20message%20received";
+ }
+}
diff --git a/pigeonhole/tests/extensions/enotify/encodeurl.svtest b/pigeonhole/tests/extensions/enotify/encodeurl.svtest
new file mode 100644
index 0000000..d334dd3
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/encodeurl.svtest
@@ -0,0 +1,359 @@
+require "vnd.dovecot.testsuite";
+require "encoded-character";
+require "variables";
+require "enotify";
+
+/*
+ * :encodeurl simple
+ */
+
+test ":encodeurl simple" {
+ set :encodeurl "url_data" "\\frop\\&fruts/^@";
+
+ if not string :is :comparator "i;octet" "${url_data}" "%5Cfrop%5C%26fruts%2F%5E%40" {
+ test_fail "url data encoded incorrectly '${url_data}'";
+ }
+}
+
+/*
+ * :encodeurl variable size limit
+ */
+
+test_config_set "sieve_variables_max_variable_size" "4000";
+test_config_reload :extension "variables";
+
+set "a" text:
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@
+.
+;
+
+test ":encodeurl variable size limit" {
+ set :length "alen" "${a}";
+
+ if not string "${alen}" "4000" {
+ test_fail "variable 'a' not 4000 bytes long (${alen})";
+ }
+
+ set :encodeurl "b" "${a}";
+ set :length "blen" "${b}";
+
+ if not string "${blen}" "3999" {
+ test_fail "variable 'b' not 3999 bytes long (${blen})";
+ }
+
+ set :encodeurl "c" "0${a}";
+ set :length "clen" "${c}";
+
+ if not string "${clen}" "4000" {
+ test_fail "variable 'c' not 4000 bytes long (${clen})";
+ }
+
+ set "cmt" "%40%40%40%40%40%40%40%40%40%40%40%40";
+ set "cmt" "${cmt}%40%40%40%40%40%40%40%40%40%40%40%0D%0A";
+ set "cmh" "${cmt}${cmt}${cmt}${cmt}";
+ set "cm" "${cmh}${cmh}${cmh}${cmh}${cmh}${cmh}${cmh}${cmh}${cmh}${cmh}";
+ set "cm" "${cm}${cmh}${cmh}${cmh}";
+ set "cm" "0${cm}${cmt}%40%40%40%40%40%40%40%40";
+
+ if not string :is "${c}" "${cm}" {
+ test_fail "variable 'c' has unexpected value";
+ }
+
+ set :encodeurl "d" "00${a}";
+ set :length "dlen" "${d}";
+
+ if not string "${dlen}" "3998" {
+ test_fail "variable 'd' not 3998 bytes long (${dlen})";
+ }
+}
+
+/*
+ * :encodeurl variable size limit UTF-8
+ */
+
+test_config_set "sieve_variables_max_variable_size" "4000";
+test_config_reload :extension "variables";
+
+set "a" text:
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}${unicode:4e03}
+.
+;
+
+test ":encodeurl variable size limit UTF-8" {
+ set :length "alen" "${a}";
+
+ if not string "${alen}" "546" {
+ test_fail "variable 'a' not 549 characters long (${alen})";
+ }
+
+ set :encodeurl "b" "${a}";
+ set :length "blen" "${b}";
+
+ if not string "${blen}" "3978" {
+ test_fail "variable 'b' not 3978 bytes long (${blen})";
+ }
+
+ set :encodeurl "c" "${a}${unicode:4e00}${unicode:4e00}";
+ set :length "clen" "${c}";
+
+ if not string "${clen}" "3996" {
+ test_fail "variable 'c' not 3996 bytes long (${clen})";
+ }
+
+ set :encodeurl "d" "${a}${unicode:4e00}${unicode:4e00}${unicode:4e00}";
+ set :length "dlen" "${d}";
+
+ if not string "${dlen}" "3996" {
+ test_fail "variable 'd' not 3996 bytes long (${dlen})";
+ }
+
+ set :encodeurl "e" "0000${a}${unicode:4e00}${unicode:4e00}";
+ set :length "elen" "${e}";
+
+ if not string "${elen}" "4000" {
+ test_fail "variable 'e' not 4000 bytes long (${elen})";
+ }
+
+ set :encodeurl "f" "00000${a}${unicode:4e00}${unicode:4e00}";
+ set :length "flen" "${f}";
+
+ if not string "${flen}" "3992" {
+ test_fail "variable 'f' not 3992 bytes long (${flen})";
+ }
+}
diff --git a/pigeonhole/tests/extensions/enotify/errors.svtest b/pigeonhole/tests/extensions/enotify/errors.svtest
new file mode 100644
index 0000000..5af36df
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/errors.svtest
@@ -0,0 +1,45 @@
+require "vnd.dovecot.testsuite";
+require "comparator-i;ascii-numeric";
+require "relational";
+
+require "enotify";
+
+test "Invalid URI (FIXME: count only)" {
+ if test_script_compile "errors/uri.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if not test_error :count "eq" :comparator "i;ascii-numeric" "2" {
+ test_fail "wrong number of errors reported";
+ }
+}
+
+test "Invalid mailto URI (FIXME: count only)" {
+ if test_script_compile "errors/uri-mailto.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if not test_error :count "eq" :comparator "i;ascii-numeric" "7" {
+ test_fail "wrong number of errors reported";
+ }
+}
+
+test "Invalid mailto :from address (FIXME: count only)" {
+ if test_script_compile "errors/from-mailto.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if not test_error :count "eq" :comparator "i;ascii-numeric" "3" {
+ test_fail "wrong number of errors reported";
+ }
+}
+
+test "Invalid :options argument (FIXME: count only)" {
+ if test_script_compile "errors/options.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if not test_error :count "eq" :comparator "i;ascii-numeric" "6" {
+ test_fail "wrong number of errors reported";
+ }
+}
diff --git a/pigeonhole/tests/extensions/enotify/errors/from-mailto.sieve b/pigeonhole/tests/extensions/enotify/errors/from-mailto.sieve
new file mode 100644
index 0000000..d519256
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/errors/from-mailto.sieve
@@ -0,0 +1,7 @@
+require "enotify";
+
+# 1: Invalid from address
+notify :from "stephan#example.org" "mailto:stephan@example.com";
+
+# 2: Empty from address
+notify :from "" "mailto:stephan@example.com";
diff --git a/pigeonhole/tests/extensions/enotify/errors/options.sieve b/pigeonhole/tests/extensions/enotify/errors/options.sieve
new file mode 100644
index 0000000..58d2265
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/errors/options.sieve
@@ -0,0 +1,18 @@
+require "enotify";
+
+# 1: empty option
+notify :options "" "mailto:stephan@example.org";
+
+# 2: invalid option name syntax
+notify :options "frop" "mailto:stephan@example.org";
+
+# 3: invalid option name syntax
+notify :options "_frop=" "mailto:stephan@example.org";
+
+# 4: invalid option name syntax
+notify :options "=frop" "mailto:stephan@example.org";
+
+# 5: invalid value
+notify :options "frop=frml
+frop" "mailto:stephan@example.org";
+
diff --git a/pigeonhole/tests/extensions/enotify/errors/uri-mailto.sieve b/pigeonhole/tests/extensions/enotify/errors/uri-mailto.sieve
new file mode 100644
index 0000000..2aced86
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/errors/uri-mailto.sieve
@@ -0,0 +1,20 @@
+require "enotify";
+
+# 1: Invalid character in to part
+notify "mailto:stephan@example.org;?header=frop";
+
+# 2: Invalid character in hname
+notify "mailto:stephan@example.org?header<=frop";
+
+# 3: Invalid character in hvalue
+notify "mailto:stephan@example.org?header=fr>op";
+
+# 4: Invalid header name
+notify "mailto:stephan@example.org?header:=frop";
+
+# 5: Invalid recipient
+notify "mailto:stephan%23example.org";
+
+# 6: Invalid to header recipient
+notify "mailto:stephan@example.org?to=nico%23frop.example.org";
+
diff --git a/pigeonhole/tests/extensions/enotify/errors/uri.sieve b/pigeonhole/tests/extensions/enotify/errors/uri.sieve
new file mode 100644
index 0000000..13ead81
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/errors/uri.sieve
@@ -0,0 +1,5 @@
+require "enotify";
+
+# 1: Invalid url scheme
+notify "snailto:stephan@example.org";
+
diff --git a/pigeonhole/tests/extensions/enotify/execute.svtest b/pigeonhole/tests/extensions/enotify/execute.svtest
new file mode 100644
index 0000000..cd6486d
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute.svtest
@@ -0,0 +1,99 @@
+require "vnd.dovecot.testsuite";
+require "relational";
+
+
+/*
+ * Execution testing (currently just meant to trigger any segfaults)
+ */
+
+test "RFC Example 1" {
+ if not test_script_compile "execute/draft-rfc-ex1.sieve" {
+ test_fail "script compile failed";
+ }
+
+ if not test_script_run {
+ test_fail "script run failed";
+ }
+
+ if not test_result_execute {
+ test_fail "result execute failed";
+ }
+}
+
+test "RFC Example 2" {
+ if not test_script_compile "execute/draft-rfc-ex2.sieve" {
+ test_fail "script compile failed";
+ }
+
+ if not test_script_run {
+ test_fail "script execute failed";
+ }
+
+ if not test_result_execute {
+ test_fail "result execute failed";
+ }
+}
+
+/* tel: not supported
+test "RFC Example 3" {
+ if not test_script_compile "execute/draft-rfc-ex3.sieve" {
+ test_fail "script compile failed";
+ }
+
+ if not test_script_run {
+ test_fail "script execute failed";
+ }
+
+ if not test_result_execute {
+ test_fail "result execute failed";
+ }
+}
+*/
+
+/* tel: and xmmp: not supported
+test "RFC Example 5" {
+ if not test_script_compile "execute/draft-rfc-ex5.sieve" {
+ test_fail "script compile failed";
+ }
+
+ if not test_script_run {
+ test_fail "script execute failed";
+ }
+
+ if not test_result_execute {
+ test_fail "result execute failed";
+ }
+}
+*/
+
+test "RFC Example 6" {
+ if not test_script_compile "execute/draft-rfc-ex6.sieve" {
+ test_fail "script compile failed";
+ }
+
+ if not test_script_run {
+ test_fail "script execute failed";
+ }
+
+ if not test_result_execute {
+ test_fail "result execute failed";
+ }
+}
+
+test "Duplicate recipients" {
+ if not test_script_compile "execute/duplicates.sieve" {
+ test_fail "script compile failed";
+ }
+
+ if not test_script_run {
+ test_fail "script execute failed";
+ }
+
+ if test_result_action :count "ne" "2" {
+ test_fail "second notify action was discarded entirely";
+ }
+
+ if not test_result_execute {
+ test_fail "result execute failed";
+ }
+}
diff --git a/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex1.sieve b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex1.sieve
new file mode 100644
index 0000000..6747d7b
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex1.sieve
@@ -0,0 +1,26 @@
+require ["enotify", "fileinto", "variables"];
+
+if header :contains "from" "boss@example.org" {
+ notify :importance "1"
+ :message "This is probably very important"
+ "mailto:alm@example.com";
+ # Don't send any further notifications
+ stop;
+}
+
+if header :contains "to" "sievemailinglist@example.org" {
+ # :matches is used to get the value of the Subject header
+ if header :matches "Subject" "*" {
+ set "subject" "${1}";
+ }
+
+ # :matches is used to get the value of the From header
+ if header :matches "From" "*" {
+ set "from" "${1}";
+ }
+
+ notify :importance "3"
+ :message "[SIEVE] ${from}: ${subject}"
+ "mailto:alm@example.com";
+ fileinto "INBOX.sieve";
+}
diff --git a/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex2.sieve b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex2.sieve
new file mode 100644
index 0000000..a5c6a26
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex2.sieve
@@ -0,0 +1,22 @@
+require ["enotify", "fileinto", "variables", "envelope"];
+
+if header :matches "from" "*@*.example.org" {
+ # :matches is used to get the MAIL FROM address
+ if envelope :all :matches "from" "*" {
+ set "env_from" " [really: ${1}]";
+ }
+
+ # :matches is used to get the value of the Subject header
+ if header :matches "Subject" "*" {
+ set "subject" "${1}";
+ }
+
+ # :matches is used to get the address from the From header
+ if address :matches :all "from" "*" {
+ set "from_addr" "${1}";
+ }
+
+ notify :message "${from_addr}${env_from}: ${subject}"
+ "mailto:alm@example.com";
+}
+
diff --git a/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex3.sieve b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex3.sieve
new file mode 100644
index 0000000..a7b4a64
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex3.sieve
@@ -0,0 +1,31 @@
+require ["enotify", "variables"];
+
+set "notif_method"
+ "xmpp:tim@example.com?message;subject=SIEVE;body=You%20got%20mail";
+
+if header :contains "subject" "Your dog" {
+ set "notif_method" "tel:+14085551212";
+}
+
+if header :contains "to" "sievemailinglist@example.org" {
+ set "notif_method" "";
+}
+
+if not string :is "${notif_method}" "" {
+ notify "${notif_method}";
+}
+
+if header :contains "from" "boss@example.org" {
+ # :matches is used to get the value of the Subject header
+ if header :matches "Subject" "*" {
+ set "subject" "${1}";
+ }
+
+ # don't need high importance notification for
+ # a 'for your information'
+ if not header :contains "subject" "FYI:" {
+ notify :importance "1" :message "BOSS: ${subject}"
+ "tel:+14085551212";
+ }
+}
+
diff --git a/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex5.sieve b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex5.sieve
new file mode 100644
index 0000000..c6b7dc6
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex5.sieve
@@ -0,0 +1,11 @@
+require ["enotify"];
+
+if notify_method_capability
+ "xmpp:tim@example.com?message;subject=SIEVE"
+ "Online"
+ "yes" {
+ notify :importance "1" :message "You got mail"
+ "xmpp:tim@example.com?message;subject=SIEVE";
+} else {
+ notify :message "You got mail" "tel:+14085551212";
+}
diff --git a/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex6.sieve b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex6.sieve
new file mode 100644
index 0000000..6a65c64
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute/draft-rfc-ex6.sieve
@@ -0,0 +1,5 @@
+require ["enotify", "variables"];
+
+set :encodeurl "body_param" "Safe body&evil=evilbody";
+
+notify "mailto:tim@example.com?body=${body_param}";
diff --git a/pigeonhole/tests/extensions/enotify/execute/duplicates.sieve b/pigeonhole/tests/extensions/enotify/execute/duplicates.sieve
new file mode 100644
index 0000000..17f2388
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/execute/duplicates.sieve
@@ -0,0 +1,4 @@
+require "enotify";
+
+notify :message "Incoming stupidity." "mailto:stephan@example.org%2cstephan@friep.example.com%2cidiot@example.org";
+notify :message "There it is." "mailto:tss@example.net%2cstephan@example.org%2cidiot@example.org%2cnico@frop.example.org%2cstephan@friep.example.com";
diff --git a/pigeonhole/tests/extensions/enotify/mailto.svtest b/pigeonhole/tests/extensions/enotify/mailto.svtest
new file mode 100644
index 0000000..68d8daa
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/mailto.svtest
@@ -0,0 +1,541 @@
+require "vnd.dovecot.testsuite";
+require "enotify";
+require "relational";
+require "envelope";
+require "variables";
+require "comparator-i;ascii-numeric";
+
+/*
+ * Simple test
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test "Simple" {
+ notify "mailto:stephan@example.org";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not header :matches "Auto-Submitted" "auto-notified*" {
+ test_fail "auto-submitted header set inappropriately";
+ }
+
+ if not exists "X-Sieve" {
+ test_fail "x-sieve header missing from outgoing message";
+ }
+
+ if anyof (
+ not header :matches "x-priority" "3 *",
+ not header "importance" "normal") {
+
+ test_fail "default priority is not normal";
+ }
+}
+
+/*
+ * Multiple recipients
+ */
+
+test_result_reset;
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test "Multiple recipients" {
+ notify "mailto:timo@example.com%2cstephan@dovecot.example.net?cc=postmaster@frop.example.org&subject=Frop%20received";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not address :is "to" "timo@example.com" {
+ test_fail "first To address missing";
+ }
+
+ if not address :is "to" "stephan@dovecot.example.net" {
+ test_fail "second To address missing";
+ }
+
+ if not address :is "cc" "postmaster@frop.example.org" {
+ test_fail "first Cc address missing";
+ }
+
+ if not address :count "eq" :comparator "i;ascii-numeric" "to" "2" {
+ test_fail "too many recipients in To header";
+ }
+
+ if not address :count "eq" :comparator "i;ascii-numeric" "cc" "1" {
+ test_fail "too many recipients in Cc header";
+ }
+
+ if not header "subject" "Frop received" {
+ test_fail "subject header set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not header :matches "Auto-Submitted" "auto-notified*" {
+ test_fail "auto-submitted header not found for second message";
+ }
+
+ test_message :smtp 2;
+
+ if not header :matches "Auto-Submitted" "auto-notified*" {
+ test_fail "auto-submitted header not found for third message";
+ }
+}
+
+/*
+ * Duplicate recipients
+ */
+
+test_result_reset;
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test "Duplicate recipients" {
+ notify "mailto:timo@example.com%2cstephan@dovecot.example.net?cc=stephan@dovecot.example.net";
+ notify "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if address "Cc" "stephan@dovecot.example.net" {
+ test_fail "duplicate recipient not removed from first message";
+ }
+
+ test_message :smtp 1;
+
+ if address "Cc" "timo@example.com" {
+ test_fail "duplicate recipient not removed from second message";
+ }
+}
+
+
+/*
+ * Notifying on automated messages
+ */
+
+test_result_reset;
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Auto-submitted: auto-notify
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test "Notifying on automated messages" {
+ notify "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ if test_message :smtp 0 {
+ test_fail "notified of auto-submitted message";
+ }
+}
+
+/*
+ * Envelope
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test_result_reset;
+
+test_set "envelope.from" "sirius@example.org";
+test_set "envelope.to" "bertus@frop.example.org";
+
+test "Envelope" {
+ notify "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not envelope :localpart :is "from" "postmaster" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "stephan@example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not envelope :localpart :is "from" "postmaster" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "timo@example.com" {
+ test_fail "envelope sender set incorrectly";
+ }
+}
+
+/*
+ * Envelope :from
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test_set "envelope.from" "sirius@example.org";
+test_set "envelope.to" "bertus@frop.example.org";
+
+test_result_reset;
+
+test "Envelope :from" {
+ notify :from "nico@frop.example.org"
+ "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not envelope :is "from" "nico@frop.example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "stephan@example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not envelope :is "from" "nico@frop.example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "timo@example.com" {
+ test_fail "envelope sender set incorrectly";
+ }
+}
+
+/*
+ * Envelope <>
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test_set "envelope.from" "<>";
+test_set "envelope.to" "bertus@frop.example.org";
+
+test_result_reset;
+
+test "Envelope <>" {
+ notify :from "nico@frop.example.org"
+ "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not envelope :is "from" "" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "stephan@example.org" {
+ test_fail "envelope recipient set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not envelope :is "from" "" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "timo@example.com" {
+ test_fail "envelope recipient set incorrectly";
+ }
+}
+
+/*
+ * Envelope config - sender
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test_set "envelope.from" "sirius@example.org";
+test_set "envelope.to" "bertus@frop.example.org";
+
+test_config_set "sieve_notify_mailto_envelope_from"
+ "sender";
+test_config_reload :extension "enotify";
+test_result_reset;
+
+test "Envelope config - sender" {
+ notify :from "nico@frop.example.org"
+ "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not header :is "from" "nico@frop.example.org" {
+ test_fail "from set incorrectly";
+ }
+
+ if not envelope :is "from" "sirius@example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "stephan@example.org" {
+ test_fail "envelope recipient set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not header :is "from" "nico@frop.example.org" {
+ test_fail "from set incorrectly";
+ }
+
+ if not envelope :is "from" "sirius@example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "timo@example.com" {
+ test_fail "envelope recipient set incorrectly";
+ }
+}
+
+/*
+ * Envelope config - recipient
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test_set "envelope.from" "sirius@example.org";
+test_set "envelope.to" "bertus@frop.example.org";
+
+test_config_set "sieve_notify_mailto_envelope_from"
+ "recipient";
+test_config_reload :extension "enotify";
+test_result_reset;
+
+test "Envelope config - recipient" {
+ notify :from "nico@frop.example.org"
+ "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not header :is "from" "nico@frop.example.org" {
+ test_fail "from set incorrectly";
+ }
+
+ if not envelope :is "from" "bertus@frop.example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "stephan@example.org" {
+ test_fail "envelope recipient set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not header :is "from" "nico@frop.example.org" {
+ test_fail "from set incorrectly";
+ }
+
+ if not envelope :is "from" "bertus@frop.example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "timo@example.com" {
+ test_fail "envelope recipient set incorrectly";
+ }
+}
+
+/*
+ * Envelope config - user_email
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test_set "envelope.from" "sirius@example.org";
+test_set "envelope.to" "bertus@frop.example.org";
+
+test_config_set "sieve_notify_mailto_envelope_from"
+ "user_email";
+test_config_set "sieve_user_email" "b.wortel@example.org";
+test_config_reload;
+test_config_reload :extension "enotify";
+test_result_reset;
+
+test "Envelope config - user_email" {
+ notify :from "nico@frop.example.org"
+ "mailto:stephan@example.org?cc=timo@example.com";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ if not header :is "from" "nico@frop.example.org" {
+ test_fail "from set incorrectly";
+ }
+
+ if not envelope :is "from" "b.wortel@example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "stephan@example.org" {
+ test_fail "envelope recipient set incorrectly";
+ }
+
+ test_message :smtp 1;
+
+ if not header :is "from" "nico@frop.example.org" {
+ test_fail "from set incorrectly";
+ }
+
+ if not envelope :is "from" "b.wortel@example.org" {
+ test_fail "envelope sender set incorrectly";
+ }
+
+ if not envelope :is "to" "timo@example.com" {
+ test_fail "envelope recipient set incorrectly";
+ }
+}
+
+/*
+ * UTF-8 addresses
+ */
+
+test_result_reset;
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Subject: Frop!
+
+Klutsefluts.
+.
+;
+
+test "UTF-8 address" {
+ set "to" "=?utf-8?q?G=C3=BCnther?= M. Karotte <g.m.karotte@example.com>";
+ set "cc" "Dieter T. =?utf-8?q?Stoppelr=C3=BCbe?= <d.t.stoppelruebe@example.com>";
+
+ set :encodeurl "to_enc" "${to}";
+ set :encodeurl "cc_enc" "${cc}";
+
+ notify "mailto:?to=${to_enc}&cc=${cc_enc}";
+
+ if not test_result_execute {
+ test_fail "failed to execute notify";
+ }
+
+ test_message :smtp 0;
+
+ set "expected" "Günther M. Karotte <g.m.karotte@example.com>";
+ if not header :is "to" "${expected}" {
+ if header :matches "to" "*" { set "decoded" "${1}"; }
+
+ test_fail text:
+to header is not encoded/decoded properly:
+expected: ${expected}
+decoded: ${decoded}
+.
+;
+ }
+
+ set "expected" "Dieter T. Stoppelrübe <d.t.stoppelruebe@example.com>";
+ if not header :is "cc" "${expected}" {
+ if header :matches "cc" "*" { set "decoded" "${1}"; }
+
+ test_fail text:
+to header is not encoded/decoded properly:
+expected: ${expected}
+decoded: ${decoded}
+.
+;
+ }
+}
diff --git a/pigeonhole/tests/extensions/enotify/notify_method_capability.svtest b/pigeonhole/tests/extensions/enotify/notify_method_capability.svtest
new file mode 100644
index 0000000..0d13477
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/notify_method_capability.svtest
@@ -0,0 +1,12 @@
+require "vnd.dovecot.testsuite";
+require "enotify";
+
+test "Mailto" {
+ if not notify_method_capability :is "mailto:stephan@example.org" "online" "maybe" {
+ test_fail "test should have matched";
+ }
+
+ if notify_method_capability :is "mailto:stephan@example.org" "online" "yes" {
+ test_fail "test should not have matched";
+ }
+}
diff --git a/pigeonhole/tests/extensions/enotify/valid_notify_method.svtest b/pigeonhole/tests/extensions/enotify/valid_notify_method.svtest
new file mode 100644
index 0000000..35255d6
--- /dev/null
+++ b/pigeonhole/tests/extensions/enotify/valid_notify_method.svtest
@@ -0,0 +1,31 @@
+require "vnd.dovecot.testsuite";
+
+require "enotify";
+
+test "Mailto: invalid header name" {
+ if valid_notify_method
+ "mailto:stephan@example.org?header:=frop" {
+ test_fail "invalid uri accepted";
+ }
+}
+
+test "Mailto: invalid recipient" {
+ if valid_notify_method
+ "mailto:stephan%23example.org" {
+ test_fail "invalid uri accepted";
+ }
+}
+
+test "Mailto: invalid to header recipient" {
+ if valid_notify_method
+ "mailto:stephan@example.org?to=nico%23frop.example.org" {
+ test_fail "invalid uri accepted";
+ }
+}
+
+test "Mailto: valid URI" {
+ if not valid_notify_method
+ "mailto:stephan@example.org" {
+ test_fail "valid uri denied";
+ }
+}