| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/basictypes.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/autocomplete/autocomplete_match.h" |
| #include "chrome/browser/autocomplete/extension_app_provider.h" |
| #include "chrome/browser/history/history_service.h" |
| #include "chrome/browser/history/history_service_factory.h" |
| #include "chrome/browser/history/url_database.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "components/metrics/proto/omnibox_event.pb.h" |
| #include "content/public/test/test_browser_thread.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using base::ASCIIToUTF16; |
| |
| class ExtensionAppProviderTest : public testing::Test { |
| protected: |
| struct test_data { |
| const base::string16 input; |
| const size_t num_results; |
| const GURL output[3]; |
| }; |
| |
| ExtensionAppProviderTest() |
| : ui_thread_(content::BrowserThread::UI, &message_loop_), |
| history_service_(NULL) { } |
| virtual ~ExtensionAppProviderTest() { } |
| |
| virtual void SetUp() OVERRIDE; |
| |
| void RunTest(test_data* keyword_cases, |
| int num_cases); |
| |
| protected: |
| base::MessageLoopForUI message_loop_; |
| content::TestBrowserThread ui_thread_; |
| scoped_refptr<ExtensionAppProvider> app_provider_; |
| scoped_ptr<TestingProfile> profile_; |
| HistoryService* history_service_; |
| }; |
| |
| void ExtensionAppProviderTest::SetUp() { |
| profile_.reset(new TestingProfile()); |
| ASSERT_TRUE(profile_->CreateHistoryService(true, false)); |
| profile_->BlockUntilHistoryProcessesPendingRequests(); |
| history_service_ = |
| HistoryServiceFactory::GetForProfile(profile_.get(), |
| Profile::EXPLICIT_ACCESS); |
| |
| app_provider_ = new ExtensionAppProvider(NULL, profile_.get()); |
| |
| struct TestExtensionApp { |
| const char* app_name; |
| const char* launch_url; |
| bool should_match_against_launch_url; |
| const char* title; |
| int typed_count; |
| } kExtensionApps[] = { |
| {"COYB", "http://asdf/", true, "COYB", 7}, |
| {"NSNO", "http://fdsa/", true, "NSNO", 2}, |
| {"APPP", "chrome-extension://xyz/", false, "APPP", 2}, |
| }; |
| |
| history::URLDatabase* url_db = history_service_->InMemoryDatabase(); |
| |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExtensionApps); ++i) { |
| // Populate the Extension Apps list. |
| ExtensionAppProvider::ExtensionApp extension_app = { |
| ASCIIToUTF16(kExtensionApps[i].app_name), |
| ASCIIToUTF16(kExtensionApps[i].launch_url), |
| kExtensionApps[i].should_match_against_launch_url |
| }; |
| app_provider_->AddExtensionAppForTesting(extension_app); |
| |
| // Populate the InMemoryDatabase. |
| history::URLRow info(GURL(kExtensionApps[i].launch_url)); |
| info.set_title(base::UTF8ToUTF16(kExtensionApps[i].title)); |
| info.set_typed_count(kExtensionApps[i].typed_count); |
| url_db->AddURL(info); |
| } |
| } |
| |
| void ExtensionAppProviderTest::RunTest( |
| test_data* keyword_cases, |
| int num_cases) { |
| ACMatches matches; |
| for (int i = 0; i < num_cases; ++i) { |
| AutocompleteInput input(keyword_cases[i].input, base::string16::npos, |
| base::string16(), GURL(), |
| metrics::OmniboxEventProto::INVALID_SPEC, true, |
| false, true, true); |
| app_provider_->Start(input, false); |
| EXPECT_TRUE(app_provider_->done()); |
| matches = app_provider_->matches(); |
| EXPECT_EQ(keyword_cases[i].num_results, matches.size()) |
| << ASCIIToUTF16("Input was: ") + keyword_cases[i].input; |
| if (matches.size() == keyword_cases[i].num_results) { |
| for (size_t j = 0; j < keyword_cases[i].num_results; ++j) |
| EXPECT_EQ(keyword_cases[i].output[j], matches[j].destination_url); |
| } |
| } |
| } |
| |
| TEST_F(ExtensionAppProviderTest, BasicMatching) { |
| test_data edit_cases[] = { |
| // Searching for a nonexistent value should give nothing. |
| {ASCIIToUTF16("Not Found"), 0, { GURL() }}, |
| |
| // The letter 'o' appears in both extension apps. |
| {ASCIIToUTF16("o"), 2, { GURL("http://asdf/"), |
| GURL("http://fdsa/") }}, |
| // The string 'co' appears in one extension app. |
| {ASCIIToUTF16("co"), 1, { GURL("http://asdf/") }}, |
| // Try with URL matching. |
| {ASCIIToUTF16("http://asdf/"), 1, { GURL("http://asdf/") }}, |
| {ASCIIToUTF16("http://fdsa/"), 1, { GURL("http://fdsa/") }}, |
| |
| // "xyz" appears in a launch URL, but we're not matching against it. |
| {ASCIIToUTF16("xyz"), 0, { GURL() }}, |
| |
| // But it should be matcheable by title. |
| {ASCIIToUTF16("APPP"), 1, { GURL("chrome-extension://xyz/") }}, |
| |
| }; |
| |
| RunTest(edit_cases, ARRAYSIZE_UNSAFE(edit_cases)); |
| } |
| |
| TEST_F(ExtensionAppProviderTest, CreateMatchSanitize) { |
| struct TestData { |
| const char* name; |
| const char* match_contents; |
| } cases[] = { |
| { "Test", "Test" }, |
| { "Test \n Test", "Test Test" }, |
| { "Test\r\t\nTest", "TestTest" }, |
| }; |
| |
| AutocompleteInput input(ASCIIToUTF16("Test"), base::string16::npos, |
| base::string16(), GURL(), |
| metrics::OmniboxEventProto::INVALID_SPEC, true, true, |
| true, false); |
| base::string16 url(ASCIIToUTF16("http://example.com")); |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { |
| ExtensionAppProvider::ExtensionApp extension_app = |
| {ASCIIToUTF16(cases[i].name), url, true}; |
| AutocompleteMatch match = |
| app_provider_->CreateAutocompleteMatch(input, |
| extension_app, |
| 0, |
| base::string16::npos); |
| EXPECT_EQ(ASCIIToUTF16(cases[i].match_contents), match.contents); |
| } |
| } |