blob: 66a592dcfe736a8c265d7c0e93dbd226278416c0 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/web_contents_based_canceller.h"
#include "base/test/test_future.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/test/web_contents_tester.h"
#include "content/test/test_render_view_host.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
class WebContentsBasedCancellerTest
: public RenderViewHostImplTestHarness,
public testing::WithParamInterface<
WebContentsBasedCanceller::CancelCondition> {
public:
RenderFrameHostImpl* main_rfh_impl() {
return static_cast<RenderFrameHostImpl*>(main_rfh());
}
protected:
std::unique_ptr<WebContentsBasedCanceller> CreateWebContentsBasedCanceller() {
return WebContentsBasedCanceller::Create(main_rfh_impl(), GetParam());
}
};
INSTANTIATE_TEST_SUITE_P(
All,
WebContentsBasedCancellerTest,
testing::Values(WebContentsBasedCanceller::CancelCondition::kActiveState,
WebContentsBasedCanceller::CancelCondition::kVisibility),
[](const testing::TestParamInfo<WebContentsBasedCancellerTest::ParamType>&
info) {
switch (info.param) {
case WebContentsBasedCanceller::CancelCondition::kActiveState:
return "ActiveState";
case WebContentsBasedCanceller::CancelCondition::kVisibility:
return "Visibility";
}
});
TEST_P(WebContentsBasedCancellerTest, CreateActiveVisible) {
EXPECT_NE(nullptr, CreateWebContentsBasedCanceller());
}
TEST_P(WebContentsBasedCancellerTest, CreateInactive) {
main_rfh_impl()->SetLifecycleState(
RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache);
EXPECT_EQ(nullptr, CreateWebContentsBasedCanceller());
}
TEST_P(WebContentsBasedCancellerTest, CreateHidden) {
web_contents()->WasHidden();
switch (GetParam()) {
case WebContentsBasedCanceller::CancelCondition::kActiveState:
EXPECT_NE(nullptr, CreateWebContentsBasedCanceller());
break;
case WebContentsBasedCanceller::CancelCondition::kVisibility:
EXPECT_EQ(nullptr, CreateWebContentsBasedCanceller());
break;
}
}
TEST_P(WebContentsBasedCancellerTest, BecomeInactive) {
auto ac = CreateWebContentsBasedCanceller();
base::test::TestFuture<void> future;
ac->SetCancelCallback(future.GetCallback());
main_rfh_impl()->SetLifecycleState(
RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache);
EXPECT_TRUE(future.Wait());
}
TEST_P(WebContentsBasedCancellerTest, BecomeHidden) {
auto ac = CreateWebContentsBasedCanceller();
base::test::TestFuture<void> future;
ac->SetCancelCallback(future.GetCallback());
web_contents()->WasHidden();
switch (GetParam()) {
case WebContentsBasedCanceller::CancelCondition::kActiveState:
EXPECT_FALSE(future.IsReady());
break;
case WebContentsBasedCanceller::CancelCondition::kVisibility:
#if BUILDFLAG(IS_ANDROID)
// Android sends HIDDEN when picking a file. We should not cancel in this
// case.
// TODO(crbug.com/457495639): Figure out how to handle Android.
EXPECT_FALSE(future.IsReady());
#else
EXPECT_TRUE(future.IsReady());
#endif
break;
}
}
TEST_P(WebContentsBasedCancellerTest, InactiveBeforeSettingCallback) {
auto ac = CreateWebContentsBasedCanceller();
main_rfh_impl()->SetLifecycleState(
RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache);
base::test::TestFuture<void> future;
ac->SetCancelCallback(future.GetCallback());
EXPECT_TRUE(future.IsReady());
}
TEST_P(WebContentsBasedCancellerTest, HiddenBeforeSettingCallback) {
auto ac = CreateWebContentsBasedCanceller();
web_contents()->WasHidden();
base::test::TestFuture<void> future;
ac->SetCancelCallback(future.GetCallback());
switch (GetParam()) {
case WebContentsBasedCanceller::CancelCondition::kActiveState:
EXPECT_FALSE(future.IsReady());
break;
case WebContentsBasedCanceller::CancelCondition::kVisibility:
EXPECT_TRUE(future.IsReady());
break;
}
}
// Tests that destroying does not call the callback.
TEST_P(WebContentsBasedCancellerTest, Destroy) {
auto ac = CreateWebContentsBasedCanceller();
base::test::TestFuture<void> future;
ac->SetCancelCallback(future.GetCallback());
ac.reset();
main_rfh_impl()->SetLifecycleState(
RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache);
EXPECT_FALSE(future.IsReady());
}
} // namespace content