+include $(top_srcdir)/Makefile.test.include
+
noinst_LTLIBRARIES = libimap-storage.la
AM_CPPFLAGS = \
pkginc_libdir=$(pkgincludedir)
pkginc_lib_HEADERS = $(headers)
+test_programs = \
+ test-imap-msgpart \
+ test-imap-metadata
+
+test_imap_msgpart_SOURCES = test-imap-msgpart.c
+test_imap_msgpart_LDADD = \
+ libimap-storage.la \
+ ../lib-storage/libstorage.la \
+ ../lib-dovecot/libdovecot.la \
+ $(LIBDOVECOT_TEST_LIBS)
+
+test_imap_metadata_SOURCES = test-imap-metadata.c
+test_imap_metadata_LDADD = \
+ libimap-storage.la \
+ ../lib-storage/libstorage.la \
+ ../lib-dovecot/libdovecot.la \
+ $(LIBDOVECOT_TEST_LIBS)
--- /dev/null
+/* Copyright (c) 2026 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "test-common.h"
+#include "mail-storage.h"
+#include "mail-namespace.h"
+#include "imap-metadata.h"
+
+static void test_imap_metadata_verify_entry_name(void)
+{
+ const struct {
+ const char *name;
+ bool valid;
+ } tests[] = {
+ { "/private/comment", TRUE },
+ { "/shared/comment", TRUE },
+ { "/private/foo/bar", TRUE },
+ { "/shared/a/b/c", TRUE },
+ { "/PRIVATE/UPPER", TRUE },
+ { "/Shared/Mixed", TRUE },
+ { "private/foo", FALSE },
+ { "/private", TRUE },
+ { "/shared", TRUE },
+ { "/private/", FALSE },
+ { "/shared//foo", FALSE },
+ { "/private/foo*", FALSE },
+ { "/shared/foo%", FALSE },
+ { "/other/foo", FALSE },
+ { "", FALSE },
+ { "/", FALSE },
+ { "/private/ctrl\x01", FALSE },
+ { "//private/foo", FALSE },
+ { "/private/foo//bar", FALSE },
+ };
+ unsigned int i;
+
+ test_begin("imap_metadata_verify_entry_name()");
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ const char *error = NULL;
+ bool result = imap_metadata_verify_entry_name(tests[i].name, &error);
+ test_assert_idx(result == tests[i].valid, i);
+ }
+ test_end();
+}
+
+int main(void)
+{
+ void (*const test_functions[])(void) = {
+ test_imap_metadata_verify_entry_name,
+ NULL
+ };
+ return test_run(test_functions);
+}
--- /dev/null
+/* Copyright (c) 2026 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "test-common.h"
+#include "mail-storage.h"
+#include "imap-msgpart.h"
+
+static void test_imap_msgpart_parse(void)
+{
+ const struct {
+ const char *section;
+ bool success;
+ bool contains_body;
+ } tests[] = {
+ { "", TRUE, TRUE },
+ { "1", TRUE, TRUE },
+ { "1.2", TRUE, TRUE },
+ { "MIME", FALSE, FALSE },
+ { "1.MIME", TRUE, TRUE },
+ { "HEADER", TRUE, FALSE },
+ { "1.HEADER", TRUE, FALSE },
+ { "TEXT", TRUE, TRUE },
+ { "1.TEXT", TRUE, TRUE },
+ { "HEADER.FIELDS (Subject Date)", TRUE, FALSE },
+ { "HEADER.FIELDS.NOT (From)", TRUE, FALSE },
+ { "1.HEADER.FIELDS (Subject)", TRUE, FALSE },
+ { "1.2.3.4", TRUE, TRUE },
+ { "1.2.MIME", TRUE, TRUE },
+ { "1.2.TEXT", TRUE, TRUE },
+ { "1.2.HEADER", TRUE, FALSE },
+ { "1.", FALSE, FALSE },
+ { ".1", FALSE, FALSE },
+ { "1.2..3", FALSE, FALSE },
+ { "HEADER.FIELDS", FALSE, FALSE },
+ { "HEADER.FIELDS ()", FALSE, FALSE },
+ { "INVALID", FALSE, FALSE },
+ };
+ unsigned int i;
+
+ test_begin("imap_msgpart_parse()");
+
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ struct imap_msgpart *part = NULL;
+ int ret = imap_msgpart_parse(tests[i].section, &part);
+
+ test_assert_idx((ret == 0) == tests[i].success, i);
+ if (ret == 0) {
+ test_assert_idx(imap_msgpart_contains_body(part) == tests[i].contains_body, i);
+ imap_msgpart_free(&part);
+ }
+ }
+
+ test_end();
+}
+
+int main(void)
+{
+ void (*const test_functions[])(void) = {
+ test_imap_msgpart_parse,
+ NULL
+ };
+ return test_run(test_functions);
+}