summaryrefslogtreecommitdiffstats
path: root/tests/network/test-network-panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/network/test-network-panel.c')
-rw-r--r--tests/network/test-network-panel.c874
1 files changed, 874 insertions, 0 deletions
diff --git a/tests/network/test-network-panel.c b/tests/network/test-network-panel.c
new file mode 100644
index 0000000..b68c06f
--- /dev/null
+++ b/tests/network/test-network-panel.c
@@ -0,0 +1,874 @@
+/*
+ * Copyright (c) 2010-2014, 2018 Red Hat, Inc.
+ *
+ * The Control Center is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * The Control Center is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with the Control Center; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Benjamin Berg <bberg@redhat.com>
+ */
+
+#define G_LOG_DOMAIN "test-network-panel"
+
+#include "nm-macros-internal.h"
+
+#include <NetworkManager.h>
+#include <nm-client.h>
+#include <nm-utils.h>
+
+#include "nm-test-libnm-utils.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <gtk/gtk.h>
+
+#include "cc-test-window.h"
+#include "shell/cc-object-storage.h"
+
+#include "nmtst-helpers.h"
+
+typedef struct {
+ NMTstcServiceInfo *sinfo;
+ NMClient *client;
+
+ NMDevice *main_ether;
+
+ GtkWindow *shell;
+ CcPanel *panel;
+} NetworkPanelFixture;
+
+
+extern GType cc_network_panel_get_type (void);
+
+static void
+fixture_set_up_empty (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ g_autoptr(GError) error = NULL;
+
+ cc_object_storage_initialize ();
+
+ /* Bring up the libnm service. */
+ fixture->sinfo = nmtstc_service_init ();
+
+ fixture->client = nm_client_new (NULL, &error);
+ g_assert_no_error (error);
+
+ /* Insert into object storage so that we see the same events as the panel. */
+ cc_object_storage_add_object (CC_OBJECT_NMCLIENT, fixture->client);
+
+ fixture->shell = GTK_WINDOW (cc_test_window_new ());
+
+ fixture->panel = g_object_new (cc_network_panel_get_type (),
+ "shell", CC_SHELL (fixture->shell),
+ NULL);
+
+ g_object_ref (fixture->panel);
+ cc_shell_set_active_panel (CC_SHELL (fixture->shell), fixture->panel);
+
+ gtk_window_present (fixture->shell);
+}
+
+static void
+fixture_tear_down (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ g_clear_object (&fixture->panel);
+ g_clear_object (&fixture->client);
+ g_clear_pointer (&fixture->shell, gtk_window_destroy);
+
+ cc_object_storage_destroy ();
+
+ g_clear_pointer (&fixture->sinfo, nmtstc_service_cleanup);
+}
+
+static void
+fixture_set_up_wired (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMDevice *second;
+
+ fixture_set_up_empty (fixture, user_data);
+
+ fixture->main_ether = nmtstc_service_add_wired_device (fixture->sinfo,
+ fixture->client,
+ "eth1000",
+ "52:54:00:ab:db:23",
+ NULL);
+
+ /* Add/remove one to catch issues with signal disconnects. */
+ second = nmtstc_service_add_wired_device (fixture->sinfo,
+ fixture->client,
+ "eth1001",
+ "52:54:00:ab:db:24",
+ NULL);
+ nmtst_remove_device (fixture->sinfo, fixture->client, second);
+}
+
+/*****************************************************************************/
+
+static GtkWidget *
+find_label (GtkWidget *widget,
+ const gchar *label_pattern)
+{
+ GtkWidget *child;
+ GtkWidget *label = NULL;
+
+ if (GTK_IS_LABEL (widget)) {
+ const gchar *text = gtk_label_get_text (GTK_LABEL (widget));
+ if (g_pattern_match_simple (label_pattern, text))
+ return widget;
+ }
+
+ if (ADW_IS_PREFERENCES_ROW (widget)) {
+ const gchar *text = adw_preferences_row_get_title (ADW_PREFERENCES_ROW (widget));
+ if (g_pattern_match_simple (label_pattern, text))
+ return widget;
+ }
+
+ if (ADW_IS_ACTION_ROW (widget)) {
+ const gchar *text = adw_action_row_get_subtitle (ADW_ACTION_ROW (widget));
+ if (g_pattern_match_simple (label_pattern, text))
+ return widget;
+ }
+
+ for (child = gtk_widget_get_first_child (widget);
+ child;
+ child = gtk_widget_get_next_sibling (child)) {
+ label = find_label (child, label_pattern);
+ if (label)
+ break;
+ }
+
+ return label;
+}
+
+static int
+widget_geo_dist (GtkWidget *a,
+ GtkWidget *b,
+ GtkWidget *base)
+{
+ GtkAllocation allocation;
+ double ax0, ay0, ax1, ay1, bx0, by0, bx1, by1, xdist = 0, ydist = 0;
+
+ gtk_widget_get_allocation (a, &allocation);
+ if (!gtk_widget_translate_coordinates (a, base, 0, 0, &ax0, &ay0) ||
+ !gtk_widget_translate_coordinates (a, base, allocation.width, allocation.height, &ax1, &ay1))
+ return -G_MAXINT;
+
+ gtk_widget_get_allocation (b, &allocation);
+ if (!gtk_widget_translate_coordinates (b, base, 0, 0, &bx0, &by0) ||
+ !gtk_widget_translate_coordinates (b, base, allocation.width, allocation.height, &bx1, &by1))
+ return +G_MAXINT;
+
+ if (bx0 >= ax1)
+ xdist = bx0 - ax1;
+ else if (ax0 >= bx1)
+ xdist = ax0 - bx1;
+ if (by0 >= ay1)
+ ydist = by0 - ay1;
+ else if (ay0 >= by1)
+ ydist = ay0 - by1;
+
+ return xdist + ydist;
+}
+
+static GList*
+test_list_descendants (GtkWidget *widget,
+ GType widget_type)
+{
+ GtkWidget *child;
+ GList *results = NULL;
+
+ for (child = gtk_widget_get_first_child (widget);
+ child;
+ child = gtk_widget_get_next_sibling (child)) {
+ if (!widget_type || g_type_is_a (G_OBJECT_TYPE (child), widget_type))
+ results = g_list_prepend (results, child);
+ else
+ results = g_list_concat (results, test_list_descendants (child, widget_type));
+ }
+
+ return results;
+}
+
+static int
+widget_geo_cmp (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ gpointer *data = user_data;
+ GtkWidget *wa = (void*) a, *wb = (void*) b, *toplevel = data[0], *base_widget = data[1];
+ int adist = widget_geo_dist (wa, base_widget, toplevel);
+ int bdist = widget_geo_dist (wb, base_widget, toplevel);
+ return adist > bdist ? +1 : adist == bdist ? 0 : -1;
+}
+
+static GtkWidget *
+find_sibling (GtkWidget *widget,
+ GType parent_type,
+ GType sibling_type)
+{
+ g_autoptr(GList) siblings = NULL;
+ GtkWidget *tmpwidget = widget;
+ gpointer data[2];
+
+ /* find all sibling candidates */
+ while ((tmpwidget = gtk_widget_get_parent (tmpwidget)) != NULL)
+ {
+ siblings = g_list_concat (siblings, test_list_descendants (tmpwidget, sibling_type));
+
+ /* Stop searching further up if we reached the defined parent */
+ if (parent_type && g_type_is_a (G_OBJECT_TYPE (tmpwidget), parent_type))
+ break;
+ }
+
+ /* sort them by distance to base_widget */
+ data[0] = gtk_widget_get_native (widget);
+ data[1] = widget;
+ siblings = g_list_sort_with_data (siblings, widget_geo_cmp, data);
+
+ /* pick nearest != base_widget */
+ siblings = g_list_remove (siblings, widget);
+ tmpwidget = siblings ? siblings->data : NULL;
+
+ return tmpwidget;
+}
+
+/*****************************************************************************/
+
+#if 0 /* See /network-panel-wired/vpn-sorting note */
+static GtkWidget*
+find_parent_of_type(GtkWidget *widget, GType parent)
+{
+ while (widget) {
+ widget = gtk_widget_get_parent (widget);
+ if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (widget), parent))
+ return widget;
+ }
+
+ return NULL;
+}
+#endif
+
+/*****************************************************************************/
+
+static void
+test_empty_ui (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ GtkWidget *bt_header;
+ GtkWidget *wired_header;
+
+ /* There should be no Wired or Bluetooth sections */
+ wired_header = find_label (GTK_WIDGET (fixture->shell), "Wired");
+ g_assert_false (wired_header && gtk_widget_is_visible(wired_header));
+
+ bt_header = find_label (GTK_WIDGET (fixture->shell), "Bluetooth");
+ g_assert_false (bt_header && gtk_widget_is_visible(bt_header));
+}
+
+/*****************************************************************************/
+
+static void
+test_device_add (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ const gchar *device_path;
+
+ /* Tell the test service to add a new device.
+ * We use some weird numbers so that the devices will not exist on the
+ * host system. */
+ fixture->main_ether = nmtstc_service_add_wired_device (fixture->sinfo,
+ fixture->client,
+ "eth1000",
+ "52:54:00:ab:db:23",
+ NULL);
+ device_path = nm_object_get_path (NM_OBJECT (fixture->main_ether));
+ g_debug("Device added: %s\n", device_path);
+
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "Wired"));
+}
+
+static void
+test_second_device_add (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMDevice *device;
+ const gchar *device_path;
+
+ test_device_add (fixture, user_data);
+
+ device = nmtstc_service_add_wired_device (fixture->sinfo,
+ fixture->client,
+ "eth1001",
+ "52:54:00:ab:db:24",
+ NULL);
+ device_path = nm_object_get_path (NM_OBJECT (device));
+ g_debug("Second device added: %s\n", device_path);
+
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "Wired"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "Ethernet (eth1000)"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "Ethernet (eth1001)"));
+}
+
+static void
+test_second_device_add_remove (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMDevice *device;
+ const gchar *device_path;
+ GtkWidget *bt_header;
+
+ test_device_add (fixture, user_data);
+
+ device = nmtstc_service_add_wired_device (fixture->sinfo,
+ fixture->client,
+ "eth1001",
+ "52:54:00:ab:db:24",
+ NULL);
+ device_path = nm_object_get_path (NM_OBJECT (device));
+ g_debug("Second device added: %s\n", device_path);
+
+ nmtst_remove_device (fixture->sinfo, fixture->client, device);
+ g_debug("Second device removed again\n");
+
+ /* eth1000 should be labeled "Wired" again */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "Wired"));
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "Ethernet (eth1000)"));
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "Ethernet (eth1001)"));
+
+ /* Some more checks for unrelated UI not showing up randomly */
+ bt_header = find_label (GTK_WIDGET (fixture->shell), "Bluetooth");
+ g_assert_false (bt_header && gtk_widget_is_visible(bt_header));
+}
+
+/*****************************************************************************/
+
+static void
+add_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ NMClient *client = NM_CLIENT (object);
+ EventWaitInfo *info = user_data;
+ g_autoptr(GError) error = NULL;
+
+ info->rc = nm_client_add_connection_finish (client, result, &error);
+ g_assert_no_error (error);
+ g_assert_nonnull (info->rc);
+
+ info->other_remaining--;
+ WAIT_CHECK_REMAINING()
+}
+
+static void
+delete_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ NMRemoteConnection *connection = NM_REMOTE_CONNECTION (object);
+ EventWaitInfo *info = user_data;
+ g_autoptr(GError) error = NULL;
+
+ nm_remote_connection_delete_finish (connection, result, &error);
+ g_assert_no_error (error);
+
+ info->other_remaining--;
+ WAIT_CHECK_REMAINING()
+}
+
+static void
+test_connection_add (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ g_autoptr(GError) error = NULL;
+ WAIT_DECL()
+
+ conn = nmtst_create_minimal_connection ("test-inactive", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
+ nm_device_connection_compatible (fixture->main_ether, conn, &error);
+ g_assert_no_error (error);
+
+ nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_ADDED);
+
+ WAIT_FINISHED(5)
+
+ g_clear_object (&info.rc);
+ g_object_unref (conn);
+
+ /* We have one (non-active) connection only, so we get a special case */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "Cable unplugged"));
+}
+
+/*****************************************************************************/
+
+static void
+test_unconnected_carrier_plug (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ nmtst_set_wired_speed (fixture->sinfo, fixture->main_ether, 1234);
+ nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER);
+
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "1234 Mb/s"));
+}
+
+
+/*****************************************************************************/
+
+
+static void
+test_connection_add_activate (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ NMActiveConnection *active_conn = NULL;
+ g_autoptr(GError) error = NULL;
+ GtkWidget *label, *sw;
+
+ /* First set us into disconnected state with a carrier. */
+ nmtst_set_wired_speed (fixture->sinfo, fixture->main_ether, 1234);
+ nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER);
+
+ conn = nmtst_create_minimal_connection ("test-active", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
+
+ nm_device_connection_compatible (fixture->main_ether, conn, &error);
+ g_assert_no_error (error);
+
+ active_conn = nmtst_add_and_activate_connection (fixture->sinfo, fixture->client, fixture->main_ether, conn);
+ g_object_unref (active_conn);
+
+ label = find_label (GTK_WIDGET (fixture->shell), "1234 Mb/s");
+ sw = find_sibling (label, GTK_TYPE_LIST_BOX_ROW, GTK_TYPE_SWITCH);
+ g_assert_nonnull (sw);
+ g_assert_false (gtk_switch_get_state (GTK_SWITCH (sw)));
+
+ /* Now set the state to connected and check the switch state */
+ nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE);
+ g_assert_true (gtk_switch_get_state (GTK_SWITCH (sw)));
+
+ /* Let's toggle the switch back and check we get events */
+ gtk_switch_set_active (GTK_SWITCH (sw), FALSE);
+
+ /* Only one connection, so a generic label. */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "Connected - 1234 Mb/s"));
+}
+
+static void
+test_connection_multi_add_activate (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ GtkWidget *sw, *bt_header;
+ g_autoptr(GError) error = NULL;
+
+ /* Add a single connection (just changing up to other test). */
+ test_connection_add (fixture, user_data);
+
+ /* Basically same as test_connection_add_activate but with different assertions. */
+ nmtst_set_wired_speed (fixture->sinfo, fixture->main_ether, 1234);
+ nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER);
+
+ conn = nmtst_create_minimal_connection ("test-active", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
+
+ nm_device_connection_compatible (fixture->main_ether, conn, &error);
+ g_assert_no_error (error);
+
+ g_object_unref (nmtst_add_and_activate_connection (fixture->sinfo, fixture->client, fixture->main_ether, conn));
+
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "test-inactive"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "test-active"));
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "52:54:00:ab:db:23"));
+
+ /* We have no switch if there are multiple connections */
+ sw = find_sibling (find_label (GTK_WIDGET (fixture->shell), "test-active"), GTK_TYPE_LIST_BOX_ROW, GTK_TYPE_SWITCH);
+ if (sw)
+ g_assert_false (gtk_widget_is_visible (sw));
+
+ /* Now set the state to connected and check the switch state */
+ nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE);
+
+ /* Hardware address is shown at this point */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "52:54:00:ab:db:23"));
+
+ /* Some more checks for unrelated UI not showing up randomly */
+ bt_header = find_label (GTK_WIDGET (fixture->shell), "Bluetooth");
+ g_assert_false (bt_header && gtk_widget_is_visible(bt_header));
+}
+
+/*****************************************************************************/
+
+static void
+test_vpn_add (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ NMSettingConnection *connsetting;
+ NMSettingVpn *setting;
+
+ WAIT_DECL()
+
+ conn = nmtst_create_minimal_connection ("test_vpn_a", NULL, NM_SETTING_VPN_SETTING_NAME, &connsetting);
+ setting = nm_connection_get_setting_vpn (conn);
+ g_object_set (G_OBJECT (connsetting), NM_SETTING_CONNECTION_ID, "A", NULL);
+ g_object_set (G_OBJECT (setting), NM_SETTING_VPN_SERVICE_TYPE, "org.freedesktop.NetworkManager.vpnc", NULL);
+
+ nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_ADDED);
+
+ g_object_unref (conn);
+
+ WAIT_FINISHED(5)
+
+ g_clear_object (&info.rc);
+
+ /* Make sure it shows up. */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "A"));
+}
+
+/*****************************************************************************/
+
+static void
+test_vpn_add_remove (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ NMSettingConnection *connsetting;
+ NMSettingVpn *setting;
+ WAIT_DECL()
+
+ conn = nmtst_create_minimal_connection ("test_vpn_a", NULL, NM_SETTING_VPN_SETTING_NAME, &connsetting);
+ setting = nm_connection_get_setting_vpn (conn);
+ g_object_set (G_OBJECT (connsetting), NM_SETTING_CONNECTION_ID, "A", NULL);
+ g_object_set (G_OBJECT (setting), NM_SETTING_VPN_SERVICE_TYPE, "org.freedesktop.NetworkManager.vpnc", NULL);
+
+ nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_ADDED);
+
+ WAIT_FINISHED(5)
+
+ /* Make sure it shows up. */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "A"));
+
+ /* And delete again */
+ nm_remote_connection_delete_async (info.rc, NULL, delete_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_REMOVED);
+
+ WAIT_FINISHED(5)
+
+ g_clear_object (&info.rc);
+ g_object_unref (conn);
+
+ /* Make sure it does not show up. */
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "A"));
+}
+
+/*****************************************************************************/
+
+static void
+test_vpn_updating (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ NMSettingConnection *connsetting;
+ NMSettingVpn *setting;
+ GVariantBuilder builder;
+ WAIT_DECL()
+
+ conn = nmtst_create_minimal_connection ("test_vpn_a", NULL, NM_SETTING_VPN_SETTING_NAME, &connsetting);
+ setting = nm_connection_get_setting_vpn (conn);
+ g_object_set (G_OBJECT (connsetting), NM_SETTING_CONNECTION_ID, "A", NULL);
+ g_object_set (G_OBJECT (setting), NM_SETTING_VPN_SERVICE_TYPE, "org.freedesktop.NetworkManager.vpnc", NULL);
+
+ nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_ADDED);
+
+ WAIT_FINISHED(5)
+
+ g_object_unref (conn);
+
+ /* Make sure it shows up. */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "A"));
+
+ /* Rename VPN from A to B */
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sa{sv}}"));
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sa{sv}}"));
+ g_variant_builder_add (&builder, "s", "connection");
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
+ g_variant_builder_add (&builder, "s", "id");
+ g_variant_builder_add (&builder, "v", g_variant_new_string ("B"));
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
+ g_variant_builder_add (&builder, "s", "type");
+ g_variant_builder_add (&builder, "v", g_variant_new_string (nm_connection_get_connection_type (NM_CONNECTION (info.rc))));
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
+ g_variant_builder_add (&builder, "s", "uuid");
+ g_variant_builder_add (&builder, "v", g_variant_new_string (nm_connection_get_uuid (NM_CONNECTION (info.rc))));
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_close (&builder);
+ g_variant_builder_close (&builder);
+
+ nmtstc_service_update_connection_variant (
+ fixture->sinfo,
+ nm_object_get_path (NM_OBJECT (info.rc)),
+ g_variant_builder_end (&builder),
+ FALSE);
+ g_variant_builder_clear (&builder);
+
+ WAIT_CONNECTION(info.rc, 1, "changed");
+
+ WAIT_FINISHED(5)
+
+ g_clear_object (&info.rc);
+
+ /* Make sure it the label got renamed. */
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "A"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "B"));
+}
+
+/*****************************************************************************/
+
+#if 0 /* See note below, where this test is added */
+static void
+test_vpn_sorting (NetworkPanelFixture *fixture,
+ gconstpointer user_data)
+{
+ NMConnection *conn;
+ NMSettingConnection *connsetting;
+ NMSettingVpn *setting;
+ g_autoptr(GError) error = NULL;
+ GVariantBuilder builder;
+ GtkWidget *a, *b, *container;
+ GList *list;
+ WAIT_DECL()
+
+ conn = nmtst_create_minimal_connection ("test_vpn_a", NULL, NM_SETTING_VPN_SETTING_NAME, &connsetting);
+ setting = nm_connection_get_setting_vpn (conn);
+ g_object_set (G_OBJECT (connsetting), NM_SETTING_CONNECTION_ID, "A", NULL);
+ g_object_set (G_OBJECT (setting), NM_SETTING_VPN_SERVICE_TYPE, "org.freedesktop.NetworkManager.vpnc", NULL);
+
+ nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_ADDED);
+
+ WAIT_FINISHED(5)
+
+ g_object_unref (conn);
+ g_clear_object (&info.rc);
+
+ /* Create a second VPN which should be in front in the list */
+ conn = nmtst_create_minimal_connection ("test_vpn_b", NULL, NM_SETTING_VPN_SETTING_NAME, &connsetting);
+ setting = nm_connection_get_setting_vpn (conn);
+ g_object_set (G_OBJECT (connsetting), NM_SETTING_CONNECTION_ID, "1", NULL);
+ g_object_set (G_OBJECT (setting), NM_SETTING_VPN_SERVICE_TYPE, "org.freedesktop.NetworkManager.vpnc", NULL);
+
+ nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info);
+
+ info.other_remaining = 1;
+ WAIT_CLIENT(fixture->client, 2, NM_CLIENT_CONNECTIONS, NM_CLIENT_CONNECTION_ADDED);
+
+ WAIT_FINISHED(5)
+
+ g_object_unref (conn);
+
+ /* Make sure both VPNs are there. */
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "A"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "1"));
+
+ /* And test that A is after 1 */
+ a = find_parent_of_type (find_label (GTK_WIDGET (fixture->shell), "A"), GTK_TYPE_STACK);
+ b = find_parent_of_type (find_label (GTK_WIDGET (fixture->shell), "1"), GTK_TYPE_STACK);
+ container = gtk_widget_get_parent (a);
+ list = gtk_container_get_children (GTK_CONTAINER (container));
+ g_assert_cmpint (g_list_index (list, a), >, g_list_index (list, b));
+ g_list_free (list);
+
+ /* Rename VPN from 1 to B */
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sa{sv}}"));
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sa{sv}}"));
+ g_variant_builder_add (&builder, "s", "connection");
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
+ g_variant_builder_add (&builder, "s", "id");
+ g_variant_builder_add (&builder, "v", g_variant_new_string ("B"));
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
+ g_variant_builder_add (&builder, "s", "type");
+ g_variant_builder_add (&builder, "v", g_variant_new_string (nm_connection_get_connection_type (NM_CONNECTION (info.rc))));
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
+ g_variant_builder_add (&builder, "s", "uuid");
+ g_variant_builder_add (&builder, "v", g_variant_new_string (nm_connection_get_uuid (NM_CONNECTION (info.rc))));
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_close (&builder);
+ g_variant_builder_close (&builder);
+
+ nmtstc_service_update_connection_variant (
+ fixture->sinfo,
+ nm_object_get_path (NM_OBJECT (info.rc)),
+ g_variant_builder_end (&builder),
+ FALSE);
+ g_variant_builder_clear (&builder);
+
+ WAIT_CONNECTION(info.rc, 1, "changed");
+
+ WAIT_FINISHED(5)
+
+ g_clear_object (&info.rc);
+
+ /* Make sure it the label got renamed. */
+ g_assert_null (find_label (GTK_WIDGET (fixture->shell), "1"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "A"));
+ g_assert_nonnull (find_label (GTK_WIDGET (fixture->shell), "B"));
+
+ /* And test that A is before B */
+ a = find_parent_of_type (find_label (GTK_WIDGET (fixture->shell), "A"), GTK_TYPE_STACK);
+ b = find_parent_of_type (find_label (GTK_WIDGET (fixture->shell), "B"), GTK_TYPE_STACK);
+ container = gtk_widget_get_parent (a);
+ list = gtk_container_get_children (GTK_CONTAINER (container));
+ g_assert_cmpint (g_list_index (list, a), <, g_list_index (list, b));
+ g_list_free (list);
+}
+#endif
+
+/*****************************************************************************/
+
+int
+main (int argc, char **argv)
+{
+ g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
+ g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE);
+ g_setenv ("LC_ALL", "C", TRUE);
+
+ gtk_test_init (&argc, &argv, NULL);
+ adw_init ();
+
+ g_test_add ("/network-panel-wired/empty-ui",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_empty_ui,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/device-add",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_device_add,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/second-device-add",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_second_device_add,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/second-device-add-remove",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_second_device_add_remove,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/unconnected-carrier-plug",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_wired,
+ test_unconnected_carrier_plug,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/connection-add",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_wired,
+ test_connection_add,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/connection-add-activate",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_wired,
+ test_connection_add_activate,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/connection-multi-add-activate",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_wired,
+ test_connection_multi_add_activate,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/vpn-add",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_vpn_add,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/vpn-add-remove",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_vpn_add_remove,
+ fixture_tear_down);
+
+ g_test_add ("/network-panel-wired/vpn-updating",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_vpn_updating,
+ fixture_tear_down);
+
+#if 0
+ /*
+ * FIXME: Currently broken, so test is disabled. Test will likely need
+ * updating when this is fixed to look for GTK_TYPE_LIST_BOX_ROW rather
+ * than GTK_TYPE_STACK.
+ */
+ g_test_add ("/network-panel-wired/vpn-sorting",
+ NetworkPanelFixture,
+ NULL,
+ fixture_set_up_empty,
+ test_vpn_sorting,
+ fixture_tear_down);
+#endif
+
+ return g_test_run ();
+}
+