test_multi_step_success (Test *test,
                         gconstpointer data)
{
  CockpitWebService *service;
  CockpitCreds *creds;
  GHashTable *headers = NULL;
  gint spot = 0;
  gchar *id = NULL;

  const SuccessMultiFixture *fix = data;

  for (spot = 0; fix->headers[spot]; spot++)
    {
      GAsyncResult *result = NULL;
      JsonObject *response = NULL;
      GError *error = NULL;
      const gchar *header = fix->headers[spot];
      const gchar *expect_prompt = fix->prompts[spot];
      gchar *out = NULL;
      gchar *prompt = NULL;

      headers = web_socket_util_new_headers ();
      if (id)
        {
          g_assert (id != NULL);
          out = g_base64_encode ((guint8 *)header, strlen (header));
          g_hash_table_insert (headers, g_strdup ("Authorization"),
                               g_strdup_printf  ("X-Conversation %s %s", id, out));
          g_free (id);
          g_free (out);
          out = NULL;
          id = NULL;
        }
      else
        {
          g_hash_table_insert (headers, g_strdup ("Authorization"),
                               g_strdup (header));
        }
      cockpit_auth_login_async (test->auth, "/cockpit/", NULL, headers, on_ready_get_result, &result);
      g_hash_table_unref (headers);

      while (result == NULL)
        g_main_context_iteration (NULL, TRUE);

      headers = web_socket_util_new_headers ();
      response = cockpit_auth_login_finish (test->auth, result, NULL, headers, &error);
      g_object_unref (result);

      /* Confirm we got the right prompt */
      if (expect_prompt)
        {
          g_assert (prompt == NULL);
          g_assert (id == NULL);

          g_assert (parse_login_reply_challenge (headers, &id, &prompt));
          g_assert_cmpstr (expect_prompt, ==, prompt);
          g_assert (id != NULL);
          g_free (prompt);
          prompt = NULL;

          g_assert_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED);
          g_clear_error (&error);

          g_hash_table_unref (headers);
        }
      else
        {
          g_assert_no_error (error);
        }

      if (response)
        json_object_unref (response);
    }

  mock_auth_include_cookie_as_if_client (headers, headers, "cockpit");
  service = cockpit_auth_check_cookie (test->auth, "/cockpit", headers);
  creds = cockpit_web_service_get_creds (service);
  g_assert_cmpstr ("cockpit", ==, cockpit_creds_get_application (creds));
  g_assert_null (cockpit_creds_get_password (creds));
  if (headers)
    g_hash_table_destroy (headers);
  g_object_unref (service);
}
test_multi_step_success (Test *test,
                         gconstpointer data)
{
  CockpitWebService *service;
  CockpitCreds *creds;
  GHashTable *headers = NULL;
  gint spot = 0;
  gchar *id = NULL;

  const SuccessMultiFixture *fix = data;

  for (spot = 0; fix->headers[spot]; spot++)
    {
      GAsyncResult *result = NULL;
      JsonObject *response = NULL;
      GError *error = NULL;
      const gchar *header = fix->headers[spot];
      const gchar *expect_prompt = fix->prompts[spot];
      gchar *out = NULL;
      gchar *prompt = NULL;

      headers = web_socket_util_new_headers ();
      if (id)
        {
          g_assert (id != NULL);
          out = g_base64_encode ((guint8 *)header, strlen (header));
          g_hash_table_insert (headers, g_strdup ("Authorization"),
                               g_strdup_printf  ("X-Conversation %s %s", id, out));
          g_free (id);
          g_free (out);
          out = NULL;
          id = NULL;
        }
      else
        {
          g_hash_table_insert (headers, g_strdup ("Authorization"),
                               g_strdup (header));
        }
      cockpit_auth_login_async (test->auth, "/cockpit/", NULL, headers, on_ready_get_result, &result);
      g_hash_table_unref (headers);

      while (result == NULL)
        g_main_context_iteration (NULL, TRUE);

      headers = web_socket_util_new_headers ();
      response = cockpit_auth_login_finish (test->auth, result, NULL, headers, &error);
      g_object_unref (result);

       
      if (expect_prompt)
        {
          g_assert (prompt == NULL);
          g_assert (id == NULL);

          g_assert (parse_login_reply_challenge (headers, &id, &prompt));
          g_assert_cmpstr (expect_prompt, ==, prompt);
          g_assert (id != NULL);
          g_free (prompt);
          prompt = NULL;

          g_assert_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED);
          g_clear_error (&error);

          g_hash_table_unref (headers);
        }
      else
        {
          g_assert_no_error (error);
        }

      if (response)
        json_object_unref (response);
    }

  mock_auth_include_cookie_as_if_client (headers, headers, "cockpit");
  service = cockpit_auth_check_cookie (test->auth, "/cockpit", headers);
  creds = cockpit_web_service_get_creds (service);
  g_assert_cmpstr ("cockpit", ==, cockpit_creds_get_application (creds));
  g_assert_null (cockpit_creds_get_password (creds));
  if (headers)
    g_hash_table_destroy (headers);
  g_object_unref (service);
}