[geary/wip/181-special-folder-dupes: 1/7] Add some unit tests for Geary.ImapDb.Account folder management
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/181-special-folder-dupes: 1/7] Add some unit tests for Geary.ImapDb.Account folder management
- Date: Mon, 14 Jan 2019 05:28:03 +0000 (UTC)
commit faf7a2bdfdb0685eaeac3b6a8bf8ce84c87f7aa2
Author: Michael Gratton <mike vee net>
Date: Mon Jan 14 11:01:03 2019 +1100
Add some unit tests for Geary.ImapDb.Account folder management
src/engine/imap-db/imap-db-account.vala | 36 +--
.../imap-engine/imap-engine-generic-account.vala | 2 +-
test/engine/imap-db/imap-db-account-test.vala | 305 +++++++++++++++++++++
test/meson.build | 1 +
test/test-case.vala | 23 ++
test/test-engine.vala | 1 +
6 files changed, 344 insertions(+), 24 deletions(-)
---
diff --git a/src/engine/imap-db/imap-db-account.vala b/src/engine/imap-db/imap-db-account.vala
index 6b1db5e6..0353fd2d 100644
--- a/src/engine/imap-db/imap-db-account.vala
+++ b/src/engine/imap-db/imap-db-account.vala
@@ -326,18 +326,7 @@ private class Geary.ImapDB.Account : BaseObject {
throw err;
}
-
- Geary.Account account;
- try {
- account = Geary.Engine.instance.get_account_instance(account_information);
- } catch (Error e) {
- // If they're opening an account, the engine should already be
- // open, and there should be no reason for this to fail. Thus, if
- // we get here, it's a programmer error.
-
- error("Error finding account from its information: %s", e.message);
- }
-
+
background_cancellable = new Cancellable();
// Kick off a background update of the search table, but since the database is getting
@@ -419,21 +408,23 @@ private class Geary.ImapDB.Account : BaseObject {
return yield fetch_folder_async(path, cancellable);
}
- public async void delete_folder_async(Geary.Folder folder, Cancellable? cancellable)
- throws Error {
+ public async void delete_folder_async(Geary.FolderPath path,
+ GLib.Cancellable? cancellable)
+ throws GLib.Error {
check_open();
-
- Geary.FolderPath path = folder.path;
-
yield db.exec_transaction_async(Db.TransactionType.RW, (cx) => {
int64 folder_id;
do_fetch_folder_id(cx, path, false, out folder_id, cancellable);
- if (folder_id == Db.INVALID_ROWID)
- return Db.TransactionOutcome.ROLLBACK;
-
+ if (folder_id == Db.INVALID_ROWID) {
+ throw new EngineError.NOT_FOUND(
+ "Folder not found: %s", path.to_string()
+ );
+ }
+
if (do_has_children(cx, folder_id, cancellable)) {
- debug("Can't delete folder %s because it has children", folder.to_string());
- return Db.TransactionOutcome.ROLLBACK;
+ throw new ImapError.NOT_SUPPORTED(
+ "Folder has children: %s", path.to_string()
+ );
}
do_delete_folder(cx, folder_id, cancellable);
@@ -441,7 +432,6 @@ private class Geary.ImapDB.Account : BaseObject {
return Db.TransactionOutcome.COMMIT;
}, cancellable);
-
}
private void initialize_contacts(Cancellable? cancellable = null) throws Error {
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala
b/src/engine/imap-engine/imap-engine-generic-account.vala
index 08cc810a..7276ca9f 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -1268,7 +1268,7 @@ internal class Geary.ImapEngine.UpdateRemoteFolders : AccountOperation {
foreach (Geary.Folder folder in removed) {
try {
debug("Locally deleting removed folder %s", folder.to_string());
- yield local.delete_folder_async(folder, cancellable);
+ yield local.delete_folder_async(folder.path, cancellable);
} catch (Error e) {
debug("Unable to locally delete removed folder %s: %s", folder.to_string(), e.message);
}
diff --git a/test/engine/imap-db/imap-db-account-test.vala b/test/engine/imap-db/imap-db-account-test.vala
new file mode 100644
index 00000000..146d7127
--- /dev/null
+++ b/test/engine/imap-db/imap-db-account-test.vala
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2019 Michael Gratton <mike vee net>
+ *
+ * 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.AccountTest : TestCase {
+
+
+ private GLib.File? tmp_dir = null;
+ private Geary.AccountInformation? config = null;
+ private Account? account = null;
+
+
+ public AccountTest() {
+ base("Geary.ImapDB.AccountTest");
+ add_test("create_base_folder", create_base_folder);
+ add_test("create_child_folder", create_child_folder);
+ add_test("list_folders", list_folders);
+ add_test("delete_folder", delete_folder);
+ add_test("delete_folder_with_child", delete_folder_with_child);
+ add_test("delete_nonexistent_folder", delete_nonexistent_folder);
+ add_test("fetch_base_folder", fetch_base_folder);
+ add_test("fetch_child_folder", fetch_child_folder);
+ add_test("fetch_nonexistent_folder", fetch_nonexistent_folder);
+ }
+
+ public override void set_up() throws GLib.Error {
+ this.tmp_dir = GLib.File.new_for_path(
+ GLib.DirUtils.make_tmp("geary-db-database-test-XXXXXX")
+ );
+
+ this.config = new Geary.AccountInformation(
+ "test",
+ ServiceProvider.OTHER,
+ new MockCredentialsMediator(),
+ new Geary.RFC822.MailboxAddress(null, "test example com")
+ );
+
+ this.account = new Account(config);
+ this.account.open_async.begin(
+ this.tmp_dir,
+ GLib.File.new_for_path(_SOURCE_ROOT_DIR).get_child("sql"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ this.account.open_async.end(async_result());
+ }
+
+ public override void tear_down() throws GLib.Error {
+ this.account.close_async.begin(
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ this.account.close_async.end(async_result());
+
+ delete_file(this.tmp_dir);
+ this.tmp_dir = null;
+ }
+
+ public void create_base_folder() throws GLib.Error {
+ Imap.Folder folder = new Imap.Folder(
+ new Imap.FolderRoot("test"),
+ new Imap.FolderProperties.selectable(
+ new Imap.MailboxAttributes(
+ Gee.Collection.empty<Geary.Imap.MailboxAttribute>()
+ ),
+ new Imap.StatusData(
+ new Imap.MailboxSpecifier("test"),
+ 10, // total
+ 9, // recent
+ new Imap.UID(8),
+ new Imap.UIDValidity(7),
+ 6 //unseen
+ ),
+ new Imap.Capabilities(1)
+ )
+ );
+
+ this.account.clone_folder_async.begin(
+ folder,
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ this.account.clone_folder_async.end(async_result());
+
+ Geary.Db.Result result = this.account.db.query(
+ "SELECT * FROM FolderTable;"
+ );
+ assert_false(result.finished, "Folder not created");
+ assert_string("test", result.string_for("name"), "Folder name");
+ assert_true(result.is_null_for("parent_id"), "Folder parent");
+ assert_false(result.next(), "Multiple rows inserted");
+ }
+
+ public void create_child_folder() throws GLib.Error {
+ this.account.db.exec(
+ "INSERT INTO FolderTable (id, name) VALUES (1, 'test');"
+ );
+
+ Imap.Folder folder = new Imap.Folder(
+ new Imap.FolderRoot("test").get_child("child"),
+ new Imap.FolderProperties.selectable(
+ new Imap.MailboxAttributes(
+ Gee.Collection.empty<Geary.Imap.MailboxAttribute>()
+ ),
+ new Imap.StatusData(
+ new Imap.MailboxSpecifier("test>child"),
+ 10, // total
+ 9, // recent
+ new Imap.UID(8),
+ new Imap.UIDValidity(7),
+ 6 //unseen
+ ),
+ new Imap.Capabilities(1)
+ )
+ );
+
+ this.account.clone_folder_async.begin(
+ folder,
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ this.account.clone_folder_async.end(async_result());
+
+ Geary.Db.Result result = this.account.db.query(
+ "SELECT * FROM FolderTable WHERE id != 1;"
+ );
+ assert_false(result.finished, "Folder not created");
+ assert_string("child", result.string_for("name"), "Folder name");
+ assert_int(1, result.int_for("parent_id"), "Folder parent");
+ assert_false(result.next(), "Multiple rows inserted");
+ }
+
+ public void list_folders() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1),
+ (3, 'test3', 2);
+ """);
+
+ this.account.list_folders_async.begin(
+ null,
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ Gee.Collection<Geary.ImapDB.Folder> result =
+ this.account.list_folders_async.end(async_result());
+
+ Folder test1 = traverse(result).first();
+ assert_int(1, result.size, "Base folder not listed");
+ assert_string("test1", test1.get_path().basename, "Base folder name");
+
+ this.account.list_folders_async.begin(
+ test1.get_path(),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ result = this.account.list_folders_async.end(async_result());
+
+ Folder test2 = traverse(result).first();
+ assert_int(1, result.size, "Child folder not listed");
+ assert_string("test2", test2.get_path().basename, "Child folder name");
+
+ this.account.list_folders_async.begin(
+ test2.get_path(),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ result = this.account.list_folders_async.end(async_result());
+
+ Folder test3 = traverse(result).first();
+ assert_int(1, result.size, "Grandchild folder not listed");
+ assert_string("test3", test3.get_path().basename, "Grandchild folder name");
+ }
+
+ public void delete_folder() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1);
+ """);
+
+ this.account.delete_folder_async.begin(
+ new Imap.FolderRoot("test1").get_child("test2"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ this.account.delete_folder_async.end(async_result());
+
+ this.account.delete_folder_async.begin(
+ new Imap.FolderRoot("test1"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ this.account.delete_folder_async.end(async_result());
+ }
+
+ public void delete_folder_with_child() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1);
+ """);
+
+ this.account.delete_folder_async.begin(
+ new Imap.FolderRoot("test1"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ try {
+ this.account.delete_folder_async.end(async_result());
+ assert_not_reached();
+ } catch (GLib.Error err) {
+ assert_error(new ImapError.NOT_SUPPORTED(""), err);
+ }
+ }
+
+ public void delete_nonexistent_folder() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1);
+ """);
+
+ this.account.delete_folder_async.begin(
+ new Imap.FolderRoot("test3"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ try {
+ this.account.delete_folder_async.end(async_result());
+ assert_not_reached();
+ } catch (GLib.Error err) {
+ assert_error(new EngineError.NOT_FOUND(""), err);
+ }
+ }
+
+ public void fetch_base_folder() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1);
+ """);
+
+ this.account.fetch_folder_async.begin(
+ new Imap.FolderRoot("test1"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+
+ Folder? result = this.account.fetch_folder_async.end(async_result());
+ assert_non_null(result);
+ assert_string("test1", result.get_path().basename);
+ }
+
+ public void fetch_child_folder() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1);
+ """);
+
+ this.account.fetch_folder_async.begin(
+ new Imap.FolderRoot("test1").get_child("test2"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+
+ Folder? result = this.account.fetch_folder_async.end(async_result());
+ assert_non_null(result);
+ assert_string("test2", result.get_path().basename);
+ }
+
+ public void fetch_nonexistent_folder() throws GLib.Error {
+ this.account.db.exec("""
+ INSERT INTO FolderTable (id, name, parent_id)
+ VALUES
+ (1, 'test1', null),
+ (2, 'test2', 1);
+ """);
+
+ this.account.fetch_folder_async.begin(
+ new Imap.FolderRoot("test3"),
+ null,
+ (obj, ret) => { async_complete(ret); }
+ );
+ try {
+ this.account.fetch_folder_async.end(async_result());
+ assert_not_reached();
+ } catch (GLib.Error err) {
+ assert_error(new EngineError.NOT_FOUND(""), err);
+ }
+ }
+
+}
diff --git a/test/meson.build b/test/meson.build
index 26e588ba..c8f45530 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -36,6 +36,7 @@ geary_test_engine_sources = [
'engine/imap/parameter/imap-list-parameter-test.vala',
'engine/imap/response/imap-namespace-response-test.vala',
'engine/imap/transport/imap-deserializer-test.vala',
+ 'engine/imap-db/imap-db-account-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',
diff --git a/test/test-case.vala b/test/test-case.vala
index 166bf324..b90de697 100644
--- a/test/test-case.vala
+++ b/test/test-case.vala
@@ -152,6 +152,27 @@ private inline void print_assert(string message, string? context) {
GLib.stderr.putc('\n');
}
+public void delete_file(File parent) throws GLib.Error {
+ FileInfo info = parent.query_info(
+ "standard::*",
+ FileQueryInfoFlags.NOFOLLOW_SYMLINKS
+ );
+
+ if (info.get_file_type () == FileType.DIRECTORY) {
+ FileEnumerator enumerator = parent.enumerate_children(
+ "standard::*",
+ FileQueryInfoFlags.NOFOLLOW_SYMLINKS
+ );
+
+ info = null;
+ while (((info = enumerator.next_file()) != null)) {
+ delete_file(parent.get_child(info.get_name()));
+ }
+ }
+
+ parent.delete();
+}
+
public abstract class TestCase : Object {
@@ -304,5 +325,7 @@ public abstract class TestCase : Object {
assert_no_error(err);
}
}
+
}
+
}
diff --git a/test/test-engine.vala b/test/test-engine.vala
index d5f1e546..3c2309d8 100644
--- a/test/test-engine.vala
+++ b/test/test-engine.vala
@@ -45,6 +45,7 @@ int main(string[] args) {
engine.add_suite(new Geary.Imap.ListParameterTest().get_suite());
engine.add_suite(new Geary.Imap.MailboxSpecifierTest().get_suite());
engine.add_suite(new Geary.Imap.NamespaceResponseTest().get_suite());
+ engine.add_suite(new Geary.ImapDB.AccountTest().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());
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]