+Subject: Re: Basic text/html message
+Date: Fri, 21 Nov 1997 10:01:10 -0600
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="=-NJextDaQ1tE2ZGhW9Wm0"
+Message-ID: <3456@example.net>
+In-Reply-To: <1234@local.machine.example>
+References: <1234@local.machine.example>
+X-Mailer: Geary Test Suite 1.0
+
+--=-NJextDaQ1tE2ZGhW9Wm0
+Content-Type: text/plain; charset=UTF-8; format=flowed
+Content-Transfer-Encoding: quoted-printable
+
+This is the first line.
+
+This is the second line.
+
+=
+
+--=-NJextDaQ1tE2ZGhW9Wm0
+Content-Type: text/html; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+This is the first line.
+
+
This is the second line.
+
+=
+
+--=-NJextDaQ1tE2ZGhW9Wm0--
diff --git a/test/data/basic-text-html.eml b/test/data/basic-text-html.eml
new file mode 100644
index 00000000..0c3f4a6c
--- /dev/null
+++ b/test/data/basic-text-html.eml
@@ -0,0 +1,18 @@
+From: Alice
+Sender: Bob
+To: Charlie
+CC: Dave
+BCC: Eve
+Reply-To: \"Alice: Personal Account\"
+Subject: Re: Basic text/html message
+Date: Fri, 21 Nov 1997 10:01:10 -0600
+Content-Type: text/html; charset=UTF-8
+Message-ID: <3456@example.net>
+In-Reply-To: <1234@local.machine.example>
+References: <1234@local.machine.example>
+X-Mailer: Geary Test Suite 1.0
+
+This is the first line.
+
+
This is the second line.
+
diff --git a/test/data/basic-text-plain.eml b/test/data/basic-text-plain.eml
new file mode 100644
index 00000000..517d15ec
--- /dev/null
+++ b/test/data/basic-text-plain.eml
@@ -0,0 +1,17 @@
+From: Alice
+Sender: Bob
+To: Charlie
+CC: Dave
+BCC: Eve
+Reply-To: "Alice: Personal Account"
+Subject: Re: Basic text/plain message
+Date: Fri, 21 Nov 1997 10:01:10 -0600
+Message-ID: <3456@example.net>
+In-Reply-To: <1234@local.machine.example>
+References: <1234@local.machine.example>
+X-Mailer: Geary Test Suite 1.0
+
+This is the first line.
+
+This is the second line.
+
diff --git a/test/data/geary-0.6-db.tar.xz b/test/data/geary-0.6-db.tar.xz
new file mode 100644
index 00000000..4ffe9af0
Binary files /dev/null and b/test/data/geary-0.6-db.tar.xz differ
diff --git a/test/data/meson.build b/test/data/meson.build
new file mode 100644
index 00000000..a4cda4d6
--- /dev/null
+++ b/test/data/meson.build
@@ -0,0 +1,3 @@
+geary_test_engine_resources = gnome.compile_resources('org.gnome.GearyTest',
+ files('org.gnome.GearyTest.gresource.xml'),
+)
diff --git a/test/data/org.gnome.GearyTest.gresource.xml b/test/data/org.gnome.GearyTest.gresource.xml
new file mode 100644
index 00000000..eeeb42fd
--- /dev/null
+++ b/test/data/org.gnome.GearyTest.gresource.xml
@@ -0,0 +1,9 @@
+
+
+
+ basic-text-plain.eml
+ basic-text-html.eml
+ basic-multipart-alternative.eml
+ geary-0.6-db.tar.xz
+
+
diff --git a/test/engine/api/geary-attachment-test.vala b/test/engine/api/geary-attachment-test.vala
index 8127b8d3..63ac9fa9 100644
--- a/test/engine/api/geary-attachment-test.vala
+++ b/test/engine/api/geary-attachment-test.vala
@@ -10,7 +10,6 @@ extern const string _SOURCE_ROOT_DIR;
class Geary.AttachmentTest : TestCase {
- private const string ATTACHMENT_ID = "test-id";
private const string CONTENT_TYPE = "image/png";
private const string CONTENT_ID = "test-content-id";
private const string CONTENT_DESC = "Mea navis volitans anguillis plena est";
@@ -21,19 +20,19 @@ class Geary.AttachmentTest : TestCase {
private Mime.ContentDisposition? content_disposition;
private File? file;
+
private class TestAttachment : Attachment {
// A test article
- internal TestAttachment(string id,
- Mime.ContentType content_type,
+ internal TestAttachment(Mime.ContentType content_type,
string? content_id,
string? content_description,
Mime.ContentDisposition content_disposition,
string? content_filename,
- File file,
- int64 filesize) {
- base(id, content_type, content_id, content_description,
- content_disposition, content_filename, file, filesize);
+ GLib.File file) {
+ base(content_type, content_id, content_description,
+ content_disposition, content_filename);
+ set_file_info(file, 742);
}
}
@@ -63,7 +62,7 @@ class Geary.AttachmentTest : TestCase {
public override void set_up() {
try {
this.content_type = Mime.ContentType.deserialize(CONTENT_TYPE);
- this.default_type = Mime.ContentType.deserialize(Mime.ContentType.DEFAULT_CONTENT_TYPE);
+ this.default_type = Mime.ContentType.ATTACHMENT_DEFAULT;
this.content_disposition = new Mime.ContentDisposition("attachment", null);
File source = File.new_for_path(_SOURCE_ROOT_DIR);
@@ -76,14 +75,12 @@ class Geary.AttachmentTest : TestCase {
public void get_safe_file_name_with_content_name() throws Error {
const string TEST_FILENAME = "test-filename.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.content_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
TEST_FILENAME,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -97,14 +94,12 @@ class Geary.AttachmentTest : TestCase {
const string TEST_FILENAME = "test-filename.jpg";
const string RESULT_FILENAME = "test-filename.jpg.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.content_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
TEST_FILENAME,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -118,14 +113,12 @@ class Geary.AttachmentTest : TestCase {
const string TEST_FILENAME = "test-filename";
const string RESULT_FILENAME = "test-filename.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.content_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
TEST_FILENAME,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -138,14 +131,12 @@ class Geary.AttachmentTest : TestCase {
public void get_safe_file_name_with_no_content_name() throws Error {
const string RESULT_FILENAME = CONTENT_ID + ".png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.content_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
null,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -156,16 +147,14 @@ class Geary.AttachmentTest : TestCase {
}
public void get_safe_file_name_with_no_content_name_or_id() throws Error {
- const string RESULT_FILENAME = ATTACHMENT_ID + ".png";
+ const string RESULT_FILENAME = "attachment.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.content_type,
null,
CONTENT_DESC,
content_disposition,
null,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -179,14 +168,12 @@ class Geary.AttachmentTest : TestCase {
const string ALT_TEXT = "some text";
const string RESULT_FILENAME = "some text.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.content_type,
null,
CONTENT_DESC,
content_disposition,
null,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(ALT_TEXT, (obj, ret) => {
@@ -199,14 +186,12 @@ class Geary.AttachmentTest : TestCase {
public void get_safe_file_name_with_default_content_type() throws Error {
const string TEST_FILENAME = "test-filename.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.default_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
TEST_FILENAME,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -221,14 +206,12 @@ class Geary.AttachmentTest : TestCase {
const string TEST_FILENAME = "test-filename.jpg";
const string RESULT_FILENAME = "test-filename.jpg.png";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.default_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
TEST_FILENAME,
- this.file,
- 742
+ this.file
);
test.get_safe_file_name.begin(null, (obj, ret) => {
@@ -242,14 +225,12 @@ class Geary.AttachmentTest : TestCase {
throws Error {
const string TEST_FILENAME = "test-filename.unlikely";
Attachment test = new TestAttachment(
- ATTACHMENT_ID,
this.default_type,
CONTENT_ID,
CONTENT_DESC,
content_disposition,
TEST_FILENAME,
- File.new_for_path(TEST_FILENAME),
- 742
+ File.new_for_path(TEST_FILENAME)
);
test.get_safe_file_name.begin(null, (obj, ret) => {
diff --git a/test/engine/db/db-database-test.vala b/test/engine/db/db-database-test.vala
new file mode 100644
index 00000000..e79e8d4a
--- /dev/null
+++ b/test/engine/db/db-database-test.vala
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2018 Michael Gratton
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+class Geary.Db.DatabaseTest : TestCase {
+
+
+ public DatabaseTest() {
+ base("Geary.Db.DatabaseTest");
+ add_test("transient_open", transient_open);
+ add_test("open_existing", open_existing);
+ add_test("open_create_file", open_create_file);
+ add_test("open_create_dir", open_create_dir);
+ add_test("open_create_dir_existing", open_create_dir_existing);
+ }
+
+ public void transient_open() throws Error {
+ Database db = new Geary.Db.Database.transient();
+ db.open.begin(
+ Geary.Db.DatabaseFlags.NONE, null, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ // Need to get a connection since the database doesn't
+ // actually get created until then
+ db.get_master_connection();
+ }
+
+ public void open_existing() throws Error {
+ GLib.FileIOStream stream;
+ GLib.File tmp_file = GLib.File.new_tmp(
+ "geary-db-database-test-XXXXXX", out stream
+ );
+
+ Database db = new Geary.Db.Database.persistent(tmp_file);
+ db.open.begin(
+ Geary.Db.DatabaseFlags.NONE, null, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ // Need to get a connection since the database doesn't
+ // actually get created until then
+ db.get_master_connection();
+
+ tmp_file.delete();
+ }
+
+ public void open_create_file() throws Error {
+ GLib.File tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ Database db = new Geary.Db.Database.persistent(
+ tmp_dir.get_child("test.db")
+ );
+ db.open.begin(
+ Geary.Db.DatabaseFlags.CREATE_FILE, null, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ // Need to get a connection since the database doesn't
+ // actually get created until then
+ db.get_master_connection();
+
+ db.file.delete();
+ tmp_dir.delete();
+ }
+
+ public void open_create_dir() throws Error {
+ GLib.File tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ Database db = new Geary.Db.Database.persistent(
+ tmp_dir.get_child("nonexistent").get_child("test.db")
+ );
+ db.open.begin(
+ Geary.Db.DatabaseFlags.CREATE_DIRECTORY |
+ Geary.Db.DatabaseFlags.CREATE_FILE,
+ null, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ // Need to get a connection since the database doesn't
+ // actually get created until then
+ db.get_master_connection();
+
+ db.file.delete();
+ db.file.get_parent().delete();
+ tmp_dir.delete();
+ }
+
+ public void open_create_dir_existing() throws Error {
+ GLib.File tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ Database db = new Geary.Db.Database.persistent(
+ tmp_dir.get_child("test.db")
+ );
+ db.open.begin(
+ Geary.Db.DatabaseFlags.CREATE_DIRECTORY |
+ Geary.Db.DatabaseFlags.CREATE_FILE,
+ null, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ // Need to get a connection since the database doesn't
+ // actually get created until then
+ db.get_master_connection();
+
+ db.file.delete();
+ tmp_dir.delete();
+ }
+
+
+}
diff --git a/test/engine/db/db-versioned-database-test.vala b/test/engine/db/db-versioned-database-test.vala
new file mode 100644
index 00000000..6d52abc8
--- /dev/null
+++ b/test/engine/db/db-versioned-database-test.vala
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 Michael Gratton
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+
+class Geary.Db.VersionedDatabaseTest : TestCase {
+
+
+ public VersionedDatabaseTest() {
+ base("Geary.Db.VersionedDatabaseTest");
+ add_test("open_new", open_new);
+ }
+
+ public void open_new() throws Error {
+ GLib.File tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ GLib.File sql1 = tmp_dir.get_child("version-001.sql");
+ sql1.create(
+ GLib.FileCreateFlags.NONE
+ ).write("CREATE TABLE TestTable (id INTEGER PRIMARY KEY, col TEXT);".data);
+
+ GLib.File sql2 = tmp_dir.get_child("version-002.sql");
+ sql2.create(
+ GLib.FileCreateFlags.NONE
+ ).write("INSERT INTO TestTable (col) VALUES ('value');".data);
+
+ VersionedDatabase db = new VersionedDatabase.persistent(
+ tmp_dir.get_child("test.db"), tmp_dir
+ );
+
+ db.open.begin(
+ Geary.Db.DatabaseFlags.CREATE_FILE, null, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ Geary.Db.Result result = db.query("SELECT * FROM TestTable;");
+ assert_false(result.finished, "Row not inserted");
+ assert_string("value", result.string_for("col"));
+ assert_false(result.next(), "Multiple rows inserted");
+
+ db.file.delete();
+ sql1.delete();
+ sql2.delete();
+ tmp_dir.delete();
+ }
+
+
+}
diff --git a/test/engine/imap-db/imap-db-attachment-test.vala b/test/engine/imap-db/imap-db-attachment-test.vala
new file mode 100644
index 00000000..2211655b
--- /dev/null
+++ b/test/engine/imap-db/imap-db-attachment-test.vala
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2018 Michael Gratton
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+
+class Geary.ImapDB.AttachmentTest : TestCase {
+
+
+ private const string ATTACHMENT_BODY = "This is an attachment.\r\n";
+
+
+ public AttachmentTest() {
+ base("Geary.ImapDB.AttachmentTest");
+ add_test("new_from_minimal_mime_part", new_from_minimal_mime_part);
+ add_test("new_from_complete_mime_part", new_from_complete_mime_part);
+ add_test("new_from_inline_mime_part", new_from_inline_mime_part);
+ }
+
+ public void new_from_minimal_mime_part() throws Error {
+ GMime.Part part = new_part(null, ATTACHMENT_BODY.data);
+ part.set_header("Content-Type", "");
+
+ Attachment test = new Attachment.from_part(
+ 1, new Geary.RFC822.Part(part)
+ );
+ assert_string(
+ Geary.Mime.ContentType.ATTACHMENT_DEFAULT.to_string(),
+ test.content_type.to_string()
+ );
+ assert_null_string(test.content_id, "content_id");
+ assert_null_string(test.content_description, "content_description");
+ assert_int(
+ Geary.Mime.DispositionType.UNSPECIFIED,
+ test.content_disposition.disposition_type,
+ "content disposition type"
+ );
+ assert_false(test.has_content_filename, "has_content_filename");
+ assert_null_string(test.content_filename, "content_filename");
+ }
+
+ public void new_from_complete_mime_part() throws Error {
+ const string TYPE = "text/plain";
+ const string ID = "test-id";
+ const string DESC = "test description";
+ const string NAME = "test.txt";
+
+ GMime.Part part = new_part(null, ATTACHMENT_BODY.data);
+ part.set_content_id(ID);
+ part.set_content_description(DESC);
+ part.set_content_disposition(
+ new GMime.ContentDisposition.from_string(
+ "attachment; filename=%s".printf(NAME)
+ )
+ );
+
+ Attachment test = new Attachment.from_part(
+ 1, new Geary.RFC822.Part(part)
+ );
+
+ assert_string(TYPE, test.content_type.to_string());
+ assert_string(ID, test.content_id);
+ assert_string(DESC, test.content_description);
+ assert_int(
+ Geary.Mime.DispositionType.ATTACHMENT,
+ test.content_disposition.disposition_type
+ );
+ assert_true(test.has_content_filename, "has_content_filename");
+ assert_string(test.content_filename, NAME, "content_filename");
+ }
+
+ public void new_from_inline_mime_part() throws Error {
+ GMime.Part part = new_part(null, ATTACHMENT_BODY.data);
+ part.set_content_disposition(
+ new GMime.ContentDisposition.from_string("inline")
+ );
+
+ Attachment test = new Attachment.from_part(
+ 1, new Geary.RFC822.Part(part)
+ );
+
+ assert_int(
+ Geary.Mime.DispositionType.INLINE,
+ test.content_disposition.disposition_type
+ );
+ }
+
+}
+
+class Geary.ImapDB.AttachmentIoTest : TestCase {
+
+
+ private const string ENCODED_BODY = "This is an attachment.\r\n";
+ private const string DECODED_BODY = "This is an attachment.\n";
+
+ private GLib.File? tmp_dir;
+ private Geary.Db.Database? db;
+
+ public AttachmentIoTest() {
+ base("Geary.ImapDB.AttachmentIoTest");
+ add_test("save_minimal_attachment", save_minimal_attachment);
+ add_test("save_complete_attachment", save_complete_attachment);
+ add_test("save_qp_attachment", save_qp_attachment);
+ add_test("list_attachments", list_attachments);
+ add_test("delete_attachments", delete_attachments);
+ }
+
+ public override void set_up() throws Error {
+ this.tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-impadb-attachment-io-test-XXXXXX")
+ );
+
+ this.db = new Geary.Db.Database.transient();
+ this.db.open.begin(
+ Geary.Db.DatabaseFlags.NONE, null, null,
+ (obj, res) => { async_complete(res); }
+ );
+ this.db.open.end(async_result());
+ this.db.exec("""
+CREATE TABLE MessageTable (
+ id INTEGER PRIMARY KEY
+);
+""");
+ this.db.exec("INSERT INTO MessageTable VALUES (1);");
+
+ this.db.exec("""
+CREATE TABLE MessageAttachmentTable (
+ id INTEGER PRIMARY KEY,
+ message_id INTEGER REFERENCES MessageTable ON DELETE CASCADE,
+ filename TEXT,
+ mime_type TEXT,
+ filesize INTEGER,
+ disposition INTEGER,
+ content_id TEXT DEFAULT NULL,
+ description TEXT DEFAULT NULL
+);
+""");
+
+ }
+
+ public override void tear_down() throws Error {
+ this.db.close();
+ this.db = null;
+
+ Geary.Files.recursive_delete_async.begin(
+ this.tmp_dir,
+ null,
+ (obj, res) => { async_complete(res); }
+ );
+ Geary.Files.recursive_delete_async.end(async_result());
+ this.tmp_dir = null;
+ }
+
+ public void save_minimal_attachment() throws Error {
+ GMime.Part part = new_part(null, ENCODED_BODY.data);
+
+ Gee.List attachments = Attachment.save_attachments(
+ this.db.get_master_connection(),
+ this.tmp_dir,
+ 1,
+ new Gee.ArrayList.wrap({
+ new Geary.RFC822.Part(part)
+ }),
+ null
+ );
+
+ assert_int(1, attachments.size, "No attachment provided");
+
+ Geary.Attachment attachment = attachments[0];
+ assert_non_null(attachment.file, "Attachment file");
+ assert_int(
+ DECODED_BODY.data.length,
+ (int) attachment.filesize,
+ "Attachment file size"
+ );
+
+ uint8[] buf = new uint8[4096];
+ size_t len = 0;
+ attachments[0].file.read().read_all(buf, out len);
+ assert_string(DECODED_BODY, (string) buf[0:len]);
+
+ Geary.Db.Result result = this.db.query(
+ "SELECT * FROM MessageAttachmentTable;"
+ );
+ assert_false(result.finished, "Row not inserted");
+ assert_int(1, result.int_for("message_id"), "Row message id");
+ assert_int(
+ DECODED_BODY.data.length,
+ result.int_for("filesize"),
+ "Row file size"
+ );
+ assert_false(result.next(), "Multiple rows inserted");
+ }
+
+ public void save_complete_attachment() throws Error {
+ const string TYPE = "text/plain";
+ const string ID = "test-id";
+ const string DESCRIPTION = "test description";
+ const Geary.Mime.DispositionType DISPOSITION_TYPE =
+ Geary.Mime.DispositionType.INLINE;
+ const string FILENAME = "test.txt";
+
+ GMime.Part part = new_part(TYPE, ENCODED_BODY.data);
+ part.set_content_id(ID);
+ part.set_content_description(DESCRIPTION);
+ part.set_content_disposition(
+ new GMime.ContentDisposition.from_string(
+ "inline; filename=%s;".printf(FILENAME)
+ ));
+
+ Gee.List attachments = Attachment.save_attachments(
+ this.db.get_master_connection(),
+ this.tmp_dir,
+ 1,
+ new Gee.ArrayList.wrap({
+ new Geary.RFC822.Part(part)
+ }),
+ null
+ );
+
+ assert_int(1, attachments.size, "No attachment provided");
+
+ Geary.Attachment attachment = attachments[0];
+ assert_string(TYPE, attachment.content_type.to_string());
+ assert_string(ID, attachment.content_id);
+ assert_string(DESCRIPTION, attachment.content_description);
+ assert_string(FILENAME, attachment.content_filename);
+ assert_int(
+ DISPOSITION_TYPE,
+ attachment.content_disposition.disposition_type,
+ "Attachment disposition type"
+ );
+
+ uint8[] buf = new uint8[4096];
+ size_t len = 0;
+ attachment.file.read().read_all(buf, out len);
+ assert_string(DECODED_BODY, (string) buf[0:len]);
+
+ Geary.Db.Result result = this.db.query(
+ "SELECT * FROM MessageAttachmentTable;"
+ );
+ assert_false(result.finished, "Row not inserted");
+ assert_int(1, result.int_for("message_id"), "Row message id");
+ assert_string(TYPE, result.string_for("mime_type"));
+ assert_string(ID, result.string_for("content_id"));
+ assert_string(DESCRIPTION, result.string_for("description"));
+ assert_int(
+ DISPOSITION_TYPE,
+ result.int_for("disposition"),
+ "Row disposition type"
+ );
+ assert_string(FILENAME, result.string_for("filename"));
+ assert_false(result.next(), "Multiple rows inserted");
+ }
+
+ public void save_qp_attachment() throws Error {
+ // Example courtesy https://en.wikipedia.org/wiki/Quoted-printable
+ const string QP_ENCODED =
+"""J'interdis aux marchands de vanter trop leur marchandises. Car ils se font =
+vite p=C3=A9dagogues et t'enseignent comme but ce qui n'est par essence qu'=
+un moyen, et te trompant ainsi sur la route =C3=A0 suivre les voil=C3=A0 bi=
+ent=C3=B4t qui te d=C3=A9gradent, car si leur musique est vulgaire ils te f=
+abriquent pour te la vendre une =C3=A2me vulgaire.""";
+ const string QP_DECODED =
+"""J'interdis aux marchands de vanter trop leur marchandises. Car ils se font vite pédagogues et t'enseignent comme but ce qui n'est par essence qu'un moyen, et te trompant ainsi sur la route à suivre les voilà bientôt qui te dégradent, car si leur musique est vulgaire ils te fabriquent pour te la vendre une âme vulgaire.""";
+ GMime.Part part = new_part(
+ "text/plain; charset=utf-8",
+ QP_ENCODED.data,
+ GMime.ContentEncoding.QUOTEDPRINTABLE
+ );
+
+ Gee.List attachments = Attachment.save_attachments(
+ this.db.get_master_connection(),
+ this.tmp_dir,
+ 1,
+ new Gee.ArrayList.wrap({
+ new Geary.RFC822.Part(part)
+ }),
+ null
+ );
+
+ assert_int(1, attachments.size, "No attachment provided");
+
+ uint8[] buf = new uint8[4096];
+ size_t len = 0;
+ attachments[0].file.read().read_all(buf, out len);
+ assert_string(QP_DECODED, (string) buf[0:len]);
+ }
+
+ public void list_attachments() throws Error {
+ this.db.exec("""
+INSERT INTO MessageAttachmentTable ( message_id, mime_type )
+VALUES (1, 'text/plain');
+""");
+ this.db.exec("""
+INSERT INTO MessageAttachmentTable ( message_id, mime_type )
+VALUES (2, 'text/plain');
+""");
+
+ Gee.List loaded = Attachment.list_attachments(
+ this.db.get_master_connection(),
+ GLib.File.new_for_path("/tmp"),
+ 1,
+ null
+ );
+
+ assert_int(1, loaded.size, "Expected one row loaded");
+ assert_int(1, (int) loaded[0].message_id, "Unexpected message id");
+ }
+
+ public void delete_attachments() throws Error {
+ GMime.Part part = new_part(null, ENCODED_BODY.data);
+
+ Gee.List attachments = Attachment.save_attachments(
+ this.db.get_master_connection(),
+ this.tmp_dir,
+ 1,
+ new Gee.ArrayList.wrap({
+ new Geary.RFC822.Part(part)
+ }),
+ null
+ );
+
+ assert_true(attachments[0].file.query_exists(null),
+ "Attachment not saved to disk");
+
+ this.db.exec("""
+INSERT INTO MessageAttachmentTable ( message_id, mime_type )
+VALUES (2, 'text/plain');
+""");
+
+ Attachment.delete_attachments(
+ this.db.get_master_connection(), this.tmp_dir, 1, null
+ );
+
+ Geary.Db.Result result = this.db.query(
+ "SELECT * FROM MessageAttachmentTable;"
+ );
+ assert_false(result.finished);
+ assert_int(2, result.int_for("message_id"), "Unexpected message_id");
+ assert_false(result.next(), "Attachment not deleted from db");
+
+ assert_false(attachments[0].file.query_exists(null),
+ "Attachment not deleted from disk");
+ }
+
+}
+
+private GMime.Part new_part(string? mime_type,
+ uint8[] body,
+ GMime.ContentEncoding encoding = GMime.ContentEncoding.DEFAULT) {
+ GMime.Part part = new GMime.Part();
+ if (mime_type != null) {
+ part.set_content_type(new GMime.ContentType.from_string(mime_type));
+ }
+ GMime.DataWrapper body_wrapper = new GMime.DataWrapper.with_stream(
+ new GMime.StreamMem.with_buffer(body),
+ encoding
+ );
+ part.set_content_object(body_wrapper);
+ return part;
+}
diff --git a/test/engine/imap-db/imap-db-database-test.vala b/test/engine/imap-db/imap-db-database-test.vala
new file mode 100644
index 00000000..1a7cdc19
--- /dev/null
+++ b/test/engine/imap-db/imap-db-database-test.vala
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2018 Michael Gratton
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+
+class Geary.ImapDB.DatabaseTest : TestCase {
+
+
+ public DatabaseTest() {
+ base("Geary.ImapDb.DatabaseTest");
+ add_test("open_new", open_new);
+ add_test("upgrade_0_6", upgrade_0_6);
+ }
+
+ public void open_new() throws Error {
+ GLib.File tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ Database db = new Database(
+ tmp_dir.get_child("test.db"),
+ GLib.File.new_for_path(_SOURCE_ROOT_DIR).get_child("sql"),
+ tmp_dir.get_child("attachments"),
+ new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_UPGRADE),
+ new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_VACUUM),
+ "test@example.com"
+ );
+
+ db.open.begin(
+ Geary.Db.DatabaseFlags.CREATE_FILE, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ // Need to get a connection since the database doesn't
+ // actually get created until then
+ db.get_master_connection();
+
+ // Need to close it again to stop the GC process running
+ db.close();
+
+ db.file.delete();
+ tmp_dir.delete();
+ }
+
+ public void upgrade_0_6() throws Error {
+ GLib.File tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ // Since the upgrade process also messes around with
+ // attachments on disk which we want to be able to test, we
+ // need to have a complete-ish database and attachments
+ // directory hierarchy. For convenience, these are included as
+ // a single compressed archive, but that means we need to
+ // un-compress and unpack the archive as part of the test
+ // fixture.
+ const string DB_0_6_RESOURCE = "geary-0.6-db.tar.xz";
+ const string DB_0_6_DIR = "geary-0.6-db";
+ const string ATTACHMENT_12 = "capitalism.jpeg";
+
+ GLib.File db_archive = GLib.File
+ .new_for_uri(RESOURCE_URI)
+ .resolve_relative_path(DB_0_6_RESOURCE);
+ GLib.File db_dir = tmp_dir.get_child(DB_0_6_DIR);
+ GLib.File db_file = db_dir.get_child("geary.db");
+ GLib.File attachments_dir = db_dir.get_child("attachments");
+
+ unpack_archive(db_archive, tmp_dir);
+
+ // This number is the id of the last known message in the
+ // database
+ GLib.File message_dir = attachments_dir.get_child("43");
+
+ // Ensure one of the expected attachments exists up
+ // front. Since there are 12 known attachments, 12 should be
+ // the last one in the table and exist on the file system,
+ // while 13 should not.
+ assert_true(
+ message_dir.get_child("12").get_child(ATTACHMENT_12).query_exists(),
+ "Expected attachment file"
+ );
+ assert_false(
+ message_dir.get_child("13").query_exists(),
+ "Unexpected attachment file"
+ );
+
+ Database db = new Database(
+ db_file,
+ GLib.File.new_for_path(_SOURCE_ROOT_DIR).get_child("sql"),
+ attachments_dir,
+ new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_UPGRADE),
+ new Geary.SimpleProgressMonitor(Geary.ProgressType.DB_VACUUM),
+ "test@example.com"
+ );
+
+ db.open.begin(
+ Geary.Db.DatabaseFlags.CREATE_FILE, null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ db.open.end(async_result());
+
+ assert_int(25, db.get_schema_version(), "Post-upgrade version");
+
+ // Since schema v22 deletes the re-creates all attachments,
+ // attachment 12 should no longer exist on the file system and
+ // there should be an attachment with id 24.
+ assert_false(
+ message_dir.get_child("12").get_child(ATTACHMENT_12).query_exists(),
+ "Old attachment file not deleted"
+ );
+ assert_true(
+ message_dir.get_child("24").get_child(ATTACHMENT_12).query_exists(),
+ "New attachment dir/file not created"
+ );
+
+
+ // Need to close it again to stop the GC process running
+ db.close();
+
+ Geary.Files.recursive_delete_async.begin(
+ tmp_dir, null,
+ (obj, res) => { async_complete(res); }
+ );
+ Geary.Files.recursive_delete_async.end(async_result());
+ }
+
+
+ private void unpack_archive(GLib.File archive, GLib.File dest)
+ throws Error {
+ // GLib doesn't seem to have native support for unpacking
+ // multi-file archives however, so use this fun kludge
+ // instead.
+
+ GLib.InputStream bytes = archive.read();
+
+ GLib.Subprocess untar = new GLib.Subprocess(
+ GLib.SubprocessFlags.STDIN_PIPE,
+ "tar", "-xJf", "-", "-C", dest.get_path()
+ );
+ GLib.OutputStream stdin = untar.get_stdin_pipe();
+
+ uint8[] buf = new uint8[4096];
+ ssize_t len = 0;
+ do {
+ len = bytes.read(buf);
+ stdin.write(buf[0:len]);
+ } while (len > 0);
+
+ stdin.close();
+
+ untar.wait();
+ }
+
+}
diff --git a/test/engine/mime-content-type-test.vala b/test/engine/mime-content-type-test.vala
index b1bdd4de..4b766000 100644
--- a/test/engine/mime-content-type-test.vala
+++ b/test/engine/mime-content-type-test.vala
@@ -9,14 +9,21 @@ class Geary.Mime.ContentTypeTest : TestCase {
public ContentTypeTest() {
base("Geary.Mime.ContentTypeTest");
- add_test("is_default", is_default);
+ add_test("static_defaults", static_defaults);
add_test("get_file_name_extension", get_file_name_extension);
add_test("guess_type_from_name", guess_type_from_name);
add_test("guess_type_from_buf", guess_type_from_buf);
}
- public void is_default() throws Error {
- assert(new ContentType("application", "octet-stream", null).is_default());
+ public void static_defaults() throws Error {
+ assert_string(
+ "text/plain; charset=us-ascii",
+ ContentType.DISPLAY_DEFAULT.to_string()
+ );
+ assert_string(
+ "application/octet-stream",
+ ContentType.ATTACHMENT_DEFAULT.to_string()
+ );
}
public void get_file_name_extension() throws Error {
@@ -25,17 +32,15 @@ class Geary.Mime.ContentTypeTest : TestCase {
}
public void guess_type_from_name() throws Error {
- try {
- assert(ContentType.guess_type("test.png", null).is_type("image", "png"));
- } catch (Error err) {
- assert_not_reached();
- }
-
- try {
- assert(ContentType.guess_type("foo.test", null).get_mime_type() == ContentType.DEFAULT_CONTENT_TYPE);
- } catch (Error err) {
- assert_not_reached();
- }
+ assert_true(
+ ContentType.guess_type("test.png", null).is_type("image", "png"),
+ "Expected image/png"
+ );
+ assert_true(
+ ContentType.guess_type("foo.test", null)
+ .is_same(ContentType.ATTACHMENT_DEFAULT),
+ "Expected ContentType.ATTACHMENT_DEFAULT"
+ );
}
public void guess_type_from_buf() throws Error {
@@ -44,17 +49,15 @@ class Geary.Mime.ContentTypeTest : TestCase {
);
Memory.ByteBuffer empty = new Memory.ByteBuffer({0x0}, 1);
- try {
- assert(ContentType.guess_type(null, png).is_type("image", "png"));
- } catch (Error err) {
- assert_not_reached();
- }
-
- try {
- assert(ContentType.guess_type(null, empty).get_mime_type() == ContentType.DEFAULT_CONTENT_TYPE);
- } catch (Error err) {
- assert_not_reached();
- }
+ assert_true(
+ ContentType.guess_type(null, png).is_type("image", "png"),
+ "Expected image/png"
+ );
+ assert_true(
+ ContentType.guess_type(null, empty)
+ .is_same(ContentType.ATTACHMENT_DEFAULT),
+ "Expected ContentType.ATTACHMENT_DEFAULT"
+ );
}
}
diff --git a/test/engine/rfc822-message-data-test.vala b/test/engine/rfc822-message-data-test.vala
index 156fe48f..5251fd9d 100644
--- a/test/engine/rfc822-message-data-test.vala
+++ b/test/engine/rfc822-message-data-test.vala
@@ -14,30 +14,30 @@ class Geary.RFC822.MessageDataTest : TestCase {
public void preview_text_with_header() throws Error {
PreviewText plain_preview1 = new PreviewText.with_header(
- new Geary.Memory.StringBuffer(PLAIN_BODY1_ENCODED),
- new Geary.Memory.StringBuffer(PLAIN_BODY1_HEADERS)
+ new Geary.Memory.StringBuffer(PLAIN_BODY1_HEADERS),
+ new Geary.Memory.StringBuffer(PLAIN_BODY1_ENCODED)
);
- assert(plain_preview1.buffer.to_string() == PLAIN_BODY1_EXPECTED);
+ assert_string(PLAIN_BODY1_EXPECTED, plain_preview1.buffer.to_string());
PreviewText base64_preview = new PreviewText.with_header(
- new Geary.Memory.StringBuffer(BASE64_BODY_ENCODED),
- new Geary.Memory.StringBuffer(BASE64_BODY_HEADERS)
+ new Geary.Memory.StringBuffer(BASE64_BODY_HEADERS),
+ new Geary.Memory.StringBuffer(BASE64_BODY_ENCODED)
);
- assert(base64_preview.buffer.to_string() == BASE64_BODY_EXPECTED);
+ assert_string(BASE64_BODY_EXPECTED, base64_preview.buffer.to_string());
string html_part_headers = "Content-Type: text/html; charset=utf-8\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n";
PreviewText html_preview1 = new PreviewText.with_header(
- new Geary.Memory.StringBuffer(HTML_BODY1_ENCODED),
- new Geary.Memory.StringBuffer(html_part_headers)
+ new Geary.Memory.StringBuffer(html_part_headers),
+ new Geary.Memory.StringBuffer(HTML_BODY1_ENCODED)
);
- assert(html_preview1.buffer.to_string() == HTML_BODY1_EXPECTED);
+ assert_string(HTML_BODY1_EXPECTED, html_preview1.buffer.to_string());
PreviewText html_preview2 = new PreviewText.with_header(
- new Geary.Memory.StringBuffer(HTML_BODY2_ENCODED),
- new Geary.Memory.StringBuffer(html_part_headers)
+ new Geary.Memory.StringBuffer(html_part_headers),
+ new Geary.Memory.StringBuffer(HTML_BODY2_ENCODED)
);
- assert(html_preview2.buffer.to_string() == HTML_BODY2_EXPECTED);
+ assert_string(HTML_BODY2_EXPECTED, html_preview2.buffer.to_string());
}
public static string PLAIN_BODY1_HEADERS = "Content-Type: text/plain; charset=\"us-ascii\"\r\nContent-Transfer-Encoding: 7bit\r\n";
diff --git a/test/engine/rfc822-message-test.vala b/test/engine/rfc822-message-test.vala
index aaca0c84..f32f871c 100644
--- a/test/engine/rfc822-message-test.vala
+++ b/test/engine/rfc822-message-test.vala
@@ -7,29 +7,56 @@
class Geary.RFC822.MessageTest : TestCase {
+
+ private const string BASIC_TEXT_PLAIN = "basic-text-plain.eml";
+ private const string BASIC_TEXT_HTML = "basic-text-html.eml";
+ private const string BASIC_MULTIPART_ALTERNATIVE =
+ "basic-multipart-alternative.eml";
+
+ private const string HTML_CONVERSION_TEMPLATE =
+ "%s
";
+
+ private const string BASIC_PLAIN_BODY = """This is the first line.
+
+This is the second line.
+
+""";
+
+ private const string BASIC_HTML_BODY = """This is the first line.
+
+
This is the second line.
+
+""";
+
public MessageTest() {
base("Geary.RFC822.MessageTest");
add_test("basic_message_from_buffer", basic_message_from_buffer);
add_test("encoded_recipient", encoded_recipient);
add_test("duplicate_mailbox", duplicate_mailbox);
add_test("duplicate_message_id", duplicate_message_id);
+ add_test("text_plain_as_plain", text_plain_as_plain);
+ add_test("text_plain_as_html", text_plain_as_html);
+ add_test("text_html_as_html", text_html_as_html);
+ add_test("text_html_as_plain", text_html_as_plain);
+ add_test("multipart_alternative_as_plain",
+ multipart_alternative_as_plain);
+ add_test("multipart_alternative_as_converted_html",
+ multipart_alternative_as_converted_html);
+ add_test("multipart_alternative_as_html",
+ multipart_alternative_as_html);
add_test("get_preview", get_preview);
}
public void basic_message_from_buffer() throws Error {
- Message? basic = null;
- try {
- basic = string_to_message(BASIC_MESSAGE);
- } catch (Error err) {
- assert_no_error(err);
- }
- assert_data(basic.subject, "Re: Saying Hello");
- assert_addresses(basic.from, "Mary Smith ");
- assert_address(basic.sender, "Mary Smith Sender ");
- assert_addresses(basic.reply_to, "\"Mary Smith: Personal Account\" ");
- assert_addresses(basic.to, "John Doe ");
- assert_addresses(basic.cc, "John Doe CC ");
- assert_addresses(basic.bcc, "John Doe BCC ");
+ Message basic = resource_to_message(BASIC_TEXT_PLAIN);
+
+ assert_data(basic.subject, "Re: Basic text/plain message");
+ assert_addresses(basic.from, "Alice ");
+ assert_address(basic.sender, "Bob ");
+ assert_addresses(basic.reply_to, "\"Alice: Personal Account\" ");
+ assert_addresses(basic.to, "Charlie ");
+ assert_addresses(basic.cc, "Dave ");
+ assert_addresses(basic.bcc, "Eve ");
//assert_data(basic.message_id, "<3456@example.net>");
assert_message_id_list(basic.in_reply_to, "<1234@local.machine.example>");
assert_message_id_list(basic.references, "<1234@local.machine.example>");
@@ -38,24 +65,14 @@ class Geary.RFC822.MessageTest : TestCase {
}
public void encoded_recipient() throws Error {
- Message? enc = null;
- try {
- enc = string_to_message(ENCODED_TO);
- } catch (Error err) {
- assert_no_error(err);
- }
+ Message enc = string_to_message(ENCODED_TO);
// Courtesy Mailsploit https://www.mailsploit.com
assert(enc.to[0].name == "potus@whitehouse.gov ");
}
public void duplicate_mailbox() throws Error {
- Message? dup = null;
- try {
- dup = string_to_message(DUPLICATE_TO);
- } catch (Error err) {
- assert_no_error(err);
- }
+ Message dup = string_to_message(DUPLICATE_TO);
assert(dup.to.size == 2);
assert_addresses(
@@ -64,12 +81,7 @@ class Geary.RFC822.MessageTest : TestCase {
}
public void duplicate_message_id() throws Error {
- Message? dup = null;
- try {
- dup = string_to_message(DUPLICATE_REFERENCES);
- } catch (Error err) {
- assert_no_error(err);
- }
+ Message dup = string_to_message(DUPLICATE_REFERENCES);
assert(dup.references.list.size == 2);
assert_message_id_list(
@@ -77,13 +89,84 @@ class Geary.RFC822.MessageTest : TestCase {
);
}
+ public void text_plain_as_plain() throws Error {
+ Message test = resource_to_message(BASIC_TEXT_PLAIN);
+
+ assert_true(test.has_plain_body(), "Expected plain body");
+ assert_false(test.has_html_body(), "Expected non-html body");
+ assert_string(BASIC_PLAIN_BODY, test.get_plain_body(false, null));
+ }
+
+ public void text_plain_as_html() throws Error {
+ Message test = resource_to_message(BASIC_TEXT_PLAIN);
+
+ assert_true(test.has_plain_body(), "Expected plain body");
+ assert_false(test.has_html_body(), "Expected non-html body");
+ assert_string(
+ HTML_CONVERSION_TEMPLATE.printf(BASIC_PLAIN_BODY),
+ test.get_plain_body(true, null)
+ );
+ }
+
+ public void text_html_as_html() throws Error {
+ Message test = resource_to_message(BASIC_TEXT_HTML);
+
+ assert_true(test.has_html_body(), "Expected html body");
+ assert_false(test.has_plain_body(), "Expected non-plain body");
+ assert_string(BASIC_HTML_BODY, test.get_html_body(null));
+ }
+
+ public void text_html_as_plain() throws Error {
+ Message test = resource_to_message(BASIC_TEXT_HTML);
+
+ assert_true(test.has_html_body(), "Expected html body");
+ assert_false(test.has_plain_body(), "Expected non-plain body");
+ assert_string(BASIC_HTML_BODY, test.get_html_body(null));
+ }
+
+ public void multipart_alternative_as_plain() throws Error {
+ Message test = resource_to_message(BASIC_MULTIPART_ALTERNATIVE);
+
+ assert_true(test.has_plain_body(), "Expected plain body");
+ assert_true(test.has_html_body(), "Expected html body");
+ assert_string(BASIC_PLAIN_BODY, test.get_plain_body(false, null));
+ }
+
+ public void multipart_alternative_as_converted_html() throws Error {
+ Message test = resource_to_message(BASIC_MULTIPART_ALTERNATIVE);
+
+ assert_true(test.has_plain_body(), "Expected plain body");
+ assert_true(test.has_html_body(), "Expected html body");
+ assert_string(
+ HTML_CONVERSION_TEMPLATE.printf(BASIC_PLAIN_BODY),
+ test.get_plain_body(true, null)
+ );
+ }
+
+ public void multipart_alternative_as_html() throws Error {
+ Message test = resource_to_message(BASIC_MULTIPART_ALTERNATIVE);
+
+ assert_true(test.has_plain_body(), "Expected plain body");
+ assert_true(test.has_html_body(), "Expected html body");
+ assert_string(BASIC_HTML_BODY, test.get_html_body(null));
+ }
+
public void get_preview() throws Error {
- try {
- Message multipart_signed = string_to_message(MULTIPART_SIGNED_MESSAGE_TEXT);
- assert(multipart_signed.get_preview() == MULTIPART_SIGNED_MESSAGE_PREVIEW);
- } catch (Error err) {
- assert_no_error(err);
- }
+ Message multipart_signed = string_to_message(MULTIPART_SIGNED_MESSAGE_TEXT);
+
+ assert(multipart_signed.get_preview() == MULTIPART_SIGNED_MESSAGE_PREVIEW);
+ }
+
+ private Message resource_to_message(string path) throws Error {
+ GLib.File resource =
+ GLib.File.new_for_uri(RESOURCE_URI).resolve_relative_path(path);
+
+ uint8[] contents;
+ resource.load_contents(null, out contents, null);
+
+ return new Message.from_buffer(
+ new Geary.Memory.ByteBuffer(contents, contents.length)
+ );
}
private Message string_to_message(string message_text) throws Error {
@@ -92,28 +175,34 @@ class Geary.RFC822.MessageTest : TestCase {
);
}
- private void assert_data(Geary.MessageData.AbstractMessageData? data, string expected) {
- assert(data != null);
- assert(data.to_string() == expected);
+ private void assert_data(Geary.MessageData.AbstractMessageData? actual,
+ string expected)
+ throws Error {
+ assert_non_null(actual, expected);
+ assert_string(expected, actual.to_string());
}
- private void assert_address(Geary.RFC822.MailboxAddress? address, string expected) {
- assert(address != null);
- assert(address.to_rfc822_string() == expected);
+ private void assert_address(Geary.RFC822.MailboxAddress? address,
+ string expected)
+ throws Error {
+ assert_non_null(address, expected);
+ assert_string(expected, address.to_rfc822_string());
}
- private void assert_addresses(Geary.RFC822.MailboxAddresses? addresses, string expected) {
- assert(addresses != null);
- assert(addresses.to_rfc822_string() == expected);
+ private void assert_addresses(Geary.RFC822.MailboxAddresses? addresses,
+ string expected)
+ throws Error {
+ assert_non_null(addresses, expected);
+ assert_string(expected, addresses.to_rfc822_string());
}
- private void assert_message_id_list(Geary.RFC822.MessageIDList? ids, string expected) {
- assert(ids != null);
+ private void assert_message_id_list(Geary.RFC822.MessageIDList? ids,
+ string expected)
+ throws Error {
+ assert_non_null(ids, expected);
assert(ids.to_rfc822_string() == expected);
}
- private static string BASIC_MESSAGE = "From: Mary Smith \r\nSender: Mary Smith Sender \r\nTo: John Doe \r\nCC: John Doe CC \r\nBCC: John Doe BCC \r\nReply-To: \"Mary Smith: Personal Account\" \r\nSubject: Re: Saying Hello\r\nDate: Fri, 21 Nov 1997 10:01:10 -0600\r\nMessage-ID: <3456@example.net>\r\nIn-Reply-To: <1234@local.machine.example>\r\nReferences: <1234@local.machine.example>\r\nX-Mailer: Geary Test Suite 1.0\r\n\r\nThis is a reply to your hello.\r\n\r\n";
-
// Courtesy Mailsploit https://www.mailsploit.com
private static string ENCODED_TO = "From: Mary Smith \r\nTo: =?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3YiIDx0ZXN0Pg==?= \r\nSubject: Re: Saying Hello\r\nDate: Fri, 21 Nov 1997 10:01:10 -0600\r\n\r\nThis is a reply to your hello.\r\n\r\n";
diff --git a/test/engine/rfc822-part-test.vala b/test/engine/rfc822-part-test.vala
new file mode 100644
index 00000000..513232d0
--- /dev/null
+++ b/test/engine/rfc822-part-test.vala
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018 Michael Gratton
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+class Geary.RFC822.PartTest : TestCase {
+
+ private const string BODY = "This is an attachment.\n";
+
+
+ public PartTest() {
+ base("Geary.RFC822.PartTest");
+ add_test("new_from_empty_mime_part", new_from_empty_mime_part);
+ add_test("new_from_complete_mime_part", new_from_complete_mime_part);
+ }
+
+ public void new_from_empty_mime_part() throws Error {
+ GMime.Part part = new_part(null, BODY.data);
+ part.set_header("Content-Type", "");
+
+ Part test = new Part(part);
+
+ assert_null(test.content_type, "content_type");
+ assert_null_string(test.content_id, "content_id");
+ assert_null_string(test.content_description, "content_description");
+ assert_null(test.content_disposition, "content_disposition");
+ }
+
+ public void new_from_complete_mime_part() throws Error {
+ const string TYPE = "text/plain";
+ const string ID = "test-id";
+ const string DESC = "test description";
+
+ GMime.Part part = new_part(TYPE, BODY.data);
+ part.set_content_id(ID);
+ part.set_content_description(DESC);
+ part.set_content_disposition(
+ new GMime.ContentDisposition.from_string("inline")
+ );
+
+ Part test = new Part(part);
+
+ assert_string(TYPE, test.content_type.to_string());
+ assert_string(ID, test.content_id);
+ assert_string(DESC, test.content_description);
+ assert_non_null(test.content_disposition, "content_disposition");
+ assert_int(
+ Geary.Mime.DispositionType.INLINE,
+ test.content_disposition.disposition_type
+ );
+ }
+
+ private GMime.Part new_part(string? mime_type,
+ uint8[] body,
+ GMime.ContentEncoding encoding = GMime.ContentEncoding.DEFAULT) {
+ GMime.Part part = new GMime.Part();
+ if (mime_type != null) {
+ part.set_content_type(new GMime.ContentType.from_string(mime_type));
+ }
+ GMime.DataWrapper body_wrapper = new GMime.DataWrapper.with_stream(
+ new GMime.StreamMem.with_buffer(body),
+ encoding
+ );
+ part.set_content_object(body_wrapper);
+ part.encode(GMime.EncodingConstraint.7BIT);
+ return part;
+ }
+
+}
diff --git a/test/meson.build b/test/meson.build
index e74841c4..98f78372 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,3 +1,5 @@
+subdir('data')
+
geary_test_lib_sources = [
'mock-object.vala',
'test-case.vala',
@@ -22,15 +24,20 @@ geary_test_engine_sources = [
'engine/app/app-conversation-test.vala',
'engine/app/app-conversation-monitor-test.vala',
'engine/app/app-conversation-set-test.vala',
+ 'engine/db/db-database-test.vala',
+ 'engine/db/db-versioned-database-test.vala',
'engine/imap/command/imap-create-command-test.vala',
'engine/imap/response/imap-namespace-response-test.vala',
'engine/imap/transport/imap-deserializer-test.vala',
+ 'engine/imap-db/imap-db-attachment-test.vala',
+ 'engine/imap-db/imap-db-database-test.vala',
'engine/imap-engine/account-processor-test.vala',
'engine/mime-content-type-test.vala',
'engine/rfc822-mailbox-address-test.vala',
'engine/rfc822-mailbox-addresses-test.vala',
'engine/rfc822-message-test.vala',
'engine/rfc822-message-data-test.vala',
+ 'engine/rfc822-part-test.vala',
'engine/rfc822-utils-test.vala',
'engine/util-ascii-test.vala',
'engine/util-html-test.vala',
@@ -38,7 +45,9 @@ geary_test_engine_sources = [
'engine/util-inet-test.vala',
'engine/util-js-test.vala',
'engine/util-string-test.vala',
- 'engine/util-timeout-manager-test.vala'
+ 'engine/util-timeout-manager-test.vala',
+
+ geary_test_engine_resources
]
geary_test_client_sources = [
diff --git a/test/test-case.vala b/test/test-case.vala
index 759962d7..166bf324 100644
--- a/test/test-case.vala
+++ b/test/test-case.vala
@@ -62,6 +62,18 @@ public void assert_string(string expected, string? actual, string? context = nul
}
}
+public void assert_null_string(string? actual, string? context = null)
+ throws Error {
+ if (actual != null) {
+ string a = actual;
+ if (a.length > 70) {
+ a = a[0:70] + "…";
+ }
+ print_assert("Expected: null, was: \"%s\"".printf(a), context);
+ assert_not_reached();
+ }
+}
+
public void assert_int(int expected, int actual, string? context = null)
throws Error {
if (expected != actual) {
@@ -140,9 +152,14 @@ private inline void print_assert(string message, string? context) {
GLib.stderr.putc('\n');
}
+
public abstract class TestCase : Object {
+ /** GLib.File URI for resources in test/data. */
+ public const string RESOURCE_URI = "resource:///org/gnome/GearyTest";
+
+
private class SignalWaiter : Object {
public bool was_fired = false;
diff --git a/test/test-engine.vala b/test/test-engine.vala
index 06349aef..82e1664e 100644
--- a/test/test-engine.vala
+++ b/test/test-engine.vala
@@ -31,10 +31,15 @@ int main(string[] args) {
// Depends on ConversationTest and ConversationSetTest passing
engine.add_suite(new Geary.App.ConversationMonitorTest().get_suite());
engine.add_suite(new Geary.Ascii.Test().get_suite());
+ engine.add_suite(new Geary.Db.DatabaseTest().get_suite());
+ engine.add_suite(new Geary.Db.VersionedDatabaseTest().get_suite());
engine.add_suite(new Geary.HTML.UtilTest().get_suite());
engine.add_suite(new Geary.Imap.DeserializerTest().get_suite());
engine.add_suite(new Geary.Imap.CreateCommandTest().get_suite());
engine.add_suite(new Geary.Imap.NamespaceResponseTest().get_suite());
+ engine.add_suite(new Geary.ImapDB.AttachmentTest().get_suite());
+ engine.add_suite(new Geary.ImapDB.AttachmentIoTest().get_suite());
+ engine.add_suite(new Geary.ImapDB.DatabaseTest().get_suite());
engine.add_suite(new Geary.ImapEngine.AccountProcessorTest().get_suite());
engine.add_suite(new Geary.Inet.Test().get_suite());
engine.add_suite(new Geary.JS.Test().get_suite());