blob: 0c77d2ff4049aad91ea9b0ec977206722be94abb [file] [log] [blame]
// Copyright 2016 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 <memory>
#include <utility>
#include "third_party/blink/renderer/core/html/forms/password_input_type.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/insecure_input/insecure_input_service.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
class MockInsecureInputService : public mojom::blink::InsecureInputService {
public:
explicit MockInsecureInputService(LocalFrame& frame) {
service_manager::InterfaceProvider::TestApi test_api(
&frame.GetInterfaceProvider());
test_api.SetBinderForName(
mojom::blink::InsecureInputService::Name_,
WTF::BindRepeating(&MockInsecureInputService::BindRequest,
WTF::Unretained(this)));
}
~MockInsecureInputService() override = default;
void BindRequest(mojo::ScopedMessagePipeHandle handle) {
binding_set_.AddBinding(
this, mojom::blink::InsecureInputServiceRequest(std::move(handle)));
}
unsigned DidEditFieldCalls() const { return num_did_edit_field_calls_; }
private:
void DidEditFieldInInsecureContext() override { ++num_did_edit_field_calls_; }
mojo::BindingSet<InsecureInputService> binding_set_;
unsigned num_did_edit_field_calls_ = 0;
};
// Tests that a Mojo message is sent when a password field is edited
// on the page.
TEST(PasswordInputTypeTest, DidEditFieldEvent) {
std::unique_ptr<DummyPageHolder> page_holder =
DummyPageHolder::Create(IntSize(2000, 2000));
MockInsecureInputService mock_service(page_holder->GetFrame());
page_holder->GetDocument().body()->SetInnerHTMLFromString(
"<input type='password'>");
page_holder->GetDocument().View()->UpdateAllLifecyclePhases(
DocumentLifecycle::LifecycleUpdateReason::kTest);
blink::test::RunPendingTasks();
EXPECT_EQ(0u, mock_service.DidEditFieldCalls());
// Simulate a text field edit.
page_holder->GetDocument().MaybeQueueSendDidEditFieldInInsecureContext();
blink::test::RunPendingTasks();
EXPECT_EQ(1u, mock_service.DidEditFieldCalls());
// Ensure additional edits do not trigger additional notifications.
page_holder->GetDocument().MaybeQueueSendDidEditFieldInInsecureContext();
blink::test::RunPendingTasks();
EXPECT_EQ(1u, mock_service.DidEditFieldCalls());
}
// Tests that a Mojo message is not sent when a password field is edited
// in a secure context.
TEST(PasswordInputTypeTest, DidEditFieldEventNotSentFromSecureContext) {
std::unique_ptr<DummyPageHolder> page_holder =
DummyPageHolder::Create(IntSize(2000, 2000));
MockInsecureInputService mock_service(page_holder->GetFrame());
page_holder->GetDocument().SetURL(KURL("https://example.test"));
page_holder->GetDocument().SetSecurityOrigin(
SecurityOrigin::Create(KURL("https://example.test")));
page_holder->GetDocument().SetSecureContextStateForTesting(
SecureContextState::kSecure);
page_holder->GetDocument().body()->SetInnerHTMLFromString(
"<input type='password'>");
page_holder->GetDocument().View()->UpdateAllLifecyclePhases(
DocumentLifecycle::LifecycleUpdateReason::kTest);
// Simulate a text field edit.
page_holder->GetDocument().MaybeQueueSendDidEditFieldInInsecureContext();
// No message should have been sent from a secure context.
blink::test::RunPendingTasks();
EXPECT_EQ(0u, mock_service.DidEditFieldCalls());
}
} // namespace blink