Home | History | Annotate | Download | only in cocoa
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/scoped_nsobject.h"
      6 #include "base/string_util.h"
      7 #include "base/string_number_conversions.h"
      8 #include "base/sys_string_conversions.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/page_info_model.h"
     11 #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h"
     12 #import "chrome/browser/ui/cocoa/page_info_bubble_controller.h"
     13 #include "chrome/browser/ui/cocoa/browser_test_helper.h"
     14 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
     15 #include "grit/generated_resources.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 
     18 namespace {
     19 
     20 class FakeModel : public PageInfoModel {
     21  public:
     22   FakeModel() : PageInfoModel() {}
     23 
     24   void AddSection(SectionStateIcon icon_id,
     25                   const string16& headline,
     26                   const string16& description,
     27                   SectionInfoType type) {
     28     sections_.push_back(SectionInfo(
     29         icon_id, headline, description, type));
     30   }
     31 };
     32 
     33 class FakeBridge : public PageInfoModel::PageInfoModelObserver {
     34  public:
     35   void ModelChanged() {}
     36 };
     37 
     38 class PageInfoBubbleControllerTest : public CocoaTest {
     39  public:
     40   PageInfoBubbleControllerTest() {
     41     controller_ = nil;
     42     model_ = new FakeModel();
     43   }
     44 
     45   virtual void TearDown() {
     46     [controller_ close];
     47     CocoaTest::TearDown();
     48   }
     49 
     50   void CreateBubble() {
     51     // The controller cleans up after itself when the window closes.
     52     controller_ =
     53         [[PageInfoBubbleController alloc] initWithPageInfoModel:model_
     54                                                   modelObserver:NULL
     55                                                    parentWindow:test_window()];
     56     window_ = [controller_ window];
     57     [controller_ showWindow:nil];
     58   }
     59 
     60   // Checks the controller's window for the requisite subviews in the given
     61   // numbers.
     62   void CheckWindow(int text_count,
     63                    int image_count,
     64                    int spacer_count,
     65                    int button_count) {
     66     // All windows have the help center link and a spacer for it.
     67     int link_count = 1;
     68     ++spacer_count;
     69 
     70     // The window's only immediate child is an invisible view that has a flipped
     71     // coordinate origin. It is into this that all views get placed.
     72     NSArray* windowSubviews = [[window_ contentView] subviews];
     73     EXPECT_EQ(1U, [windowSubviews count]);
     74     NSArray* subviews = [[windowSubviews lastObject] subviews];
     75 
     76     for (NSView* view in subviews) {
     77       if ([view isKindOfClass:[NSTextField class]]) {
     78         --text_count;
     79       } else if ([view isKindOfClass:[NSImageView class]]) {
     80         --image_count;
     81       } else if ([view isKindOfClass:[NSBox class]]) {
     82         --spacer_count;
     83       } else if ([view isKindOfClass:[NSButton class]]) {
     84         NSButton* button = static_cast<NSButton*>(view);
     85         // Every window should have a single link button to the help page.
     86         if ([[button cell] isKindOfClass:[HyperlinkButtonCell class]]) {
     87           --link_count;
     88           CheckButton(button, @selector(showHelpPage:));
     89         } else {
     90           --button_count;
     91           CheckButton(button, @selector(showCertWindow:));
     92         }
     93       } else {
     94         ADD_FAILURE() << "Unknown subview: " << [[view description] UTF8String];
     95       }
     96     }
     97     EXPECT_EQ(0, text_count);
     98     EXPECT_EQ(0, image_count);
     99     EXPECT_EQ(0, spacer_count);
    100     EXPECT_EQ(0, button_count);
    101     EXPECT_EQ(0, link_count);
    102     EXPECT_EQ([window_ delegate], controller_);
    103   }
    104 
    105   // Checks that a button is hooked up correctly.
    106   void CheckButton(NSButton* button, SEL action) {
    107     EXPECT_EQ(action, [button action]);
    108     EXPECT_EQ(controller_, [button target]);
    109     EXPECT_TRUE([button stringValue]);
    110   }
    111 
    112   BrowserTestHelper helper_;
    113 
    114   PageInfoBubbleController* controller_;  // Weak, owns self.
    115   FakeModel* model_;  // Weak, owned by controller.
    116   NSWindow* window_;  // Weak, owned by controller.
    117 };
    118 
    119 
    120 TEST_F(PageInfoBubbleControllerTest, NoHistoryNoSecurity) {
    121   model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
    122       string16(),
    123       l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY),
    124       PageInfoModel::SECTION_INFO_IDENTITY);
    125   model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
    126       string16(),
    127       l10n_util::GetStringFUTF16(
    128           IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
    129           ASCIIToUTF16("google.com")),
    130       PageInfoModel::SECTION_INFO_CONNECTION);
    131 
    132   CreateBubble();
    133   CheckWindow(/*text=*/2, /*image=*/2, /*spacer=*/1, /*button=*/0);
    134 }
    135 
    136 
    137 TEST_F(PageInfoBubbleControllerTest, HistoryNoSecurity) {
    138   model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
    139       string16(),
    140       l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY),
    141       PageInfoModel::SECTION_INFO_IDENTITY);
    142   model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
    143       string16(),
    144       l10n_util::GetStringFUTF16(
    145           IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT,
    146           ASCIIToUTF16("google.com")),
    147       PageInfoModel::SECTION_INFO_CONNECTION);
    148 
    149   // In practice, the history information comes later because it's queried
    150   // asynchronously, so replicate the double-build here.
    151   CreateBubble();
    152 
    153   model_->AddSection(PageInfoModel::ICON_STATE_ERROR,
    154       l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE),
    155       l10n_util::GetStringUTF16(
    156           IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY),
    157       PageInfoModel::SECTION_INFO_FIRST_VISIT);
    158 
    159   [controller_ performLayout];
    160 
    161   CheckWindow(/*text=*/4, /*image=*/3, /*spacer=*/2, /*button=*/0);
    162 }
    163 
    164 
    165 TEST_F(PageInfoBubbleControllerTest, NoHistoryMixedSecurity) {
    166   model_->AddSection(PageInfoModel::ICON_STATE_OK,
    167       string16(),
    168       l10n_util::GetStringFUTF16(
    169           IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY,
    170           ASCIIToUTF16("Goat Security Systems")),
    171       PageInfoModel::SECTION_INFO_IDENTITY);
    172 
    173   // This string is super long and the text should overflow the default clip
    174   // region (kImageSize).
    175   string16 description = l10n_util::GetStringFUTF16(
    176       IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK,
    177       l10n_util::GetStringFUTF16(
    178           IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT,
    179           ASCIIToUTF16("chrome.google.com"),
    180           base::IntToString16(1024)),
    181       l10n_util::GetStringUTF16(
    182           IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING));
    183 
    184   model_->AddSection(PageInfoModel::ICON_STATE_OK,
    185       string16(),
    186       description,
    187       PageInfoModel::SECTION_INFO_CONNECTION);
    188 
    189   CreateBubble();
    190   [controller_ setCertID:1];
    191   [controller_ performLayout];
    192 
    193   CheckWindow(/*text=*/2, /*image=*/2, /*spacer=*/1, /*button=*/1);
    194 
    195   // Look for the over-sized box.
    196   NSString* targetDesc = base::SysUTF16ToNSString(description);
    197   NSArray* subviews = [[window_ contentView] subviews];
    198   for (NSView* subview in subviews) {
    199     if ([subview isKindOfClass:[NSTextField class]]) {
    200       NSTextField* desc = static_cast<NSTextField*>(subview);
    201       if ([[desc stringValue] isEqualToString:targetDesc]) {
    202         // Typical box frame is ~55px, make sure this is extra large.
    203         EXPECT_LT(75, NSHeight([desc frame]));
    204       }
    205     }
    206   }
    207 }
    208 
    209 }  // namespace
    210