[geary/wip/181-special-folder-dupes: 1/7] Add some unit tests for Geary.ImapDb.Account folder management



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]