15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 69ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_match.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/extension_app_provider.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/url_database.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/metrics/proto/omnibox_event.pb.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16; 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionAppProviderTest : public testing::Test { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct test_data { 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16 input; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t num_results; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL output[3]; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAppProviderTest() 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ui_thread_(content::BrowserThread::UI, &message_loop_), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service_(NULL) { } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ExtensionAppProviderTest() { } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunTest(test_data* keyword_cases, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_cases); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForUI message_loop_; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ExtensionAppProvider> app_provider_; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestingProfile> profile_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryService* history_service_; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAppProviderTest::SetUp() { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.reset(new TestingProfile()); 48bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ASSERT_TRUE(profile_->CreateHistoryService(true, false)); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->BlockUntilHistoryProcessesPendingRequests(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history_service_ = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HistoryServiceFactory::GetForProfile(profile_.get(), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::EXPLICIT_ACCESS); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_provider_ = new ExtensionAppProvider(NULL, profile_.get()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct TestExtensionApp { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* app_name; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* launch_url; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_match_against_launch_url; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* title; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int typed_count; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } kExtensionApps[] = { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"COYB", "http://asdf/", true, "COYB", 7}, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"NSNO", "http://fdsa/", true, "NSNO", 2}, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"APPP", "chrome-extension://xyz/", false, "APPP", 2}, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::URLDatabase* url_db = history_service_->InMemoryDatabase(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExtensionApps); ++i) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Populate the Extension Apps list. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAppProvider::ExtensionApp extension_app = { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASCIIToUTF16(kExtensionApps[i].app_name), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASCIIToUTF16(kExtensionApps[i].launch_url), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kExtensionApps[i].should_match_against_launch_url 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_provider_->AddExtensionAppForTesting(extension_app); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Populate the InMemoryDatabase. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::URLRow info(GURL(kExtensionApps[i].launch_url)); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) info.set_title(base::UTF8ToUTF16(kExtensionApps[i].title)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info.set_typed_count(kExtensionApps[i].typed_count); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_db->AddURL(info); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionAppProviderTest::RunTest( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_data* keyword_cases, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_cases) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACMatches matches; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num_cases; ++i) { 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutocompleteInput input(keyword_cases[i].input, base::string16::npos, 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16(), GURL(), 946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) metrics::OmniboxEventProto::INVALID_SPEC, true, 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch false, true, true); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_provider_->Start(input, false); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(app_provider_->done()); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) matches = app_provider_->matches(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(keyword_cases[i].num_results, matches.size()) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ASCIIToUTF16("Input was: ") + keyword_cases[i].input; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (matches.size() == keyword_cases[i].num_results) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < keyword_cases[i].num_results; ++j) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(keyword_cases[i].output[j], matches[j].destination_url); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAppProviderTest, BasicMatching) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_data edit_cases[] = { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Searching for a nonexistent value should give nothing. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("Not Found"), 0, { GURL() }}, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The letter 'o' appears in both extension apps. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("o"), 2, { GURL("http://asdf/"), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL("http://fdsa/") }}, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string 'co' appears in one extension app. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("co"), 1, { GURL("http://asdf/") }}, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try with URL matching. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("http://asdf/"), 1, { GURL("http://asdf/") }}, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("http://fdsa/"), 1, { GURL("http://fdsa/") }}, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "xyz" appears in a launch URL, but we're not matching against it. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("xyz"), 0, { GURL() }}, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // But it should be matcheable by title. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16("APPP"), 1, { GURL("chrome-extension://xyz/") }}, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(edit_cases, ARRAYSIZE_UNSAFE(edit_cases)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAppProviderTest, CreateMatchSanitize) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct TestData { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* match_contents; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Test", "Test" }, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Test \n Test", "Test Test" }, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "Test\r\t\nTest", "TestTest" }, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutocompleteInput input(ASCIIToUTF16("Test"), base::string16::npos, 144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16(), GURL(), 1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) metrics::OmniboxEventProto::INVALID_SPEC, true, true, 1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch true, false); 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 url(ASCIIToUTF16("http://example.com")); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAppProvider::ExtensionApp extension_app = 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {ASCIIToUTF16(cases[i].name), url, true}; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteMatch match = 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_provider_->CreateAutocompleteMatch(input, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_app, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16::npos); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16(cases[i].match_contents), match.contents); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 159