[nautilus/sam/tag-manager-test: 19/19] Add test for starred files feature



commit 7346350f59733138bfefbdb9f01c050b6cb0e69e
Author: Sam Thursfield <sam afuera me uk>
Date:   Sun May 3 01:54:04 2020 +0200

    Add test for starred files feature
    
    I'm using to test that my re-implementation of NautilusTagManager
    works as expected.
    
    It brings in quite a lot of helper code to deal with Tracker and it
    depends on the currentrly unmerged [FilesProcessed signal]
    (https://gitlab.gnome.org/GNOME/tracker-miners/-/merge_requests/192).

 test/automated/displayless/meson.build             |  11 ++
 .../displayless/org.freedesktop.Tracker3.Miner.xml |  56 ++++++++
 test/automated/displayless/test-tag-manager.c      | 126 ++++++++++++++++++
 .../automated/displayless/test-utilities-tracker.c | 143 +++++++++++++++++++++
 .../automated/displayless/test-utilities-tracker.h |  19 +++
 5 files changed, 355 insertions(+)
---
diff --git a/test/automated/displayless/meson.build b/test/automated/displayless/meson.build
index 64b23bd2a..863ef501a 100644
--- a/test/automated/displayless/meson.build
+++ b/test/automated/displayless/meson.build
@@ -35,10 +35,21 @@ tests = [
   ]]
 ]
 
+tracker_miner_proxy = gnome.gdbus_codegen(
+  'tracker-miner-proxy',
+  join_paths(tracker_sparql.get_pkgconfig_variable('datadir'), 'dbus-1', 'interfaces', 
'org.freedesktop.Tracker3.Miner.xml'),
+  interface_prefix: 'org.freedesktop.Tracker3.',
+  namespace: 'Tracker')
+
 tracker_tests = [
   ['test-nautilus-search-engine-tracker', [
     'test-nautilus-search-engine-tracker.c',
   ]],
+  ['test-tag-manager', [
+    'test-tag-manager.c',
+    'test-utilities-tracker.c',
+    tracker_miner_proxy[0], tracker_miner_proxy[1],
+  ]],
 ]
 
 foreach t: tests
