blob: 8c583b09ef3d34ed0cd04953a3cc81cf15922269 [file] [log] [blame]
// Copyright (c) 2011 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 "base/compiler_specific.h"
#include "base/memory/scoped_nsobject.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/page_info_model.h"
#include "chrome/browser/page_info_model_observer.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
#import "chrome/browser/ui/cocoa/page_info_bubble_controller.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
class FakeModel : public PageInfoModel {
public:
FakeModel() : PageInfoModel() {}
void AddSection(SectionStateIcon icon_id,
const string16& headline,
const string16& description,
SectionInfoType type) {
sections_.push_back(SectionInfo(
icon_id, headline, description, type));
}
};
class FakeBridge : public PageInfoModelObserver {
public:
virtual void OnPageInfoModelChanged() OVERRIDE {}
};
class PageInfoBubbleControllerTest : public CocoaTest {
public:
PageInfoBubbleControllerTest() {
controller_ = nil;
model_ = new FakeModel();
}
virtual void TearDown() {
[controller_ close];
CocoaTest::TearDown();
}
void CreateBubble() {
// The controller cleans up after itself when the window closes.
controller_ =
[[PageInfoBubbleController alloc]
initWithPageInfoModel:model_
modelObserver:NULL
parentWindow:test_window()
webContents:NULL
navigator:NULL];
window_ = [controller_ window];
[controller_ showWindow:nil];
}
// Checks the controller's window for the requisite subviews in the given
// numbers.
void CheckWindow(int text_count,
int image_count,
int spacer_count,
int button_count) {
// All windows have the help center link and a spacer for it.
int link_count = 1;
++spacer_count;
// The window's only immediate child is an invisible view that has a flipped
// coordinate origin. It is into this that all views get placed.
NSArray* windowSubviews = [[window_ contentView] subviews];
EXPECT_EQ(1U, [windowSubviews count]);
NSArray* subviews = [[windowSubviews lastObject] subviews];
for (NSView* view in subviews) {
if ([view isKindOfClass:[NSTextField class]]) {
--text_count;
} else if ([view isKindOfClass:[NSImageView class]]) {
--image_count;
} else if ([view isKindOfClass:[NSBox class]]) {
--spacer_count;
} else if ([view isKindOfClass:[NSButton class]]) {
NSButton* button = static_cast<NSButton*>(view);
// Every window should have a single link button to the help page.
if ([[button cell] isKindOfClass:[HyperlinkButtonCell class]]) {
--link_count;
CheckButton(button, @selector(showHelpPage:));
} else {
--button_count;
CheckButton(button, @selector(showCertWindow:));
}
} else {
ADD_FAILURE() << "Unknown subview: " << [[view description] UTF8String];
}
}
EXPECT_EQ(0, text_count);
EXPECT_EQ(0, image_count);
EXPECT_EQ(0, spacer_count);
EXPECT_EQ(0, button_count);
EXPECT_EQ(0, link_count);
EXPECT_EQ([window_ delegate], controller_);
}
// Checks that a button is hooked up correctly.
void CheckButton(NSButton* button, SEL action) {
EXPECT_EQ(action, [button action]);
EXPECT_EQ(controller_, [button target]);
EXPECT_TRUE([button stringValue]);
}
PageInfoBubbleController* controller_; // Weak, owns self.
FakeModel* model_; // Weak, owned by controller.
NSWindow* window_; // Weak, owned by controller.
};
TEST_F(PageInfoBubbleControllerTest, NoHistoryNoSecurity) {
model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
string16(),
l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY),
PageInfoModel::SECTION_INFO_IDENTITY);
model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
string16(),
l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
ASCIIToUTF16("google.com")),
PageInfoModel::SECTION_INFO_CONNECTION);
CreateBubble();
CheckWindow(/*text=*/2, /*image=*/2, /*spacer=*/1, /*button=*/0);
}
TEST_F(PageInfoBubbleControllerTest, HistoryNoSecurity) {
model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
string16(),
l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY),
PageInfoModel::SECTION_INFO_IDENTITY);
model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
string16(),
l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
ASCIIToUTF16("google.com")),
PageInfoModel::SECTION_INFO_CONNECTION);
// In practice, the history information comes later because it's queried
// asynchronously, so replicate the double-build here.
CreateBubble();
model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE),
l10n_util::GetStringUTF16(
IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY),
PageInfoModel::SECTION_INFO_FIRST_VISIT);
[controller_ performLayout];
CheckWindow(/*text=*/4, /*image=*/3, /*spacer=*/2, /*button=*/0);
}
TEST_F(PageInfoBubbleControllerTest, NoHistoryMixedSecurity) {
model_->AddSection(PageInfoModel::ICON_STATE_OK,
string16(),
l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY,
ASCIIToUTF16("Goat Security Systems")),
PageInfoModel::SECTION_INFO_IDENTITY);
// This string is super long and the text should overflow the default clip
// region (kImageSize).
string16 description = l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK,
l10n_util::GetStringFUTF16(
IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT,
ASCIIToUTF16("chrome.google.com"),
base::IntToString16(1024)),
l10n_util::GetStringUTF16(
IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING));
model_->AddSection(PageInfoModel::ICON_STATE_OK,
string16(),
description,
PageInfoModel::SECTION_INFO_CONNECTION);
CreateBubble();
[controller_ setCertID:1];
[controller_ performLayout];
CheckWindow(/*text=*/2, /*image=*/2, /*spacer=*/1, /*button=*/1);
// Look for the over-sized box.
NSString* targetDesc = base::SysUTF16ToNSString(description);
NSArray* subviews = [[window_ contentView] subviews];
for (NSView* subview in subviews) {
if ([subview isKindOfClass:[NSTextField class]]) {
NSTextField* desc = static_cast<NSTextField*>(subview);
if ([[desc stringValue] isEqualToString:targetDesc]) {
// Typical box frame is ~55px, make sure this is extra large.
EXPECT_LT(75, NSHeight([desc frame]));
}
}
}
}
} // namespace