blob: cd21f7f56eac53436b3939bebbbf71b7cda077ab [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/bound_session_credentials/bound_session_request_throttled_handler_renderer_impl.h"
#include <algorithm>
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/sequence_checker_impl.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/task_runner.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/test/test_io_thread.h"
#include "chrome/common/renderer_configuration.mojom-shared.h"
#include "chrome/renderer/bound_session_credentials/bound_session_request_throttled_in_renderer_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace {
using UnblockAction = BoundSessionRequestThrottledHandler::UnblockAction;
using ResumeOrCancelThrottledRequestCallback =
BoundSessionRequestThrottledHandler::
ResumeOrCancelThrottledRequestCallback;
using ::testing::_;
} // namespace
class MockBoundSessionRequestThrottledInRendererManager
: public BoundSessionRequestThrottledInRendererManager {
public:
MockBoundSessionRequestThrottledInRendererManager() {
sequence_checker_.DetachFromSequence();
ON_CALL(*this, HandleRequestBlockedOnCookie)
.WillByDefault(testing::Invoke(
this, &MockBoundSessionRequestThrottledInRendererManager::
HandleRequestBlockedOnCookieCalled));
}
MOCK_METHOD(void,
HandleRequestBlockedOnCookie,
(const GURL&,
BoundSessionRequestThrottledHandler::
ResumeOrCancelThrottledRequestCallback),
(override));
void BindSequenceChecker() {
EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
}
private:
~MockBoundSessionRequestThrottledInRendererManager() override = default;
void HandleRequestBlockedOnCookieCalled(
const GURL& untrusted_request_url,
ResumeOrCancelThrottledRequestCallback callback) {
EXPECT_TRUE(sequence_checker_.CalledOnValidSequence());
std::move(callback).Run(
UnblockAction::kResume,
chrome::mojom::ResumeBlockedRequestsTrigger::kCookieAlreadyFresh);
}
// Used to verify `HandleRequestBlockedOnCookie()` is called on the right
// sequence.
base::SequenceCheckerImpl sequence_checker_;
};
TEST(BoundSessionRequestThrottledHandlerRendererImplTest,
HandleRequestBlockedOnCookie) {
base::test::TaskEnvironment task_environment{
base::test::TaskEnvironment::ThreadingMode::MULTIPLE_THREADS};
scoped_refptr<MockBoundSessionRequestThrottledInRendererManager> manager =
base::MakeRefCounted<MockBoundSessionRequestThrottledInRendererManager>();
base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
scoped_refptr<base::SequencedTaskRunner> io_task_runner =
io_thread.task_runner();
// Initialize the mock to ensure the sequence checker is attached to the
// `io_task_runner`. After initialization,
// `MockManager::HandleRequestBlockedOnCookie` will always verify, it is
// called on the `io_task_runner`.
base::RunLoop initialize_mock_run_loop;
io_task_runner->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&MockBoundSessionRequestThrottledInRendererManager::
BindSequenceChecker,
manager),
base::BindOnce(
[](base::OnceClosure callback) { std::move(callback).Run(); },
initialize_mock_run_loop.QuitClosure()));
initialize_mock_run_loop.Run();
EXPECT_CALL(*manager, HandleRequestBlockedOnCookie);
// Used to check that the callback passed to
// `BoundSessionRequestThrottledHandlerRendererImpl` is executed on the
// caller's sequence runner.
base::SequenceCheckerImpl sequence_checker;
BoundSessionRequestThrottledHandlerRendererImpl listener(manager,
io_task_runner);
base::RunLoop run_loop;
listener.HandleRequestBlockedOnCookie(
GURL(),
base::BindOnce(
[](base::SequenceCheckerImpl checker, base::OnceClosure callback,
UnblockAction action,
chrome::mojom::ResumeBlockedRequestsTrigger resume_trigger) {
EXPECT_TRUE(checker.CalledOnValidSequence());
std::move(callback).Run();
},
std::move(sequence_checker), run_loop.QuitClosure()));
run_loop.Run();
testing::Mock::VerifyAndClearExpectations(manager.get());
}