blob: 1cad513a62190cf74ef8ebdce867abb65bf16879 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fuchsia/base/test_navigation_listener.h"
#include <string>
#include <utility>
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/run_loop.h"
#include "fuchsia/base/mem_buffer_util.h"
namespace cr_fuchsia {
namespace {
void QuitRunLoopAndRunCallback(
base::RunLoop* run_loop,
TestNavigationListener::BeforeAckCallback before_ack_callback,
const fuchsia::web::NavigationState& change,
fuchsia::web::NavigationEventListener::OnNavigationStateChangedCallback
ack_callback) {
run_loop->Quit();
before_ack_callback.Run(change, std::move(ack_callback));
}
} // namespace
TestNavigationListener::TestNavigationListener() {
before_ack_ = base::BindRepeating(
[](const fuchsia::web::NavigationState&,
OnNavigationStateChangedCallback callback) { callback(); });
}
TestNavigationListener::~TestNavigationListener() = default;
void TestNavigationListener::RunUntilNavigationStateMatches(
const fuchsia::web::NavigationState& expected_state) {
DCHECK(before_ack_);
// Spin the runloop until the expected conditions are met.
while (!AllFieldsMatch(expected_state)) {
base::RunLoop run_loop;
base::AutoReset<BeforeAckCallback> callback_setter(
&before_ack_,
base::BindRepeating(&QuitRunLoopAndRunCallback,
base::Unretained(&run_loop), before_ack_));
run_loop.Run();
}
}
void TestNavigationListener::RunUntilUrlEquals(const GURL& expected_url) {
fuchsia::web::NavigationState state;
state.set_url(expected_url.spec());
RunUntilNavigationStateMatches(state);
}
void TestNavigationListener::RunUntilUrlAndTitleEquals(
const GURL& expected_url,
const std::string& expected_title) {
fuchsia::web::NavigationState state;
state.set_url(expected_url.spec());
state.set_title(expected_title);
RunUntilNavigationStateMatches(state);
}
void TestNavigationListener::OnNavigationStateChanged(
fuchsia::web::NavigationState change,
OnNavigationStateChangedCallback callback) {
DCHECK(before_ack_);
// Update our local cache of the Frame's current state.
if (change.has_url())
current_state_.set_url(change.url());
if (change.has_title())
current_state_.set_title(change.title());
if (change.has_can_go_forward())
current_state_.set_can_go_forward(change.can_go_forward());
if (change.has_can_go_back())
current_state_.set_can_go_back(change.can_go_back());
// Signal readiness for the next navigation event.
before_ack_.Run(change, std::move(callback));
}
void TestNavigationListener::SetBeforeAckHook(BeforeAckCallback send_ack_cb) {
DCHECK(send_ack_cb);
before_ack_ = send_ack_cb;
}
bool TestNavigationListener::AllFieldsMatch(
const fuchsia::web::NavigationState& expected) {
bool all_equal = true;
if (expected.has_url()) {
if (!current_state_.has_url() || expected.url() != current_state_.url()) {
all_equal = false;
}
}
if (expected.has_title()) {
if (!current_state_.has_title() ||
expected.title() != current_state_.title()) {
all_equal = false;
}
}
if (expected.has_can_go_forward()) {
if (!current_state_.has_can_go_forward() ||
expected.can_go_forward() != current_state_.can_go_forward()) {
all_equal = false;
}
}
if (expected.has_can_go_back()) {
if (!current_state_.has_can_go_back() ||
expected.can_go_back() != current_state_.can_go_back()) {
all_equal = false;
}
}
return all_equal;
}
} // namespace cr_fuchsia