1 // Copyright 2014 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 #include "components/omnibox/browser/suggestion_answer.h"
7 #include "base/json/json_reader.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 scoped_ptr
<SuggestionAnswer
> ParseAnswer(const std::string
& answer_json
) {
15 scoped_ptr
<base::Value
> value
= base::JSONReader::Read(answer_json
);
16 base::DictionaryValue
* dict
;
17 if (!value
|| !value
->GetAsDictionary(&dict
))
20 return SuggestionAnswer::ParseAnswer(dict
);
25 TEST(SuggestionAnswerTest
, DefaultAreEqual
) {
26 SuggestionAnswer answer1
;
27 SuggestionAnswer answer2
;
28 EXPECT_TRUE(answer1
.Equals(answer2
));
31 TEST(SuggestionAnswerTest
, CopiesAreEqual
) {
32 SuggestionAnswer answer1
;
33 EXPECT_TRUE(answer1
.Equals(SuggestionAnswer(answer1
)));
35 auto answer2
= make_scoped_ptr(new SuggestionAnswer
);
36 answer2
->set_type(832345);
37 EXPECT_TRUE(answer2
->Equals(SuggestionAnswer(*answer2
)));
41 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
42 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }] } } "
44 answer2
= ParseAnswer(json
);
46 EXPECT_TRUE(answer2
->Equals(SuggestionAnswer(*answer2
)));
49 TEST(SuggestionAnswerTest
, DifferentValuesAreUnequal
) {
52 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }, "
53 " { \"t\": \"moar text\", \"tt\": 0 }], "
54 " \"i\": { \"d\": \"//example.com/foo.jpg\" } } }, "
55 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }], "
56 " \"at\": { \"t\": \"slatfatf\", \"tt\": 42 }, "
57 " \"st\": { \"t\": \"oh hi, Mark\", \"tt\": 729347 } } } "
59 scoped_ptr
<SuggestionAnswer
> answer1
= ParseAnswer(json
);
62 // Same but with a different answer type.
63 scoped_ptr
<SuggestionAnswer
> answer2
= SuggestionAnswer::copy(answer1
.get());
64 EXPECT_TRUE(answer1
->Equals(*answer2
));
65 answer2
->set_type(44);
66 EXPECT_FALSE(answer1
->Equals(*answer2
));
68 // Same but with a different type for one of the text fields.
69 answer2
= SuggestionAnswer::copy(answer1
.get());
70 EXPECT_TRUE(answer1
->Equals(*answer2
));
71 answer2
->first_line_
.text_fields_
[1].type_
= 1;
72 EXPECT_FALSE(answer1
->Equals(*answer2
));
74 // Same but with different text for one of the text fields.
75 answer2
= SuggestionAnswer::copy(answer1
.get());
76 EXPECT_TRUE(answer1
->Equals(*answer2
));
77 answer2
->first_line_
.text_fields_
[0].text_
= base::UTF8ToUTF16("some text");
78 EXPECT_FALSE(answer1
->Equals(*answer2
));
80 // Same but with a new URL on the second line.
81 answer2
= SuggestionAnswer::copy(answer1
.get());
82 EXPECT_TRUE(answer1
->Equals(*answer2
));
83 answer2
->second_line_
.image_url_
= GURL("http://foo.com/bar.png");
84 EXPECT_FALSE(answer1
->Equals(*answer2
));
86 // Same but with the additional text removed from the second line.
87 answer2
= SuggestionAnswer::copy(answer1
.get());
88 EXPECT_TRUE(answer1
->Equals(*answer2
));
89 answer2
->second_line_
.additional_text_
.reset();
90 EXPECT_FALSE(answer1
->Equals(*answer2
));
92 // Same but with the status text removed from the second line.
93 answer2
= SuggestionAnswer::copy(answer1
.get());
94 EXPECT_TRUE(answer1
->Equals(*answer2
));
95 answer2
->second_line_
.status_text_
.reset();
96 EXPECT_FALSE(answer1
->Equals(*answer2
));
98 // Same but with the status text removed from the second line of the first
100 answer2
= SuggestionAnswer::copy(answer1
.get());
101 EXPECT_TRUE(answer1
->Equals(*answer2
));
102 answer1
->second_line_
.status_text_
.reset();
103 EXPECT_FALSE(answer1
->Equals(*answer2
));
105 // Same but with the additional text removed from the second line of the first
107 answer2
= SuggestionAnswer::copy(answer1
.get());
108 EXPECT_TRUE(answer1
->Equals(*answer2
));
109 answer1
->second_line_
.additional_text_
.reset();
110 EXPECT_FALSE(answer1
->Equals(*answer2
));
113 TEST(SuggestionAnswerTest
, EmptyJsonIsInvalid
) {
114 ASSERT_FALSE(ParseAnswer(""));
117 TEST(SuggestionAnswerTest
, MalformedJsonIsInvalid
) {
118 ASSERT_FALSE(ParseAnswer("} malformed json {"));
121 TEST(SuggestionAnswerTest
, TextFieldsRequireBothTextAndType
) {
124 " { \"il\": { \"t\": [{ \"t\": \"text\" }] } }, "
126 ASSERT_FALSE(ParseAnswer(json
));
130 " { \"il\": { \"t\": [{ \"tt\": 8 }] } }, "
132 ASSERT_FALSE(ParseAnswer(json
));
135 TEST(SuggestionAnswerTest
, ImageLinesMustContainAtLeastOneTextField
) {
138 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }, "
139 " { \"t\": \"moar text\", \"tt\": 0 }], "
140 " \"i\": { \"d\": \"//example.com/foo.jpg\" } } }, "
141 " { \"il\": { \"t\": [], "
142 " \"at\": { \"t\": \"slatfatf\", \"tt\": 42 }, "
143 " \"st\": { \"t\": \"oh hi, Mark\", \"tt\": 729347 } } } "
145 ASSERT_FALSE(ParseAnswer(json
));
148 TEST(SuggestionAnswerTest
, ExactlyTwoLinesRequired
) {
151 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
153 ASSERT_FALSE(ParseAnswer(json
));
157 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
158 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }] } } "
160 ASSERT_TRUE(ParseAnswer(json
));
164 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
165 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }] } } "
166 " { \"il\": { \"t\": [{ \"t\": \"yet more text\", \"tt\": 13 }] } } "
168 ASSERT_FALSE(ParseAnswer(json
));
171 TEST(SuggestionAnswerTest
, URLPresent
) {
174 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
175 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }], "
176 " \"i\": { \"d\": \"\" } } } "
178 ASSERT_FALSE(ParseAnswer(json
));
182 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
183 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }], "
184 " \"i\": { \"d\": \"https://example.com/foo.jpg\" } } } "
186 ASSERT_TRUE(ParseAnswer(json
));
190 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
191 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }], "
192 " \"i\": { \"d\": \"//example.com/foo.jpg\" } } } "
194 ASSERT_TRUE(ParseAnswer(json
));
197 TEST(SuggestionAnswerTest
, ValidPropertyValues
) {
200 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }, "
201 " { \"t\": \"moar text\", \"tt\": 0 }], "
202 " \"i\": { \"d\": \"//example.com/foo.jpg\" } } }, "
203 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }], "
204 " \"at\": { \"t\": \"slatfatf\", \"tt\": 42 }, "
205 " \"st\": { \"t\": \"oh hi, Mark\", \"tt\": 729347 } } } "
207 scoped_ptr
<SuggestionAnswer
> answer
= ParseAnswer(json
);
209 answer
->set_type(420527);
210 EXPECT_EQ(420527, answer
->type());
212 const SuggestionAnswer::ImageLine
& first_line
= answer
->first_line();
213 EXPECT_EQ(2U, first_line
.text_fields().size());
214 EXPECT_EQ(base::UTF8ToUTF16("text"), first_line
.text_fields()[0].text());
215 EXPECT_EQ(8, first_line
.text_fields()[0].type());
216 EXPECT_EQ(base::UTF8ToUTF16("moar text"), first_line
.text_fields()[1].text());
217 EXPECT_EQ(0, first_line
.text_fields()[1].type());
219 EXPECT_FALSE(first_line
.additional_text());
220 EXPECT_FALSE(first_line
.status_text());
222 EXPECT_TRUE(first_line
.image_url().is_valid());
223 EXPECT_EQ(GURL("https://example.com/foo.jpg"), first_line
.image_url());
225 const SuggestionAnswer::ImageLine
& second_line
= answer
->second_line();
226 EXPECT_EQ(1U, second_line
.text_fields().size());
228 base::UTF8ToUTF16("other text"), second_line
.text_fields()[0].text());
229 EXPECT_EQ(5, second_line
.text_fields()[0].type());
231 EXPECT_TRUE(second_line
.additional_text());
233 base::UTF8ToUTF16("slatfatf"), second_line
.additional_text()->text());
234 EXPECT_EQ(42, second_line
.additional_text()->type());
236 EXPECT_TRUE(second_line
.status_text());
238 base::UTF8ToUTF16("oh hi, Mark"), second_line
.status_text()->text());
239 EXPECT_EQ(729347, second_line
.status_text()->type());
241 EXPECT_FALSE(second_line
.image_url().is_valid());
244 TEST(SuggestionAnswerTest
, AddImageURLsTo
) {
245 SuggestionAnswer::URLs urls
;
248 " { \"il\": { \"t\": [{ \"t\": \"text\", \"tt\": 8 }] } }, "
249 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 5 }] } }] }";
250 scoped_ptr
<SuggestionAnswer
> answer
= ParseAnswer(json
);
252 answer
->AddImageURLsTo(&urls
);
253 ASSERT_EQ(0U, urls
.size());
257 " { \"il\": { \"t\": [{ \"t\": \"some text\", \"tt\": 5 }] } },"
258 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 8 }],"
259 " \"i\": { \"d\": \"//gstatic.com/foo.png\", \"t\": 3 }}}]}";
260 answer
= ParseAnswer(json
);
262 answer
->AddImageURLsTo(&urls
);
263 ASSERT_EQ(1U, urls
.size());
264 EXPECT_EQ(GURL("https://gstatic.com/foo.png"), urls
[0]);
268 " { \"il\": { \"t\": [{ \"t\": \"some text\", \"tt\": 5 }],"
269 " \"i\": { \"d\": \"//gstatic.com/foo.png\" } } }, "
270 " { \"il\": { \"t\": [{ \"t\": \"other text\", \"tt\": 8 }],"
271 " \"i\": { \"d\": \"//gstatic.com/bar.jpg\", \"t\": 3 }}}]}";
272 answer
= ParseAnswer(json
);
274 answer
->AddImageURLsTo(&urls
);
275 ASSERT_EQ(3U, urls
.size());
276 EXPECT_EQ(GURL("https://gstatic.com/foo.png"), urls
[1]);
277 EXPECT_EQ(GURL("https://gstatic.com/bar.jpg"), urls
[2]);