1// Copyright (c) 2012 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/values.h"
6#include "chrome/browser/extensions/api/omnibox/omnibox_api.h"
7#include "chrome/common/extensions/api/omnibox.h"
8#include "extensions/common/value_builder.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "testing/platform_test.h"
11
12namespace extensions {
13
14namespace omnibox = api::omnibox;
15namespace SendSuggestions = omnibox::SendSuggestions;
16namespace SetDefaultSuggestion = omnibox::SetDefaultSuggestion;
17
18namespace {
19
20const int kNone = ACMatchClassification::NONE;
21const int kUrl = ACMatchClassification::URL;
22const int kMatch = ACMatchClassification::MATCH;
23const int kDim = ACMatchClassification::DIM;
24
25void CompareClassification(const ACMatchClassifications& expected,
26                           const ACMatchClassifications& actual) {
27  EXPECT_EQ(expected.size(), actual.size());
28  for (size_t i = 0; i < expected.size() && i < actual.size(); ++i) {
29    EXPECT_EQ(expected[i].offset, actual[i].offset) << "Index:" << i;
30    EXPECT_EQ(expected[i].style, actual[i].style) << "Index:" << i;
31  }
32}
33
34}  // namespace
35
36// Test output key: n = character with no styling, d = dim, m = match, u = url
37// u = 1, m = 2, d = 4. u+d = 5, etc.
38
39//   0123456789
40//    mmmm
41// +       ddd
42// = nmmmmndddn
43TEST(ExtensionOmniboxTest, DescriptionStylesSimple) {
44  scoped_ptr<base::ListValue> list = ListBuilder()
45      .Append(42)
46      .Append(ListBuilder()
47        .Append(DictionaryBuilder()
48          .Set("content", "content")
49          .Set("description", "description")
50          .Set("descriptionStyles", ListBuilder()
51            .Append(DictionaryBuilder()
52              .Set("type", "match")
53              .Set("offset", 1)
54              .Set("length", 4))
55            .Append(DictionaryBuilder()
56              .Set("type", "dim")
57              .Set("offset", 6)
58              .Set("length", 3))))).Build();
59
60  ACMatchClassifications styles_expected;
61  styles_expected.push_back(ACMatchClassification(0, kNone));
62  styles_expected.push_back(ACMatchClassification(1, kMatch));
63  styles_expected.push_back(ACMatchClassification(5, kNone));
64  styles_expected.push_back(ACMatchClassification(6, kDim));
65  styles_expected.push_back(ACMatchClassification(9, kNone));
66
67  scoped_ptr<SendSuggestions::Params> params(
68      SendSuggestions::Params::Create(*list));
69  EXPECT_TRUE(params);
70  EXPECT_TRUE(params->suggest_results[0].get());
71  CompareClassification(styles_expected, StyleTypesToACMatchClassifications(
72      *params->suggest_results[0]));
73
74  // Same input, but swap the order. Ensure it still works.
75  scoped_ptr<base::ListValue> swap_list = ListBuilder()
76      .Append(42)
77      .Append(ListBuilder()
78        .Append(DictionaryBuilder()
79          .Set("content", "content")
80          .Set("description", "description")
81          .Set("descriptionStyles", ListBuilder()
82            .Append(DictionaryBuilder()
83              .Set("type", "dim")
84              .Set("offset", 6)
85              .Set("length", 3))
86            .Append(DictionaryBuilder()
87              .Set("type", "match")
88              .Set("offset", 1)
89              .Set("length", 4))))).Build();
90
91  scoped_ptr<SendSuggestions::Params> swapped_params(
92      SendSuggestions::Params::Create(*swap_list));
93  EXPECT_TRUE(swapped_params);
94  EXPECT_TRUE(swapped_params->suggest_results[0].get());
95  CompareClassification(styles_expected, StyleTypesToACMatchClassifications(
96      *swapped_params->suggest_results[0]));
97}
98
99//   0123456789
100//   uuuuu
101// +          dd
102// +          mm
103// + mmmm
104// +  dd
105// = 3773unnnn66
106TEST(ExtensionOmniboxTest, DescriptionStylesCombine) {
107  scoped_ptr<base::ListValue> list = ListBuilder()
108      .Append(42)
109      .Append(ListBuilder()
110        .Append(DictionaryBuilder()
111          .Set("content", "content")
112          .Set("description", "description")
113          .Set("descriptionStyles", ListBuilder()
114            .Append(DictionaryBuilder()
115              .Set("type", "url")
116              .Set("offset", 0)
117              .Set("length", 5))
118            .Append(DictionaryBuilder()
119              .Set("type", "dim")
120              .Set("offset", 9)
121              .Set("length", 2))
122            .Append(DictionaryBuilder()
123              .Set("type", "match")
124              .Set("offset", 9)
125              .Set("length", 2))
126            .Append(DictionaryBuilder()
127              .Set("type", "match")
128              .Set("offset", 0)
129              .Set("length", 4))
130            .Append(DictionaryBuilder()
131              .Set("type", "dim")
132              .Set("offset", 1)
133              .Set("length", 2))))).Build();
134
135  ACMatchClassifications styles_expected;
136  styles_expected.push_back(ACMatchClassification(0, kUrl | kMatch));
137  styles_expected.push_back(ACMatchClassification(1, kUrl | kMatch | kDim));
138  styles_expected.push_back(ACMatchClassification(3, kUrl | kMatch));
139  styles_expected.push_back(ACMatchClassification(4, kUrl));
140  styles_expected.push_back(ACMatchClassification(5, kNone));
141  styles_expected.push_back(ACMatchClassification(9, kMatch | kDim));
142
143  scoped_ptr<SendSuggestions::Params> params(
144      SendSuggestions::Params::Create(*list));
145  EXPECT_TRUE(params);
146  EXPECT_TRUE(params->suggest_results[0].get());
147  CompareClassification(styles_expected, StyleTypesToACMatchClassifications(
148      *params->suggest_results[0]));
149
150  // Try moving the "dim/match" style pair at offset 9. Output should be the
151  // same.
152  scoped_ptr<base::ListValue> moved_list = ListBuilder()
153      .Append(42)
154      .Append(ListBuilder()
155        .Append(DictionaryBuilder()
156          .Set("content", "content")
157          .Set("description", "description")
158          .Set("descriptionStyles", ListBuilder()
159            .Append(DictionaryBuilder()
160              .Set("type", "url")
161              .Set("offset", 0)
162              .Set("length", 5))
163            .Append(DictionaryBuilder()
164              .Set("type", "match")
165              .Set("offset", 0)
166              .Set("length", 4))
167            .Append(DictionaryBuilder()
168              .Set("type", "dim")
169              .Set("offset", 9)
170              .Set("length", 2))
171            .Append(DictionaryBuilder()
172              .Set("type", "match")
173              .Set("offset", 9)
174              .Set("length", 2))
175            .Append(DictionaryBuilder()
176              .Set("type", "dim")
177              .Set("offset", 1)
178              .Set("length", 2))))).Build();
179
180  scoped_ptr<SendSuggestions::Params> moved_params(
181      SendSuggestions::Params::Create(*moved_list));
182  EXPECT_TRUE(moved_params);
183  EXPECT_TRUE(moved_params->suggest_results[0].get());
184  CompareClassification(styles_expected, StyleTypesToACMatchClassifications(
185      *moved_params->suggest_results[0]));
186}
187
188//   0123456789
189//   uuuuu
190// + mmmmm
191// + mmm
192// +   ddd
193// + ddd
194// = 77777nnnnn
195TEST(ExtensionOmniboxTest, DescriptionStylesCombine2) {
196  scoped_ptr<base::ListValue> list = ListBuilder()
197      .Append(42)
198      .Append(ListBuilder()
199        .Append(DictionaryBuilder()
200          .Set("content", "content")
201          .Set("description", "description")
202          .Set("descriptionStyles", ListBuilder()
203            .Append(DictionaryBuilder()
204              .Set("type", "url")
205              .Set("offset", 0)
206              .Set("length", 5))
207            .Append(DictionaryBuilder()
208              .Set("type", "match")
209              .Set("offset", 0)
210              .Set("length", 5))
211            .Append(DictionaryBuilder()
212              .Set("type", "match")
213              .Set("offset", 0)
214              .Set("length", 3))
215            .Append(DictionaryBuilder()
216              .Set("type", "dim")
217              .Set("offset", 2)
218              .Set("length", 3))
219            .Append(DictionaryBuilder()
220              .Set("type", "dim")
221              .Set("offset", 0)
222              .Set("length", 3))))).Build();
223
224  ACMatchClassifications styles_expected;
225  styles_expected.push_back(ACMatchClassification(0, kUrl | kMatch | kDim));
226  styles_expected.push_back(ACMatchClassification(5, kNone));
227
228  scoped_ptr<SendSuggestions::Params> params(
229      SendSuggestions::Params::Create(*list));
230  EXPECT_TRUE(params);
231  EXPECT_TRUE(params->suggest_results[0].get());
232  CompareClassification(styles_expected, StyleTypesToACMatchClassifications(
233      *params->suggest_results[0]));
234}
235
236//   0123456789
237//   uuuuu
238// + mmmmm
239// + mmm
240// +   ddd
241// + ddd
242// = 77777nnnnn
243TEST(ExtensionOmniboxTest, DefaultSuggestResult) {
244  // Default suggestions should not have a content parameter.
245  scoped_ptr<base::ListValue> list = ListBuilder()
246      .Append(DictionaryBuilder()
247        .Set("description", "description")
248        .Set("descriptionStyles", ListBuilder()
249          .Append(DictionaryBuilder()
250            .Set("type", "url")
251            .Set("offset", 0)
252            .Set("length", 5))
253          .Append(DictionaryBuilder()
254            .Set("type", "match")
255            .Set("offset", 0)
256            .Set("length", 5))
257          .Append(DictionaryBuilder()
258            .Set("type", "match")
259            .Set("offset", 0)
260            .Set("length", 3))
261          .Append(DictionaryBuilder()
262            .Set("type", "dim")
263            .Set("offset", 2)
264            .Set("length", 3))
265          .Append(DictionaryBuilder()
266            .Set("type", "dim")
267            .Set("offset", 0)
268            .Set("length", 3)))).Build();
269
270  scoped_ptr<SetDefaultSuggestion::Params> params(
271      SetDefaultSuggestion::Params::Create(*list));
272  EXPECT_TRUE(params);
273}
274
275}  // namespace extensions
276