diff --git a/tests/proxy.c b/tests/proxy.c
index 805ad3f3d12aab6427c7405ac164eb4d75d71291..2800c13131c635f8800ce7a57e69e27a15162300 100644
--- a/tests/proxy.c
+++ b/tests/proxy.c
@@ -161,6 +161,111 @@ test_proxy_basic (TestProxyFixture *fixture, gconstpointer data)
   g_main_loop_run (fixture->loop);
 }
 
+typedef struct {
+  TestProxyFixture *fixture;
+  guint n_params;
+} TestProxyNodeParamData;
+
+static void
+test_proxy_node_param (WpProxyNode *node, int seq, guint id, guint index,
+    guint next, struct spa_pod *param, TestProxyNodeParamData *data)
+{
+  data->n_params++;
+}
+
+static void
+test_proxy_node_enum_params_done (WpProxyNode *node, GAsyncResult *res,
+    TestProxyNodeParamData *data)
+{
+  g_autoptr (GPtrArray) params = NULL;
+  g_autoptr (GError) error = NULL;
+  guint i;
+
+  params = wp_proxy_node_enum_params_collect_finish (node, res, &error);
+  g_assert_no_error (error);
+  g_assert_nonnull (params);
+
+  /* the param signal must have also been fired for all params */
+  g_assert_cmpint (params->len, ==, data->n_params);
+
+  for (i = 0; i < params->len; i++) {
+    struct spa_pod *pod = g_ptr_array_index(params, i);
+    g_assert_true (spa_pod_is_object_type (pod, SPA_TYPE_OBJECT_PropInfo));
+  }
+
+  g_main_loop_quit (data->fixture->loop);
+  g_free (data);
+}
+
+static void
+test_proxy_node_global_added (WpRemote *remote, WpProxy *proxy,
+    TestProxyFixture *fixture)
+{
+  const struct pw_node_info *info;
+  TestProxyNodeParamData *param_data;
+
+  g_assert_nonnull (proxy);
+  g_assert_true (wp_proxy_is_global (proxy));
+  g_assert_cmpuint (wp_proxy_get_interface_type (proxy), ==,
+      PW_TYPE_INTERFACE_Node);
+  g_assert_cmphex (wp_proxy_get_features (proxy), ==,
+      WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO);
+  g_assert_nonnull (wp_proxy_get_pw_proxy (proxy));
+
+  g_assert_true (WP_IS_PROXY_NODE (proxy));
+  info = wp_proxy_node_get_info (WP_PROXY_NODE (proxy));
+  g_assert_nonnull (info);
+  g_assert_cmpint (wp_proxy_get_global_id (proxy), ==, info->id);
+
+  {
+    const char *id;
+    g_autoptr (WpProperties) props =
+        wp_proxy_node_get_properties (WP_PROXY_NODE (proxy));
+
+    g_assert_nonnull (props);
+    g_assert_true (wp_properties_peek_dict (props) == info->props);
+    id = wp_properties_get (props, "node.id");
+    g_assert_nonnull (id);
+    g_assert_cmpint (info->id, ==, atoi(id));
+  }
+
+  param_data = g_new0 (TestProxyNodeParamData, 1);
+  param_data->fixture = fixture;
+
+  g_signal_connect (proxy, "param", (GCallback) test_proxy_node_param,
+      param_data);
+  wp_proxy_node_enum_params_collect (WP_PROXY_NODE (proxy), SPA_PARAM_PropInfo,
+      NULL, NULL, (GAsyncReadyCallback) test_proxy_node_enum_params_done,
+      param_data);
+}
+
+static void
+test_proxy_node (TestProxyFixture *fixture, gconstpointer data)
+{
+  /* load audiotestsrc on the server side */
+  pw_thread_loop_lock (fixture->server.thread_loop);
+  pw_core_add_spa_lib (fixture->server.core, "audiotestsrc",
+      "audiotestsrc/libspa-audiotestsrc");
+  if (!pw_module_load (fixture->server.core, "libpipewire-module-spa-node",
+        "audiotestsrc", NULL)) {
+    pw_thread_loop_unlock (fixture->server.thread_loop);
+    g_test_skip ("audiotestsrc SPA plugin is not installed");
+    return;
+  }
+  pw_thread_loop_unlock (fixture->server.thread_loop);
+
+  /* we should be able to see this exported audiotestsrc node on the client */
+  g_signal_connect (fixture->remote, "global-added::node",
+      (GCallback) test_proxy_node_global_added, fixture);
+
+  /* tell the remote to call global-added only when these features are ready */
+  wp_remote_pipewire_set_default_features (WP_REMOTE_PIPEWIRE (fixture->remote),
+      WP_TYPE_PROXY_NODE, WP_PROXY_FEATURE_PW_PROXY | WP_PROXY_FEATURE_INFO);
+
+  g_assert_true (wp_remote_connect (fixture->remote));
+  g_main_loop_run (fixture->loop);
+}
+
 gint
 main (gint argc, gchar *argv[])
 {
@@ -169,6 +274,8 @@ main (gint argc, gchar *argv[])
 
   g_test_add ("/wp/proxy/basic", TestProxyFixture, NULL,
       test_proxy_setup, test_proxy_basic, test_proxy_teardown);
+  g_test_add ("/wp/proxy/node", TestProxyFixture, NULL,
+      test_proxy_setup, test_proxy_node, test_proxy_teardown);
 
   return g_test_run ();
 }