test_multi_step_fail (Test *test,
                      gconstpointer data)
{
  GHashTable *headers = NULL;
  gint spot = 0;
  gchar *id = NULL;
  gchar *prompt = NULL;
  const ErrorMultiFixture *fix = data;

  if (fix->message)
    cockpit_expect_message (fix->message);

  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;
      gboolean ready_for_next = TRUE;

      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);
      g_assert (error != NULL);

      /* 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;
          if (fix->pause)
            {
              ready_for_next = FALSE;
              g_timeout_add_seconds (fix->pause, on_timeout_set_flag, &ready_for_next);
            }

          while (ready_for_next == FALSE)
            g_main_context_iteration (NULL, TRUE);

          if (response)
            json_object_unref (response);
          g_hash_table_unref (headers);

          g_assert_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED);
          g_clear_error (&error);
        }
      else
        {
          g_assert (response == NULL);
          if (fix->error_code)
            g_assert_error (error, COCKPIT_ERROR, fix->error_code);
          else
            g_assert (error != NULL);

          g_assert_cmpstr (fix->error_message, ==, error->message);
          g_clear_error (&error);
          break;
        }
    }

  if (headers)
    g_hash_table_destroy (headers);
}
test_multi_step_fail (Test *test,
                      gconstpointer data)
{
  GHashTable *headers = NULL;
  gint spot = 0;
  gchar *id = NULL;
  gchar *prompt = NULL;
  const ErrorMultiFixture *fix = data;

  if (fix->message)
    cockpit_expect_message (fix->message);

  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;
      gboolean ready_for_next = TRUE;

      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);
      g_assert (error != NULL);

       
      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;
          if (fix->pause)
            {
              ready_for_next = FALSE;
              g_timeout_add_seconds (fix->pause, on_timeout_set_flag, &ready_for_next);
            }

          while (ready_for_next == FALSE)
            g_main_context_iteration (NULL, TRUE);

          if (response)
            json_object_unref (response);
          g_hash_table_unref (headers);

          g_assert_error (error, COCKPIT_ERROR, COCKPIT_ERROR_AUTHENTICATION_FAILED);
          g_clear_error (&error);
        }
      else
        {
          g_assert (response == NULL);
          if (fix->error_code)
            g_assert_error (error, COCKPIT_ERROR, fix->error_code);
          else
            g_assert (error != NULL);

          g_assert_cmpstr (fix->error_message, ==, error->message);
          g_clear_error (&error);
          break;
        }
    }

  if (headers)
    g_hash_table_destroy (headers);
}