diff --git a/test/automated/displayless/org.freedesktop.Tracker3.Miner.xml 
b/test/automated/displayless/org.freedesktop.Tracker3.Miner.xml
new file mode 100644
index 000000000..6fe09c846
--- /dev/null
+++ b/test/automated/displayless/org.freedesktop.Tracker3.Miner.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<node name="/">
+  <interface name="org.freedesktop.Tracker3.Miner">
+    <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="_tracker_miner_dbus"/>
+    <method name="Start">
+      <annotation name="org.freedesktop.DBus.GLib.Async"  value="true"/>
+    </method>
+    <method name="GetStatus">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="s" name="status" direction="out" />
+    </method>
+    <method name="GetProgress">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="d" name="progress" direction="out" />
+    </method>
+    <method name="GetRemainingTime">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="i" name="remaining_time" direction="out" />
+    </method>
+    <method name="GetPauseDetails">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="as" name="pause_applications" direction="out" />
+      <arg type="as" name="pause_reasons" direction="out" />
+    </method>
+    <method name="Pause">
+      <annotation name="org.freedesktop.DBus.GLib.Async"  value="true"/>
+      <arg type="s" name="application" direction="in" />
+      <arg type="s" name="reason" direction="in" />
+      <arg type="i" name="cookie" direction="out" />
+    </method>
+    <method name="PauseForProcess">
+      <annotation name="org.freedesktop.DBus.GLib.Async"  value="true"/>
+      <arg type="s" name="application" direction="in" />
+      <arg type="s" name="reason" direction="in" />
+      <arg type="i" name="cookie" direction="out" />
+    </method>
+    <method name="Resume">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="i" name="cookie" direction="in" />
+    </method>
+
+    <!-- Signals -->
+    <signal name="Started" />
+    <signal name="Stopped">
+      <arg type="b" name="interrupted" />
+    </signal>
+    <signal name="Paused" />
+    <signal name="Resumed" />
+    <signal name="Progress">
+      <arg type="s" name="status" />
+      <arg type="d" name="progress" />
+      <arg type="i" name="remaining_time" />
+    </signal>
+  </interface>
+</node>
diff --git a/test/automated/displayless/test-tag-manager.c b/test/automated/displayless/test-tag-manager.c
new file mode 100644
index 000000000..e6d5820ee
--- /dev/null
+++ b/test/automated/displayless/test-tag-manager.c
@@ -0,0 +1,126 @@
+#include "test-utilities.h"
+#include "test-utilities-tracker.h"
+
+#include <src/nautilus-file.h>
+#include <src/nautilus-tag-manager.h>
+
+typedef struct
+{
+    NautilusTagManager *tag_manager;
+    GFile *file_one;
+} TagManagerFixture;
+
+static void
+tag_manager_fixture_set_up (TagManagerFixture *fixture,
+                            gconstpointer      user_data)
+{
+    TrackerFilesProcessedWatcher *minerfs_watcher, *extractor_watcher;
+    g_autofree gchar *path = NULL;
+
+    fixture->tag_manager = nautilus_tag_manager_get ();
+    nautilus_tag_manager_set_cancellable (fixture->tag_manager, NULL);
+
+    minerfs_watcher = tracker_files_processed_watcher_new (TRACKER_MINERFS_BUS_NAME, 
TRACKER_MINERFS_OBJECT_PATH);
+    extractor_watcher = tracker_files_processed_watcher_new (TRACKER_EXTRACT_BUS_NAME, 
TRACKER_EXTRACT_OBJECT_PATH);
+
+    create_one_file ("stars");
+
+    path = g_build_filename (g_get_tmp_dir (), "stars_first_dir", "stars_first_dir_child", NULL);
+    fixture->file_one = g_file_new_for_path (path);
+
+    tracker_files_processed_watcher_await_file (minerfs_watcher, fixture->file_one);
+    tracker_files_processed_watcher_await_file (extractor_watcher, fixture->file_one);
+    tracker_files_processed_watcher_free (minerfs_watcher);
+    tracker_files_processed_watcher_free (extractor_watcher);
+}
+
+static void
+tag_manager_fixture_tear_down (TagManagerFixture *fixture,
+                               gconstpointer      user_data)
+{
+    g_clear_object (&fixture->tag_manager);
+    g_clear_object (&fixture->file_one);
+}
+
+static void
+starred_changed_cb (NautilusTagManager *tag_manager,
+                    GList              *selection,
+                    gpointer            user_data)
+{
+    GMainLoop *loop = user_data;
+
+    g_main_loop_quit (loop);
+}
+
+static void
+test_star_unstar (TagManagerFixture *fixture,
+                  gconstpointer      user_data)
+{
+    GList *selection;
+    gulong signal_id;
+    g_autoptr (GMainLoop) loop = NULL;
+
+    loop = g_main_loop_new (NULL, 0);
+
+    signal_id = g_signal_connect (fixture->tag_manager, "starred-changed", G_CALLBACK (starred_changed_cb), 
loop);
+
+    selection = g_list_prepend (NULL, nautilus_file_get (fixture->file_one));
+
+    /* Nothing is starred to begin with */
+    g_assert (nautilus_tag_manager_get_starred_files (fixture->tag_manager) == NULL);
+
+    /* Star one file and check. */
+    nautilus_tag_manager_star_files (fixture->tag_manager, NULL, selection, NULL, NULL);
+    g_main_loop_run (loop);
+
+    g_assert_cmpint (g_list_length (nautilus_tag_manager_get_starred_files (fixture->tag_manager)), ==, 1);
+
+    /* Unstar the file and check again. */
+    nautilus_tag_manager_unstar_files (fixture->tag_manager, NULL, selection, NULL, NULL);
+    g_main_loop_run (loop);
+
+    g_assert_cmpint (g_list_length (nautilus_tag_manager_get_starred_files (fixture->tag_manager)), ==, 0);
+
+    g_signal_handler_disconnect (fixture->tag_manager, signal_id);
+}
+
+static void
+setup_test_suite (void)
+{
+    g_test_add ("/test-tag-manager/star_unstar", TagManagerFixture, NULL,
+                tag_manager_fixture_set_up, test_star_unstar,
+                tag_manager_fixture_tear_down);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+    g_autoptr (TrackerSparqlConnection) connection = NULL;
+    g_autoptr (GError) error = NULL;
+    g_autoptr (NautilusFileUndoManager) undo_manager = NULL;
+
+    g_test_init (&argc, &argv, NULL);
+
+    nautilus_ensure_extension_points ();
+
+    undo_manager = nautilus_file_undo_manager_new ();
+
+    /* Make sure to run this test using the 'tracker-sandbox' script
+     * so it doesn't make changes to your real Tracker index.
+     */
+    connection = tracker_sparql_connection_bus_new ("org.freedesktop.Tracker3.Miner.Files", NULL, NULL, 
&error);
+
+    g_assert_no_error (error);
+
+    if (!g_getenv ("TRACKER_INDEXED_TMPDIR"))
+    {
+        g_error ("This test expects to be run inside `tracker sandbox --index-recursive-tmpdir`.");
+    }
+
+    g_setenv ("TMPDIR", g_getenv ("TRACKER_INDEXED_TMPDIR"), TRUE);
+
+    setup_test_suite ();
+
+    return g_test_run ();
+}
diff --git a/test/automated/displayless/test-utilities-tracker.c 
b/test/automated/displayless/test-utilities-tracker.c
new file mode 100644
index 000000000..5baf18366
--- /dev/null
+++ b/test/automated/displayless/test-utilities-tracker.c
@@ -0,0 +1,143 @@
+#include "test-utilities-tracker.h"
+
+#include "tracker-miner-proxy.h"
+
+#define AWAIT_FILE_PROCESSED_TIMEOUT 10
+
+struct _TrackerFilesProcessedWatcher
+{
+    TrackerMiner *proxy;
+    GList *file_list;
+};
+
+static void
+files_processed_cb (TrackerMiner *proxy,
+                    GVariant     *files,
+                    gpointer      user_data)
+{
+    TrackerFilesProcessedWatcher *data = user_data;
+    GVariantIter iter;
+    GVariant *file_info;
+
+    /* Save all the status info in our structure. Don't do this in real apps,
+     * but it's useful for tests to assert about what the miner did.
+     */
+    g_variant_iter_init (&iter, files);
+    while ((file_info = g_variant_iter_next_value (&iter)))
+    {
+        data->file_list = g_list_prepend (data->file_list, file_info);
+    }
+}
+
+TrackerFilesProcessedWatcher *
+tracker_files_processed_watcher_new (const gchar *bus_name,
+                                     const gchar *object_path)
+{
+    TrackerFilesProcessedWatcher *data;
+    g_autoptr (GError) error = NULL;
+
+    data = g_slice_new0 (TrackerFilesProcessedWatcher);
+    data->proxy = tracker_miner_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                        G_DBUS_PROXY_FLAGS_NONE,
+                                                        bus_name,
+                                                        object_path,
+                                                        NULL,
+                                                        &error);
+
+    g_assert_no_error (error);
+
+    g_signal_connect (data->proxy, "files-processed", G_CALLBACK (files_processed_cb), data);
+
+    return data;
+}
+
+void
+tracker_files_processed_watcher_free (TrackerFilesProcessedWatcher *data)
+{
+    g_clear_object (&data->proxy);
+    g_list_free_full (data->file_list, (GDestroyNotify) g_variant_unref);
+
+    g_slice_free (TrackerFilesProcessedWatcher, data);
+}
+
+static gboolean await_file_timeout_cb (gpointer user_data)
+{
+    GFile *file = user_data;
+    g_autofree gchar *uri;
+
+    uri = g_file_get_uri (file);
+
+    g_error ("Timeout waiting for %s to be processed.", uri);
+
+    return G_SOURCE_REMOVE;
+}
+
+static gint
+check_file_status_cb (GVariant *status,
+                      GFile    *target_file)
+{
+    gchar *uri, *message;
+    gboolean success;
+    g_autoptr (GFile) file = NULL;
+
+    g_variant_get (status, "(&sb&s)", &uri, &success, &message);
+
+    file = g_file_new_for_uri (uri);
+
+    if (g_file_equal (file, target_file))
+    {
+        if (success)
+        {
+            g_info ("Matched successful processing of %s", uri);
+            return 0;
+        }
+        else
+        {
+            g_error ("Error processing %s: %s", uri, message);
+        }
+    }
+
+    return 1;
+}
+
+
+static void
+files_processed_quit_main_loop_cb (TrackerMiner *proxy,
+                                   GVariant     *files,
+                                   gpointer      user_data)
+{
+    GMainLoop *loop = user_data;
+
+    g_main_loop_quit (loop);
+}
+
+void
+tracker_files_processed_watcher_await_file (TrackerFilesProcessedWatcher *watcher,
+                                            GFile                        *file)
+{
+    g_autoptr (GMainLoop) loop = NULL;
+    g_autoptr (GDBusProxy) proxy = NULL;
+    guint timeout_id;
+    gulong signal_id;
+
+    if (g_list_find_custom (watcher->file_list, file, (GCompareFunc) check_file_status_cb))
+    {
+        return;
+    }
+
+    loop = g_main_loop_new (NULL, 0);
+
+    signal_id = g_signal_connect_after (watcher->proxy, "files-processed", G_CALLBACK 
(files_processed_quit_main_loop_cb), loop);
+    timeout_id = g_timeout_add_seconds (AWAIT_FILE_PROCESSED_TIMEOUT, await_file_timeout_cb, file);
+
+    while (TRUE)
+    {
+        g_main_loop_run (loop);
+
+        if (g_list_find_custom (watcher->file_list, file, (GCompareFunc) check_file_status_cb))
+            break;
+    }
+
+    g_source_remove (timeout_id);
+    g_signal_handler_disconnect (watcher->proxy, signal_id);
+}
diff --git a/test/automated/displayless/test-utilities-tracker.h 
b/test/automated/displayless/test-utilities-tracker.h
new file mode 100644
index 000000000..5e433901d
--- /dev/null
+++ b/test/automated/displayless/test-utilities-tracker.h
@@ -0,0 +1,19 @@
+#include <gio/gio.h>
+
+#pragma once
+
+#define TRACKER_MINERFS_BUS_NAME "org.freedesktop.Tracker3.Miner.Files"
+#define TRACKER_MINERFS_OBJECT_PATH "/org/freedesktop/Tracker3/Miner/Files"
+
+#define TRACKER_EXTRACT_BUS_NAME "org.freedesktop.Tracker3.Miner.Extract"
+#define TRACKER_EXTRACT_OBJECT_PATH "/org/freedesktop/Tracker3/Miner/Extract"
+
+typedef struct _TrackerFilesProcessedWatcher TrackerFilesProcessedWatcher;
+
+TrackerFilesProcessedWatcher *tracker_files_processed_watcher_new (const gchar *bus_name,
+                                                                   const gchar *object_path);
+
+void tracker_files_processed_watcher_free (TrackerFilesProcessedWatcher *data);
+
+void tracker_files_processed_watcher_await_file (TrackerFilesProcessedWatcher *watcher,
+                                                 GFile                        *file);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]