1 // Copyright (c) 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.
5 #import "chrome/browser/ui/cocoa/autofill/autofill_section_container.h"
7 #include "base/mac/foundation_util.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
11 #include "chrome/browser/ui/autofill/mock_autofill_dialog_view_delegate.h"
12 #import "chrome/browser/ui/cocoa/autofill/autofill_input_field.h"
13 #import "chrome/browser/ui/cocoa/autofill/layout_view.h"
14 #import "chrome/browser/ui/cocoa/menu_button.h"
15 #include "grit/generated_resources.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/gtest_mac.h"
18 #include "testing/platform_test.h"
19 #include "ui/base/models/combobox_model.h"
20 #include "ui/base/models/simple_menu_model.h"
21 #import "ui/base/test/ui_cocoa_test_helper.h"
25 class AutofillSectionContainerTest : public ui::CocoaTest {
27 AutofillSectionContainerTest() : section_(autofill::SECTION_BILLING) {}
28 virtual void SetUp() {
33 void ResetContainer() {
35 [[AutofillSectionContainer alloc]
36 initWithDelegate:&delegate_
37 forSection:section_]);
38 [[test_window() contentView] setSubviews:@[ [container_ view] ]];
42 base::scoped_nsobject<AutofillSectionContainer> container_;
43 testing::NiceMock<autofill::MockAutofillDialogViewDelegate> delegate_;
44 autofill::DialogSection section_;
49 TEST_VIEW(AutofillSectionContainerTest, [container_ view])
51 TEST_F(AutofillSectionContainerTest, HasSubviews) {
52 bool hasLayoutView = false;
53 bool hasTextField = false;
54 bool hasSuggestButton = false;
55 bool hasSuggestionView = false;
57 ASSERT_EQ(4U, [[[container_ view] subviews] count]);
58 for (NSView* view in [[container_ view] subviews]) {
59 if ([view isKindOfClass:[NSTextField class]]) {
61 } else if ([view isKindOfClass:[LayoutView class]]) {
63 } else if ([view isKindOfClass:[MenuButton class]]) {
64 hasSuggestButton = true;
65 } else if ([view isKindOfClass:[NSView class]]) {
66 hasSuggestionView = true;
70 EXPECT_TRUE(hasSuggestButton);
71 EXPECT_TRUE(hasLayoutView);
72 EXPECT_TRUE(hasTextField);
73 EXPECT_TRUE(hasSuggestionView);
76 TEST_F(AutofillSectionContainerTest, ModelsPopulateComboboxes) {
77 using namespace autofill;
78 using namespace testing;
80 const DetailInput kTestInputs[] = {
81 { 2, CREDIT_CARD_EXP_MONTH },
82 { 3, CREDIT_CARD_EXP_4_DIGIT_YEAR }
86 inputs.push_back(kTestInputs[0]);
87 inputs.push_back(kTestInputs[1]);
89 autofill::MonthComboboxModel monthComboModel;
90 autofill::YearComboboxModel yearComboModel;
91 EXPECT_CALL(delegate_, RequestedFieldsForSection(section_))
92 .WillOnce(ReturnRef(inputs));
93 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
94 .WillRepeatedly(Return(&monthComboModel));
96 delegate_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR))
97 .WillRepeatedly(Return(&yearComboModel));
100 NSPopUpButton* popup = base::mac::ObjCCastStrict<NSPopUpButton>(
101 [container_ getField:CREDIT_CARD_EXP_MONTH]);
102 EXPECT_EQ(13, [popup numberOfItems]);
103 EXPECT_NSEQ(@"Month", [popup itemTitleAtIndex:0]);
104 EXPECT_NSEQ(@"01", [popup itemTitleAtIndex:1]);
105 EXPECT_NSEQ(@"02", [popup itemTitleAtIndex:2]);
106 EXPECT_NSEQ(@"03", [popup itemTitleAtIndex:3]);
107 EXPECT_NSEQ(@"12", [popup itemTitleAtIndex:12]);
109 NSPopUpButton* yearPopup = base::mac::ObjCCastStrict<NSPopUpButton>(
110 [container_ getField:CREDIT_CARD_EXP_4_DIGIT_YEAR]);
111 EXPECT_EQ(11, [yearPopup numberOfItems]);
112 EXPECT_NSEQ(@"Year", [yearPopup itemTitleAtIndex:0]);
115 TEST_F(AutofillSectionContainerTest, OutputMatchesDefinition) {
116 using namespace autofill;
117 using namespace testing;
119 const DetailInput kTestInputs[] = {
120 { 1, EMAIL_ADDRESS, IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL },
121 { 2, CREDIT_CARD_EXP_MONTH }
123 autofill::MonthComboboxModel comboModel;
125 inputs.push_back(kTestInputs[0]);
126 inputs.push_back(kTestInputs[1]);
128 EXPECT_CALL(delegate_, RequestedFieldsForSection(section_))
129 .WillOnce(ReturnRef(inputs));
130 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(EMAIL_ADDRESS))
131 .WillRepeatedly(ReturnNull());
132 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
133 .WillRepeatedly(Return(&comboModel));
137 NSPopUpButton* popup = base::mac::ObjCCastStrict<NSPopUpButton>(
138 [container_ getField:CREDIT_CARD_EXP_MONTH]);
139 [popup selectItemWithTitle:@"02"];
140 [[container_ getField:EMAIL_ADDRESS] setStringValue:@"magic@example.org"];
142 autofill::DetailOutputMap output;
143 [container_ getInputs:&output];
145 ASSERT_EQ(inputs.size(), output.size());
146 EXPECT_EQ(ASCIIToUTF16("magic@example.org"), output[&inputs[0]]);
147 EXPECT_EQ(ASCIIToUTF16("02"), output[&inputs[1]]);
150 TEST_F(AutofillSectionContainerTest, SuggestionsPopulatedByController) {
151 ui::SimpleMenuModel model(NULL);
152 model.AddItem(10, ASCIIToUTF16("a"));
153 model.AddItem(11, ASCIIToUTF16("b"));
155 using namespace autofill;
156 using namespace testing;
158 EXPECT_CALL(delegate_, MenuModelForSection(section_))
159 .WillOnce(Return(&model));
162 MenuButton* button = nil;
163 for (id item in [[container_ view] subviews]) {
164 if ([item isKindOfClass:[MenuButton class]]) {
170 NSMenu* menu = [button attachedMenu];
171 // Expect _three_ items - popup menus need an empty first item.
172 ASSERT_EQ(3, [menu numberOfItems]);
174 EXPECT_NSEQ(@"a", [[menu itemAtIndex:1] title]);
175 EXPECT_NSEQ(@"b", [[menu itemAtIndex:2] title]);
178 TEST_F(AutofillSectionContainerTest, FieldsAreInitiallyValid) {
179 using namespace autofill;
180 using namespace testing;
182 const DetailInput kTestInputs[] = {
183 { 1, EMAIL_ADDRESS, IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL },
184 { 2, CREDIT_CARD_EXP_MONTH }
187 MonthComboboxModel comboModel;
189 inputs.push_back(kTestInputs[0]);
190 inputs.push_back(kTestInputs[1]);
192 EXPECT_CALL(delegate_, RequestedFieldsForSection(section_))
193 .WillOnce(ReturnRef(inputs));
194 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(EMAIL_ADDRESS))
195 .WillRepeatedly(ReturnNull());
196 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
197 .WillRepeatedly(Return(&comboModel));
200 NSControl<AutofillInputField>* field = [container_ getField:EMAIL_ADDRESS];
201 EXPECT_FALSE([field invalid]);
202 field = [container_ getField:CREDIT_CARD_EXP_MONTH];
203 EXPECT_FALSE([field invalid]);
206 TEST_F(AutofillSectionContainerTest, ControllerInformsValidity) {
207 using namespace autofill;
208 using namespace testing;
210 const DetailInput kTestInputs[] = {
211 { 1, EMAIL_ADDRESS, IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL },
212 { 2, CREDIT_CARD_EXP_MONTH }
215 MonthComboboxModel comboModel;
217 inputs.push_back(kTestInputs[0]);
218 inputs.push_back(kTestInputs[1]);
220 DetailOutputMap output;
221 ValidityMessages validity, validity2;
223 validity.Set(EMAIL_ADDRESS,
224 ValidityMessage(ASCIIToUTF16("Some error message"), false));
225 validity2.Set(CREDIT_CARD_EXP_MONTH,
226 ValidityMessage(ASCIIToUTF16("Some other error message"), false));
227 EXPECT_CALL(delegate_, RequestedFieldsForSection(section_))
228 .WillOnce(ReturnRef(inputs));
229 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(EMAIL_ADDRESS))
230 .WillRepeatedly(ReturnNull());
231 EXPECT_CALL(delegate_, ComboboxModelForAutofillType(CREDIT_CARD_EXP_MONTH))
232 .WillRepeatedly(Return(&comboModel));
235 [container_ getInputs:&output];
236 EXPECT_CALL(delegate_, InputsAreValid(section_, output))
237 .WillOnce(Return(validity))
238 .WillOnce(Return(validity2));
240 [container_ validateFor:VALIDATE_FINAL];
241 NSControl<AutofillInputField>* field = [container_ getField:EMAIL_ADDRESS];
242 EXPECT_TRUE([field invalid]);
243 field = [container_ getField:CREDIT_CARD_EXP_MONTH];
244 EXPECT_FALSE([field invalid]);
246 [container_ validateFor:VALIDATE_FINAL];
247 field = [container_ getField:EMAIL_ADDRESS];
248 EXPECT_FALSE([field invalid]);
249 field = [container_ getField:CREDIT_CARD_EXP_MONTH];
250 EXPECT_TRUE([field invalid]);