blob: e79ce0fa76866f9970a6c9e92ac2236fcebac085 [file] [log] [blame]
// Copyright 2015 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 "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/permissions/permission_uma_util.h"
#include "chrome/browser/ssl/security_state_tab_helper.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/hover_button.h"
#include "chrome/browser/ui/views/page_info/chosen_object_view.h"
#include "chrome/browser/ui/views/page_info/permission_selector_row.h"
#include "chrome/browser/usb/usb_chooser_context.h"
#include "chrome/browser/usb/usb_chooser_context_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/history/core/browser/history_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/test/browser_side_navigation_test_utils.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_web_contents_factory.h"
#include "net/ssl/ssl_connection_status_flags.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/device/public/cpp/test/fake_usb_device_manager.h"
#include "services/device/public/mojom/usb_device.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/event_utils.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
#include "ui/views/test/scoped_views_test_helper.h"
#include "ui/views/test/test_views_delegate.h"
#if BUILDFLAG(ENABLE_PLUGINS)
#include "chrome/browser/plugins/chrome_plugin_service_filter.h"
#endif
const char* kUrl = "http://www.example.com/index.html";
const char* kSecureUrl = "https://www.example.com/index.html";
namespace test {
class PageInfoBubbleViewTestApi {
public:
PageInfoBubbleViewTestApi(gfx::NativeView parent,
Profile* profile,
content::WebContents* web_contents)
: view_(nullptr),
parent_(parent),
profile_(profile),
web_contents_(web_contents) {
CreateView();
}
void CreateView() {
if (view_) {
view_->GetWidget()->CloseNow();
}
views::View* anchor_view = nullptr;
view_ = new PageInfoBubbleView(
anchor_view, gfx::Rect(), parent_, profile_, web_contents_, GURL(kUrl),
security_state::NONE, security_state::VisibleSecurityState(),
base::BindOnce(&PageInfoBubbleViewTestApi::OnPageInfoBubbleClosed,
base::Unretained(this), run_loop_.QuitClosure()));
}
PageInfoBubbleView* view() { return view_; }
views::View* permissions_view() { return view_->permissions_view_; }
bool reload_prompt() const { return *reload_prompt_; }
views::Widget::ClosedReason closed_reason() const { return *closed_reason_; }
base::string16 GetWindowTitle() { return view_->GetWindowTitle(); }
PermissionSelectorRow* GetPermissionSelectorAt(int index) {
return view_->selector_rows_[index].get();
}
// Returns the number of cookies shown on the link or button to open the
// collected cookies dialog. This should always be shown.
base::string16 GetCookiesLinkText() {
EXPECT_TRUE(view_->cookie_button_);
ui::AXNodeData data;
view_->cookie_button_->GetAccessibleNodeData(&data);
std::string name;
data.GetStringAttribute(ax::mojom::StringAttribute::kName, &name);
return base::ASCIIToUTF16(name);
}
base::string16 GetPermissionLabelTextAt(int index) {
return GetPermissionSelectorAt(index)->label_->GetText();
}
base::string16 GetPermissionComboboxTextAt(int index) {
auto* combobox = GetPermissionSelectorAt(index)->combobox_;
return combobox->GetTextForRow(combobox->GetSelectedRow());
}
void SimulateUserSelectingComboboxItemAt(int selector_index, int menu_index) {
auto* combobox = GetPermissionSelectorAt(selector_index)->combobox_;
combobox->SetSelectedRow(menu_index);
}
// Simulates updating the number of cookies.
void SetCookieInfo(const CookieInfoList& list) { view_->SetCookieInfo(list); }
// Simulates recreating the dialog with a new PermissionInfoList.
void SetPermissionInfo(const PermissionInfoList& list) {
for (const PageInfoBubbleView::PermissionInfo& info : list) {
view_->presenter_->OnSitePermissionChanged(info.type, info.setting);
}
CreateView();
}
void WaitForBubbleClose() { run_loop_.Run(); }
private:
void OnPageInfoBubbleClosed(base::RepeatingCallback<void()> quit_closure,
views::Widget::ClosedReason closed_reason,
bool reload_prompt) {
closed_reason_ = closed_reason;
reload_prompt_ = reload_prompt;
quit_closure.Run();
}
PageInfoBubbleView* view_; // Weak. Owned by its Widget.
// For recreating the view.
gfx::NativeView parent_;
Profile* profile_;
content::WebContents* web_contents_;
base::RunLoop run_loop_;
base::Optional<bool> reload_prompt_;
base::Optional<views::Widget::ClosedReason> closed_reason_;
DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleViewTestApi);
};
} // namespace test
namespace {
// Helper class that wraps a TestingProfile and a TestWebContents for a test
// harness. Inspired by RenderViewHostTestHarness, but doesn't use inheritance
// so the helper can be composed with other helpers in the test harness.
class ScopedWebContentsTestHelper {
public:
ScopedWebContentsTestHelper() {
web_contents_ = factory_.CreateWebContents(&profile_);
}
Profile* profile() { return &profile_; }
content::WebContents* web_contents() { return web_contents_; }
private:
content::TestBrowserThreadBundle thread_bundle_;
TestingProfile profile_;
content::TestWebContentsFactory factory_;
content::WebContents* web_contents_; // Weak. Owned by factory_.
DISALLOW_COPY_AND_ASSIGN(ScopedWebContentsTestHelper);
};
class PageInfoBubbleViewTest : public testing::Test {
public:
PageInfoBubbleViewTest() {}
// testing::Test:
void SetUp() override {
views_helper_.test_views_delegate()->set_layout_provider(
ChromeLayoutProvider::CreateLayoutProvider());
views::Widget::InitParams parent_params;
parent_params.context = views_helper_.GetContext();
parent_window_ = new views::Widget();
parent_window_->Init(parent_params);
content::WebContents* web_contents = web_contents_helper_.web_contents();
TabSpecificContentSettings::CreateForWebContents(web_contents);
api_.reset(new test::PageInfoBubbleViewTestApi(
parent_window_->GetNativeView(), web_contents_helper_.profile(),
web_contents));
}
void TearDown() override { parent_window_->CloseNow(); }
protected:
ScopedWebContentsTestHelper web_contents_helper_;
views::ScopedViewsTestHelper views_helper_;
views::Widget* parent_window_ = nullptr; // Weak. Owned by the NativeWidget.
std::unique_ptr<test::PageInfoBubbleViewTestApi> api_;
private:
DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleViewTest);
};
#if BUILDFLAG(ENABLE_PLUGINS)
// Waits until a change is observed in content settings.
class FlashContentSettingsChangeWaiter : public content_settings::Observer {
public:
explicit FlashContentSettingsChangeWaiter(Profile* profile)
: profile_(profile) {
HostContentSettingsMapFactory::GetForProfile(profile)->AddObserver(this);
}
~FlashContentSettingsChangeWaiter() override {
HostContentSettingsMapFactory::GetForProfile(profile_)->RemoveObserver(
this);
}
// content_settings::Observer:
void OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
const ContentSettingsPattern& secondary_pattern,
ContentSettingsType content_type,
const std::string& resource_identifier) override {
if (content_type == CONTENT_SETTINGS_TYPE_PLUGINS)
Proceed();
}
void Wait() { run_loop_.Run(); }
private:
void Proceed() { run_loop_.Quit(); }
Profile* profile_;
base::RunLoop run_loop_;
DISALLOW_COPY_AND_ASSIGN(FlashContentSettingsChangeWaiter);
};
#endif
} // namespace
// Each permission selector row is like this: [icon] [label] [selector]
constexpr size_t kViewsPerPermissionRow = 3;
TEST_F(PageInfoBubbleViewTest, NotificationPermissionRevokeUkm) {
GURL origin_url = GURL(kUrl).GetOrigin();
TestingProfile* profile =
static_cast<TestingProfile*>(web_contents_helper_.profile());
ukm::TestAutoSetUkmRecorder ukm_recorder;
ASSERT_TRUE(profile->CreateHistoryService(
/* delete_file= */ true,
/* no_db= */ false));
auto* history_service = HistoryServiceFactory::GetForProfile(
profile, ServiceAccessType::EXPLICIT_ACCESS);
history_service->AddPage(origin_url, base::Time::Now(),
history::SOURCE_BROWSED);
base::RunLoop origin_queried_waiter;
history_service->set_origin_queried_closure_for_testing(
origin_queried_waiter.QuitClosure());
PermissionInfoList list(1);
list.back().type = CONTENT_SETTINGS_TYPE_NOTIFICATIONS;
list.back().source = content_settings::SETTING_SOURCE_USER;
list.back().is_incognito = false;
list.back().setting = CONTENT_SETTING_ALLOW;
api_->SetPermissionInfo(list);
list.back().setting = CONTENT_SETTING_BLOCK;
api_->SetPermissionInfo(list);
origin_queried_waiter.Run();
auto entries = ukm_recorder.GetEntriesByName("Permission");
EXPECT_EQ(1u, entries.size());
auto* entry = entries.front();
ukm_recorder.ExpectEntrySourceHasUrl(entry, origin_url);
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Source"),
static_cast<int64_t>(PermissionSourceUI::OIB));
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "PermissionType"),
static_cast<int64_t>(
ContentSettingsType::CONTENT_SETTINGS_TYPE_NOTIFICATIONS));
EXPECT_EQ(*ukm_recorder.GetEntryMetric(entry, "Action"),
static_cast<int64_t>(PermissionAction::REVOKED));
}
// Test UI construction and reconstruction via
// PageInfoBubbleView::SetPermissionInfo().
TEST_F(PageInfoBubbleViewTest, SetPermissionInfo) {
// This test exercises PermissionSelectorRow in a way that it is not used in
// practice. In practice, every setting in PermissionSelectorRow starts off
// "set", so there is always one option checked in the resulting MenuModel.
// This test creates settings that are left at their defaults, leading to zero
// checked options, and checks that the text on the MenuButtons is right.
TestingProfile* profile =
static_cast<TestingProfile*>(web_contents_helper_.profile());
ASSERT_TRUE(profile->CreateHistoryService(
/* delete_file= */ true,
/* no_db= */ false));
PermissionInfoList list(1);
list.back().type = CONTENT_SETTINGS_TYPE_GEOLOCATION;
list.back().source = content_settings::SETTING_SOURCE_USER;
list.back().is_incognito = false;
list.back().setting = CONTENT_SETTING_BLOCK;
// Initially, no permissions are shown because they are all set to default.
size_t num_expected_children = 0;
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
num_expected_children += kViewsPerPermissionRow * list.size();
list.back().setting = CONTENT_SETTING_ALLOW;
api_->SetPermissionInfo(list);
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
PermissionSelectorRow* selector = api_->GetPermissionSelectorAt(0);
EXPECT_TRUE(selector);
// Verify labels match the settings on the PermissionInfoList.
EXPECT_EQ(base::ASCIIToUTF16("Location"), api_->GetPermissionLabelTextAt(0));
EXPECT_EQ(base::ASCIIToUTF16("Allow"), api_->GetPermissionComboboxTextAt(0));
// Verify calling SetPermissionInfo() directly updates the UI.
list.back().setting = CONTENT_SETTING_BLOCK;
api_->SetPermissionInfo(list);
EXPECT_EQ(base::ASCIIToUTF16("Block"), api_->GetPermissionComboboxTextAt(0));
// Simulate a user selection via the UI. Note this will also cover logic in
// PageInfo to update the pref.
api_->SimulateUserSelectingComboboxItemAt(0, 1);
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
EXPECT_EQ(base::ASCIIToUTF16("Allow"), api_->GetPermissionComboboxTextAt(0));
// Setting to the default via the UI should keep the button around.
api_->SimulateUserSelectingComboboxItemAt(0, 0);
EXPECT_EQ(base::ASCIIToUTF16("Ask (default)"),
api_->GetPermissionComboboxTextAt(0));
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
// However, since the setting is now default, recreating the dialog with those
// settings should omit the permission from the UI.
//
// TODO(https://crbug.com/829576): Reconcile the comment above with the fact
// that |num_expected_children| is not, at this point, 0 and therefore the
// permission is not being omitted from the UI.
api_->SetPermissionInfo(list);
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
}
// Test UI construction and reconstruction with USB devices.
TEST_F(PageInfoBubbleViewTest, SetPermissionInfoWithUsbDevice) {
constexpr size_t kExpectedChildren = 0;
EXPECT_EQ(kExpectedChildren, api_->permissions_view()->children().size());
const auto origin = url::Origin::Create(GURL(kUrl));
// Connect the UsbChooserContext with FakeUsbDeviceManager.
device::FakeUsbDeviceManager usb_device_manager;
device::mojom::UsbDeviceManagerPtr device_manager_ptr;
usb_device_manager.AddBinding(mojo::MakeRequest(&device_manager_ptr));
UsbChooserContext* store =
UsbChooserContextFactory::GetForProfile(web_contents_helper_.profile());
store->SetDeviceManagerForTesting(std::move(device_manager_ptr));
auto device_info = usb_device_manager.CreateAndAddDevice(
0, 0, "Google", "Gizmo", "1234567890");
store->GrantDevicePermission(origin, origin, *device_info);
PermissionInfoList list;
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren + 1, api_->permissions_view()->children().size());
ChosenObjectView* object_view = static_cast<ChosenObjectView*>(
api_->permissions_view()->children()[kExpectedChildren]);
const auto& children = object_view->children();
EXPECT_EQ(4u, children.size());
views::Label* label = static_cast<views::Label*>(children[1]);
EXPECT_EQ(base::ASCIIToUTF16("Gizmo"), label->GetText());
views::Button* button = static_cast<views::Button*>(children[2]);
const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
static_cast<views::ButtonListener*>(object_view)
->ButtonPressed(button, event);
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren, api_->permissions_view()->children().size());
EXPECT_FALSE(store->HasDevicePermission(origin, origin, *device_info));
}
namespace {
constexpr char kPolicySetting[] = R"(
[
{
"devices": [{ "vendor_id": 6353, "product_id": 5678 }],
"urls": ["http://www.example.com"]
}
])";
} // namespace
// Test UI construction and reconstruction with policy USB devices.
TEST_F(PageInfoBubbleViewTest, SetPermissionInfoWithPolicyUsbDevices) {
constexpr size_t kExpectedChildren = 0;
EXPECT_EQ(kExpectedChildren, api_->permissions_view()->children().size());
const auto origin = url::Origin::Create(GURL(kUrl));
// Add the policy setting to prefs.
Profile* profile = web_contents_helper_.profile();
profile->GetPrefs()->Set(prefs::kManagedWebUsbAllowDevicesForUrls,
*base::JSONReader::ReadDeprecated(kPolicySetting));
UsbChooserContext* store = UsbChooserContextFactory::GetForProfile(profile);
auto objects = store->GetGrantedObjects(origin, origin);
EXPECT_EQ(objects.size(), 1u);
PermissionInfoList list;
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren + 1, api_->permissions_view()->children().size());
ChosenObjectView* object_view = static_cast<ChosenObjectView*>(
api_->permissions_view()->children()[kExpectedChildren]);
const auto& children = object_view->children();
EXPECT_EQ(4u, children.size());
views::Label* label = static_cast<views::Label*>(children[1]);
EXPECT_EQ(base::ASCIIToUTF16("Unknown product 0x162E from Google Inc."),
label->GetText());
views::Button* button = static_cast<views::Button*>(children[2]);
EXPECT_EQ(button->state(), views::Button::STATE_DISABLED);
views::Label* desc_label = static_cast<views::Label*>(children[3]);
EXPECT_EQ(base::ASCIIToUTF16("USB device allowed by your administrator"),
desc_label->GetText());
// Policy granted USB permissions should not be able to be deleted.
const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
views::ButtonListener* button_listener =
static_cast<views::ButtonListener*>(object_view);
button_listener->ButtonPressed(button, event);
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren + 1, api_->permissions_view()->children().size());
}
// Test UI construction and reconstruction with both user and policy USB
// devices.
TEST_F(PageInfoBubbleViewTest, SetPermissionInfoWithUserAndPolicyUsbDevices) {
constexpr size_t kExpectedChildren = 0;
EXPECT_EQ(kExpectedChildren, api_->permissions_view()->children().size());
const auto origin = url::Origin::Create(GURL(kUrl));
// Add the policy setting to prefs.
Profile* profile = web_contents_helper_.profile();
profile->GetPrefs()->Set(prefs::kManagedWebUsbAllowDevicesForUrls,
*base::JSONReader::ReadDeprecated(kPolicySetting));
// Connect the UsbChooserContext with FakeUsbDeviceManager.
device::FakeUsbDeviceManager usb_device_manager;
device::mojom::UsbDeviceManagerPtr device_manager_ptr;
usb_device_manager.AddBinding(mojo::MakeRequest(&device_manager_ptr));
UsbChooserContext* store = UsbChooserContextFactory::GetForProfile(profile);
store->SetDeviceManagerForTesting(std::move(device_manager_ptr));
auto device_info = usb_device_manager.CreateAndAddDevice(
0, 0, "Google", "Gizmo", "1234567890");
store->GrantDevicePermission(origin, origin, *device_info);
auto objects = store->GetGrantedObjects(origin, origin);
EXPECT_EQ(objects.size(), 2u);
PermissionInfoList list;
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren + 2, api_->permissions_view()->children().size());
const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
// The first object is the user granted permission for the "Gizmo" device.
{
ChosenObjectView* object_view = static_cast<ChosenObjectView*>(
api_->permissions_view()->children()[kExpectedChildren]);
const auto& children = object_view->children();
EXPECT_EQ(4u, children.size());
views::Label* label = static_cast<views::Label*>(children[1]);
EXPECT_EQ(base::ASCIIToUTF16("Gizmo"), label->GetText());
views::Button* button = static_cast<views::Button*>(children[2]);
EXPECT_NE(button->state(), views::Button::STATE_DISABLED);
views::Label* desc_label = static_cast<views::Label*>(children[3]);
EXPECT_EQ(base::ASCIIToUTF16("USB device"), desc_label->GetText());
views::ButtonListener* button_listener =
static_cast<views::ButtonListener*>(object_view);
button_listener->ButtonPressed(button, event);
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren + 1,
api_->permissions_view()->children().size());
EXPECT_FALSE(store->HasDevicePermission(origin, origin, *device_info));
}
// The policy granted permission should now be the first child, since the user
// permission was deleted.
{
ChosenObjectView* object_view = static_cast<ChosenObjectView*>(
api_->permissions_view()->children()[kExpectedChildren]);
const auto& children = object_view->children();
EXPECT_EQ(4u, children.size());
views::Label* label = static_cast<views::Label*>(children[1]);
EXPECT_EQ(base::ASCIIToUTF16("Unknown product 0x162E from Google Inc."),
label->GetText());
views::Button* button = static_cast<views::Button*>(children[2]);
EXPECT_EQ(button->state(), views::Button::STATE_DISABLED);
views::Label* desc_label = static_cast<views::Label*>(children[3]);
EXPECT_EQ(base::ASCIIToUTF16("USB device allowed by your administrator"),
desc_label->GetText());
views::ButtonListener* button_listener =
static_cast<views::ButtonListener*>(object_view);
button_listener->ButtonPressed(button, event);
api_->SetPermissionInfo(list);
EXPECT_EQ(kExpectedChildren + 1,
api_->permissions_view()->children().size());
}
}
TEST_F(PageInfoBubbleViewTest, SetPermissionInfoForUsbGuard) {
// This test exercises PermissionSelectorRow in a way that it is not used in
// practice. In practice, every setting in PermissionSelectorRow starts off
// "set", so there is always one option checked in the resulting MenuModel.
// This test creates settings that are left at their defaults, leading to zero
// checked options, and checks that the text on the MenuButtons is right.
PermissionInfoList list(1);
list.back().type = CONTENT_SETTINGS_TYPE_USB_GUARD;
list.back().source = content_settings::SETTING_SOURCE_USER;
list.back().is_incognito = false;
list.back().setting = CONTENT_SETTING_ASK;
// Initially, no permissions are shown because they are all set to default.
size_t num_expected_children = 0;
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
// Verify calling SetPermissionInfo() directly updates the UI.
num_expected_children += kViewsPerPermissionRow * list.size();
list.back().setting = CONTENT_SETTING_BLOCK;
api_->SetPermissionInfo(list);
EXPECT_EQ(base::ASCIIToUTF16("Block"), api_->GetPermissionComboboxTextAt(0));
// Simulate a user selection via the UI. Note this will also cover logic in
// PageInfo to update the pref.
api_->SimulateUserSelectingComboboxItemAt(0, 2);
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
EXPECT_EQ(base::ASCIIToUTF16("Ask"), api_->GetPermissionComboboxTextAt(0));
// Setting to the default via the UI should keep the button around.
api_->SimulateUserSelectingComboboxItemAt(0, 0);
EXPECT_EQ(base::ASCIIToUTF16("Ask (default)"),
api_->GetPermissionComboboxTextAt(0));
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
// However, since the setting is now default, recreating the dialog with
// those settings should omit the permission from the UI.
//
// TODO(https://crbug.com/829576): Reconcile the comment above with the fact
// that |num_expected_children| is not, at this point, 0 and therefore the
// permission is not being omitted from the UI.
api_->SetPermissionInfo(list);
EXPECT_EQ(num_expected_children, api_->permissions_view()->children().size());
}
// Test that updating the number of cookies used by the current page doesn't add
// any extra views to Page Info.
TEST_F(PageInfoBubbleViewTest, UpdatingSiteDataRetainsLayout) {
#if defined(OS_WIN) && BUILDFLAG(ENABLE_VR)
constexpr size_t kExpectedChildren = 6;
#else
constexpr size_t kExpectedChildren = 5;
#endif
EXPECT_EQ(kExpectedChildren, api_->view()->children().size());
// Create a fake list of cookies.
PageInfoUI::CookieInfo first_party_cookies;
first_party_cookies.allowed = 10;
first_party_cookies.blocked = 0;
first_party_cookies.is_first_party = true;
PageInfoUI::CookieInfo third_party_cookies;
third_party_cookies.allowed = 6;
third_party_cookies.blocked = 32;
third_party_cookies.is_first_party = false;
const CookieInfoList cookies = {first_party_cookies, third_party_cookies};
// Update the number of cookies.
api_->SetCookieInfo(cookies);
EXPECT_EQ(kExpectedChildren, api_->view()->children().size());
// Check the number of cookies shown is correct.
base::string16 expected = l10n_util::GetPluralStringFUTF16(
IDS_PAGE_INFO_NUM_COOKIES_PARENTHESIZED,
first_party_cookies.allowed + third_party_cookies.allowed);
size_t index = api_->GetCookiesLinkText().find(expected);
EXPECT_NE(std::string::npos, index);
}
#if BUILDFLAG(ENABLE_PLUGINS)
TEST_F(PageInfoBubbleViewTest, ChangingFlashSettingForSiteIsRemembered) {
Profile* profile = web_contents_helper_.profile();
ChromePluginServiceFilter::GetInstance()->RegisterResourceContext(
profile, profile->GetResourceContext());
FlashContentSettingsChangeWaiter waiter(profile);
const GURL url(kUrl);
HostContentSettingsMap* map =
HostContentSettingsMapFactory::GetForProfile(profile);
// Make sure the site being tested doesn't already have this marker set.
EXPECT_EQ(nullptr,
map->GetWebsiteSetting(url, url, CONTENT_SETTINGS_TYPE_PLUGINS_DATA,
std::string(), nullptr));
EXPECT_EQ(0u, api_->permissions_view()->children().size());
// Change the Flash setting.
map->SetContentSettingDefaultScope(url, url, CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(), CONTENT_SETTING_ALLOW);
waiter.Wait();
// Check that this site has now been marked for displaying Flash always.
EXPECT_NE(nullptr,
map->GetWebsiteSetting(url, url, CONTENT_SETTINGS_TYPE_PLUGINS_DATA,
std::string(), nullptr));
// Check the Flash permission is now showing since it's non-default.
api_->CreateView();
const auto& children = api_->permissions_view()->children();
views::Label* label = static_cast<views::Label*>(children[1]);
EXPECT_EQ(base::ASCIIToUTF16("Flash"), label->GetText());
// Change the Flash setting back to the default.
map->SetContentSettingDefaultScope(url, url, CONTENT_SETTINGS_TYPE_PLUGINS,
std::string(), CONTENT_SETTING_DEFAULT);
EXPECT_EQ(kViewsPerPermissionRow, children.size());
// Check the Flash permission is still showing since the user changed it
// previously.
label = static_cast<views::Label*>(children[1]);
EXPECT_EQ(base::ASCIIToUTF16("Flash"), label->GetText());
}
#endif
// Tests opening the bubble between navigation start and finish. The bubble
// should be updated to reflect the secure state after the navigation commits.
TEST_F(PageInfoBubbleViewTest, OpenPageInfoBubbleAfterNavigationStart) {
content::BrowserSideNavigationSetUp();
SecurityStateTabHelper::CreateForWebContents(
web_contents_helper_.web_contents());
std::unique_ptr<content::NavigationSimulator> navigation =
content::NavigationSimulator::CreateRendererInitiated(
GURL(kSecureUrl),
web_contents_helper_.web_contents()->GetMainFrame());
navigation->Start();
api_->CreateView();
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_NOT_SECURE_SUMMARY),
api_->GetWindowTitle());
// Set up a test SSLInfo so that Page Info sees the connection as secure.
uint16_t cipher_suite = 0xc02f; // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
int connection_status = 0;
net::SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status);
net::SSLConnectionStatusSetVersion(net::SSL_CONNECTION_VERSION_TLS1_2,
&connection_status);
net::SSLInfo ssl_info;
ssl_info.connection_status = connection_status;
ssl_info.cert =
net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
ASSERT_TRUE(ssl_info.cert);
navigation->SetSSLInfo(ssl_info);
navigation->Commit();
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURE_SUMMARY),
api_->GetWindowTitle());
}
TEST_F(PageInfoBubbleViewTest, EnsureCloseCallback) {
api_->view()->GetWidget()->CloseWithReason(
views::Widget::ClosedReason::kCloseButtonClicked);
api_->WaitForBubbleClose();
EXPECT_EQ(false, api_->reload_prompt());
EXPECT_EQ(views::Widget::ClosedReason::kCloseButtonClicked,
api_->closed_reason());
}