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. 4 5 #include "chrome/browser/apps/drive/drive_app_converter.h" 6 7 #include <utility> 8 9 #include "base/bind.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/path_service.h" 12 #include "base/version.h" 13 #include "chrome/browser/extensions/extension_browsertest.h" 14 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_util.h" 16 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/extensions/extension_constants.h" 18 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 19 #include "content/public/test/test_utils.h" 20 #include "extensions/browser/extension_system.h" 21 #include "extensions/common/extension.h" 22 #include "extensions/common/manifest_handlers/icons_handler.h" 23 #include "extensions/common/permissions/permission_set.h" 24 #include "extensions/common/permissions/permissions_data.h" 25 #include "net/test/embedded_test_server/embedded_test_server.h" 26 #include "testing/gtest/include/gtest/gtest.h" 27 28 using extensions::AppLaunchInfo; 29 using extensions::Extension; 30 using extensions::ExtensionRegistry; 31 32 namespace { 33 34 const char kAppName[] = "Test drive app"; 35 const char kAppUrl[] = "http://foobar.com/drive_app"; 36 37 } // namespace 38 39 class DriveAppConverterTest : public ExtensionBrowserTest { 40 public: 41 DriveAppConverterTest() {} 42 virtual ~DriveAppConverterTest() {} 43 44 // ExtensionBrowserTest: 45 virtual void SetUpOnMainThread() OVERRIDE { 46 ExtensionBrowserTest::SetUpOnMainThread(); 47 48 base::FilePath test_data_dir; 49 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); 50 embedded_test_server()->ServeFilesFromDirectory(test_data_dir); 51 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 52 } 53 54 void InstallAndWaitFinish(const drive::DriveAppInfo& drive_app) { 55 runner_ = new content::MessageLoopRunner; 56 57 converter_.reset(new DriveAppConverter( 58 profile(), 59 drive_app, 60 base::Bind(&DriveAppConverterTest::ConverterFinished, 61 base::Unretained(this)))); 62 converter_->Start(); 63 64 runner_->Run(); 65 } 66 67 GURL GetTestUrl(const std::string& path) { 68 return embedded_test_server()->base_url().Resolve(path); 69 } 70 71 drive::DriveAppInfo GetTestDriveApp() { 72 // Define four icons. icon1.png is 16x16 and good to use. icon2.png is 73 // 16x16 but claims to be 32x32 and should be dropped. icon3.png is 66x66 74 // and not a valid extension icon size and should be dropped too. The forth 75 // one is icon2.png with 16x16 but should be ignored because 16x16 already 76 // has icon1.png as its resource. 77 drive::DriveAppInfo::IconList app_icons; 78 app_icons.push_back(std::make_pair(16, GetTestUrl("extensions/icon1.png"))); 79 app_icons.push_back(std::make_pair(32, GetTestUrl("extensions/icon2.png"))); 80 app_icons.push_back(std::make_pair(66, GetTestUrl("extensions/icon3.png"))); 81 app_icons.push_back(std::make_pair(16, GetTestUrl("extensions/icon2.png"))); 82 83 drive::DriveAppInfo::IconList document_icons; 84 85 return drive::DriveAppInfo("fake_drive_app_id", 86 "fake_product_id", 87 app_icons, 88 document_icons, 89 kAppName, 90 GURL(kAppUrl), 91 true); 92 } 93 94 const DriveAppConverter* converter() const { return converter_.get(); } 95 96 private: 97 void ConverterFinished(const DriveAppConverter* converter, bool success) { 98 if (runner_) 99 runner_->Quit(); 100 } 101 102 scoped_ptr<DriveAppConverter> converter_; 103 scoped_refptr<content::MessageLoopRunner> runner_; 104 105 DISALLOW_COPY_AND_ASSIGN(DriveAppConverterTest); 106 }; 107 108 IN_PROC_BROWSER_TEST_F(DriveAppConverterTest, GoodApp) { 109 InstallAndWaitFinish(GetTestDriveApp()); 110 111 const Extension* app = converter()->extension(); 112 ASSERT_TRUE(app != NULL); 113 EXPECT_EQ(kAppName, app->name()); 114 EXPECT_TRUE(app->is_hosted_app()); 115 EXPECT_TRUE(app->from_bookmark()); 116 EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(app)); 117 EXPECT_EQ(extensions::LAUNCH_CONTAINER_TAB, 118 AppLaunchInfo::GetLaunchContainer(app)); 119 EXPECT_EQ(0u, app->permissions_data()->active_permissions()->apis().size()); 120 EXPECT_EQ(1u, extensions::IconsInfo::GetIcons(app).map().size()); 121 122 const Extension* installed = extensions::ExtensionSystem::Get(profile()) 123 ->extension_service() 124 ->GetInstalledExtension(app->id()); 125 EXPECT_EQ(app, installed); 126 EXPECT_FALSE(extensions::util::ShouldSyncApp(app, profile())); 127 } 128 129 IN_PROC_BROWSER_TEST_F(DriveAppConverterTest, BadApp) { 130 drive::DriveAppInfo no_name = GetTestDriveApp(); 131 no_name.app_name.clear(); 132 InstallAndWaitFinish(no_name); 133 EXPECT_TRUE(converter()->extension() == NULL); 134 135 drive::DriveAppInfo no_url = GetTestDriveApp(); 136 no_url.create_url = GURL(); 137 InstallAndWaitFinish(no_url); 138 EXPECT_TRUE(converter()->extension() == NULL); 139 } 140 141 IN_PROC_BROWSER_TEST_F(DriveAppConverterTest, InstallTwice) { 142 InstallAndWaitFinish(GetTestDriveApp()); 143 const Extension* first_install = converter()->extension(); 144 ASSERT_TRUE(first_install != NULL); 145 EXPECT_TRUE(converter()->is_new_install()); 146 const std::string first_install_id = first_install->id(); 147 const base::Version first_install_version(first_install->VersionString()); 148 ASSERT_TRUE(first_install_version.IsValid()); 149 150 InstallAndWaitFinish(GetTestDriveApp()); 151 const Extension* second_install = converter()->extension(); 152 ASSERT_TRUE(second_install != NULL); 153 EXPECT_FALSE(converter()->is_new_install()); 154 155 // Two different app instances. 156 ASSERT_NE(first_install, second_install); 157 EXPECT_EQ(first_install_id, second_install->id()); 158 EXPECT_GE(second_install->version()->CompareTo(first_install_version), 0); 159 } 160