1// Copyright 2013 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/basictypes.h"
6#include "base/compiler_specific.h"
7#include "base/logging.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/prefs/pref_service.h"
10#include "base/strings/string16.h"
11#include "base/strings/utf_string_conversions.h"
12#include "chrome/browser/ui/autofill/generated_credit_card_bubble_controller.h"
13#include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_controller.h"
14#include "chrome/browser/ui/autofill/test_generated_credit_card_bubble_view.h"
15#include "chrome/common/pref_names.h"
16#include "chrome/test/base/testing_profile.h"
17#include "components/autofill/core/browser/autofill_test_utils.h"
18#include "content/public/browser/web_contents.h"
19#include "content/public/test/test_browser_thread_bundle.h"
20#include "content/public/test/web_contents_tester.h"
21#include "testing/gtest/include/gtest/gtest.h"
22#include "ui/base/page_transition_types.h"
23#include "ui/gfx/range/range.h"
24
25#if defined(OS_WIN)
26#include "ui/base/win/scoped_ole_initializer.h"
27#endif
28
29namespace autofill {
30
31namespace {
32
33base::string16 BackingCard() {
34  return base::ASCIIToUTF16("Visa - 1111");
35}
36
37base::string16 FrontingCard() {
38  return base::ASCIIToUTF16("Mastercard - 4444");
39}
40
41base::string16 RangeOfString(const base::string16& string,
42                             const gfx::Range& range) {
43  return string.substr(range.start(), range.end() - range.start());
44}
45
46class GeneratedCreditCardBubbleControllerTest : public testing::Test {
47 public:
48  GeneratedCreditCardBubbleControllerTest()
49      : test_web_contents_(
50            content::WebContentsTester::CreateTestWebContents(
51                &profile_, NULL)) {}
52
53  virtual void SetUp() OVERRIDE {
54    // Attaches immediately to |test_web_contents_| so a test version will exist
55    // before a non-test version can be created.
56    new TestGeneratedCreditCardBubbleController(test_web_contents_.get());
57    ASSERT_TRUE(controller()->IsInstalled());
58  }
59
60 protected:
61  TestGeneratedCreditCardBubbleController* controller() {
62    return static_cast<TestGeneratedCreditCardBubbleController*>(
63        TestGeneratedCreditCardBubbleController::FromWebContents(
64            test_web_contents_.get()));
65  }
66
67  int GeneratedCardBubbleTimesShown() {
68    return profile_.GetPrefs()->GetInteger(
69        ::prefs::kAutofillGeneratedCardBubbleTimesShown);
70  }
71
72  void Show() {
73    ASSERT_TRUE(controller()->IsInstalled());
74    TestGeneratedCreditCardBubbleController::Show(test_web_contents_.get(),
75                                                  FrontingCard(),
76                                                  BackingCard());
77  }
78
79  void NavigateWithTransition(ui::PageTransition trans) {
80    content::WebContentsTester::For(test_web_contents_.get())->TestDidNavigate(
81        test_web_contents_->GetMainFrame(), 1, GURL("about:blank"), trans);
82  }
83
84 private:
85  content::TestBrowserThreadBundle thread_bundle_;
86#if defined(OS_WIN)
87  // Without this there will be drag and drop failures. http://crbug.com/227221
88  ui::ScopedOleInitializer ole_initializer_;
89#endif
90  TestingProfile profile_;
91  scoped_ptr<content::WebContents> test_web_contents_;
92};
93
94}  // namespace
95
96TEST_F(GeneratedCreditCardBubbleControllerTest, GeneratedCardBubbleTimesShown) {
97  ASSERT_EQ(0, GeneratedCardBubbleTimesShown());
98
99  // Ensure that showing the generated card UI bumps the persistent count.
100  Show();
101  EXPECT_EQ(1, GeneratedCardBubbleTimesShown());
102  EXPECT_TRUE(controller()->GetTestingBubble()->showing());
103
104  Show();
105  Show();
106  EXPECT_EQ(3, GeneratedCardBubbleTimesShown());
107  EXPECT_TRUE(controller()->GetTestingBubble()->showing());
108}
109
110TEST_F(GeneratedCreditCardBubbleControllerTest, TitleText) {
111  Show();
112  EXPECT_FALSE(controller()->TitleText().empty());
113}
114
115TEST_F(GeneratedCreditCardBubbleControllerTest, ContentsText) {
116  // Ensure that while showing the generated card UI that the bubble's text
117  // contains "Visa - 1111" and "Mastercard - 4444".
118  Show();
119  base::string16 contents_text = controller()->ContentsText();
120  EXPECT_NE(base::string16::npos, contents_text.find(BackingCard()));
121  EXPECT_NE(base::string16::npos, contents_text.find(FrontingCard()));
122
123  // Make sure that |bubble_text_| is regenerated the same way in |Setup()|.
124  Show();
125  EXPECT_EQ(contents_text, controller()->ContentsText());
126}
127
128TEST_F(GeneratedCreditCardBubbleControllerTest, ContentsTextRanges) {
129  // Check that the highlighted ranges in the bubble's text are correct.
130  Show();
131  const base::string16& contents_text = controller()->ContentsText();
132  const std::vector<TextRange>& ranges = controller()->ContentsTextRanges();
133
134  ASSERT_EQ(3U, ranges.size());
135
136  EXPECT_EQ(FrontingCard(), RangeOfString(contents_text, ranges[0].range));
137  EXPECT_FALSE(ranges[0].is_link);
138
139  EXPECT_EQ(BackingCard(), RangeOfString(contents_text, ranges[1].range));
140  EXPECT_FALSE(ranges[1].is_link);
141
142  EXPECT_TRUE(ranges[2].is_link);
143
144  Show();
145  EXPECT_EQ(ranges, controller()->ContentsTextRanges());
146}
147
148TEST_F(GeneratedCreditCardBubbleControllerTest, AnchorIcon) {
149  Show();
150  EXPECT_FALSE(controller()->AnchorIcon().IsEmpty());
151}
152
153TEST_F(GeneratedCreditCardBubbleControllerTest, HideOnLinkClick) {
154  EXPECT_FALSE(controller()->GetTestingBubble());
155  Show();
156  EXPECT_TRUE(controller()->GetTestingBubble()->showing());
157
158  // However, if the user clicks a link the bubble should hide.
159  NavigateWithTransition(ui::PAGE_TRANSITION_LINK);
160  EXPECT_FALSE(controller());
161}
162
163TEST_F(GeneratedCreditCardBubbleControllerTest, StayOnSomeNavigations) {
164  EXPECT_FALSE(controller()->GetTestingBubble());
165  Show();
166  EXPECT_TRUE(controller()->GetTestingBubble()->showing());
167
168  // If the user reloads or the page redirects or submits a form, the bubble
169  // should stay showing.
170  NavigateWithTransition(ui::PAGE_TRANSITION_CLIENT_REDIRECT);
171  NavigateWithTransition(ui::PAGE_TRANSITION_FORM_SUBMIT);
172  NavigateWithTransition(ui::PAGE_TRANSITION_RELOAD);
173  EXPECT_TRUE(controller()->GetTestingBubble()->showing());
174}
175
176}  // namespace autofill
177