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.
5 #include "base/basictypes.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/autocomplete/autocomplete_match.h"
9 #include "chrome/browser/autocomplete/extension_app_provider.h"
10 #include "chrome/browser/history/history_service.h"
11 #include "chrome/browser/history/history_service_factory.h"
12 #include "chrome/browser/history/url_database.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "content/public/test/test_browser_thread.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 using base::ASCIIToUTF16
;
19 class ExtensionAppProviderTest
: public testing::Test
{
22 const base::string16 input
;
23 const size_t num_results
;
27 ExtensionAppProviderTest()
28 : ui_thread_(content::BrowserThread::UI
, &message_loop_
),
29 history_service_(NULL
) { }
30 virtual ~ExtensionAppProviderTest() { }
32 virtual void SetUp() OVERRIDE
;
34 void RunTest(test_data
* keyword_cases
,
38 base::MessageLoopForUI message_loop_
;
39 content::TestBrowserThread ui_thread_
;
40 scoped_refptr
<ExtensionAppProvider
> app_provider_
;
41 scoped_ptr
<TestingProfile
> profile_
;
42 HistoryService
* history_service_
;
45 void ExtensionAppProviderTest::SetUp() {
46 profile_
.reset(new TestingProfile());
47 ASSERT_TRUE(profile_
->CreateHistoryService(true, false));
48 profile_
->BlockUntilHistoryProcessesPendingRequests();
50 HistoryServiceFactory::GetForProfile(profile_
.get(),
51 Profile::EXPLICIT_ACCESS
);
53 app_provider_
= new ExtensionAppProvider(NULL
, profile_
.get());
55 struct TestExtensionApp
{
57 const char* launch_url
;
58 bool should_match_against_launch_url
;
61 } kExtensionApps
[] = {
62 {"COYB", "http://asdf/", true, "COYB", 7},
63 {"NSNO", "http://fdsa/", true, "NSNO", 2},
64 {"APPP", "chrome-extension://xyz/", false, "APPP", 2},
67 history::URLDatabase
* url_db
= history_service_
->InMemoryDatabase();
69 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kExtensionApps
); ++i
) {
70 // Populate the Extension Apps list.
71 ExtensionAppProvider::ExtensionApp extension_app
= {
72 ASCIIToUTF16(kExtensionApps
[i
].app_name
),
73 ASCIIToUTF16(kExtensionApps
[i
].launch_url
),
74 kExtensionApps
[i
].should_match_against_launch_url
76 app_provider_
->AddExtensionAppForTesting(extension_app
);
78 // Populate the InMemoryDatabase.
79 history::URLRow
info(GURL(kExtensionApps
[i
].launch_url
));
80 info
.set_title(base::UTF8ToUTF16(kExtensionApps
[i
].title
));
81 info
.set_typed_count(kExtensionApps
[i
].typed_count
);
86 void ExtensionAppProviderTest::RunTest(
87 test_data
* keyword_cases
,
90 for (int i
= 0; i
< num_cases
; ++i
) {
91 AutocompleteInput
input(keyword_cases
[i
].input
, base::string16::npos
,
92 base::string16(), GURL(),
93 AutocompleteInput::INVALID_SPEC
, true,
94 false, true, AutocompleteInput::ALL_MATCHES
);
95 app_provider_
->Start(input
, false);
96 EXPECT_TRUE(app_provider_
->done());
97 matches
= app_provider_
->matches();
98 EXPECT_EQ(keyword_cases
[i
].num_results
, matches
.size())
99 << ASCIIToUTF16("Input was: ") + keyword_cases
[i
].input
;
100 if (matches
.size() == keyword_cases
[i
].num_results
) {
101 for (size_t j
= 0; j
< keyword_cases
[i
].num_results
; ++j
)
102 EXPECT_EQ(keyword_cases
[i
].output
[j
], matches
[j
].destination_url
);
107 TEST_F(ExtensionAppProviderTest
, BasicMatching
) {
108 test_data edit_cases
[] = {
109 // Searching for a nonexistent value should give nothing.
110 {ASCIIToUTF16("Not Found"), 0, { GURL() }},
112 // The letter 'o' appears in both extension apps.
113 {ASCIIToUTF16("o"), 2, { GURL("http://asdf/"),
114 GURL("http://fdsa/") }},
115 // The string 'co' appears in one extension app.
116 {ASCIIToUTF16("co"), 1, { GURL("http://asdf/") }},
117 // Try with URL matching.
118 {ASCIIToUTF16("http://asdf/"), 1, { GURL("http://asdf/") }},
119 {ASCIIToUTF16("http://fdsa/"), 1, { GURL("http://fdsa/") }},
121 // "xyz" appears in a launch URL, but we're not matching against it.
122 {ASCIIToUTF16("xyz"), 0, { GURL() }},
124 // But it should be matcheable by title.
125 {ASCIIToUTF16("APPP"), 1, { GURL("chrome-extension://xyz/") }},
129 RunTest(edit_cases
, ARRAYSIZE_UNSAFE(edit_cases
));
132 TEST_F(ExtensionAppProviderTest
, CreateMatchSanitize
) {
135 const char* match_contents
;
138 { "Test \n Test", "Test Test" },
139 { "Test\r\t\nTest", "TestTest" },
142 AutocompleteInput
input(ASCIIToUTF16("Test"), base::string16::npos
,
143 base::string16(), GURL(),
144 AutocompleteInput::INVALID_SPEC
, true, true,
145 true, AutocompleteInput::BEST_MATCH
);
146 base::string16
url(ASCIIToUTF16("http://example.com"));
147 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(cases
); ++i
) {
148 ExtensionAppProvider::ExtensionApp extension_app
=
149 {ASCIIToUTF16(cases
[i
].name
), url
, true};
150 AutocompleteMatch match
=
151 app_provider_
->CreateAutocompleteMatch(input
,
154 base::string16::npos
);
155 EXPECT_EQ(ASCIIToUTF16(cases
[i
].match_contents
), match
.contents
);