Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / shared_module_service_unittest.cc
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 "base/memory/ref_counted.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/strings/string16.h"
8 #include "base/values.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_service_unittest.h"
11 #include "chrome/browser/extensions/pending_extension_manager.h"
12 #include "chrome/browser/extensions/shared_module_service.h"
13 #include "chrome/common/extensions/features/feature_channel.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/common/extension_builder.h"
16 #include "extensions/common/id_util.h"
17 #include "extensions/common/value_builder.h"
18 #include "sync/api/string_ordinal.h"
19
20 namespace extensions {
21
22 namespace {
23
24 // Return an extension with |id| which imports a module with the given
25 // |import_id|.
26 scoped_refptr<Extension> CreateExtensionImportingModule(
27     const std::string& import_id, const std::string& id) {
28   scoped_ptr<base::DictionaryValue> manifest =
29       DictionaryBuilder()
30           .Set("name", "Has Dependent Modules")
31           .Set("version", "1.0")
32           .Set("manifest_version", 2)
33           .Set("import",
34                ListBuilder().Append(DictionaryBuilder().Set("id", import_id)))
35           .Build();
36
37   return ExtensionBuilder().SetManifest(manifest.Pass())
38                            .AddFlags(Extension::FROM_WEBSTORE)
39                            .SetID(id)
40                            .Build();
41 }
42
43 }  // namespace
44
45 class SharedModuleServiceUnitTest : public ExtensionServiceTestBase {
46  public:
47   SharedModuleServiceUnitTest() :
48       // The "export" key is open for dev-channel only, but unit tests
49       // run as stable channel on the official Windows build.
50       current_channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {}
51  protected:
52   virtual void SetUp() OVERRIDE;
53
54   // Install an extension and notify the ExtensionService.
55   testing::AssertionResult InstallExtension(const Extension* extension);
56   ScopedCurrentChannel current_channel_;
57 };
58
59 void SharedModuleServiceUnitTest::SetUp() {
60   ExtensionServiceTestBase::SetUp();
61   InitializeGoodInstalledExtensionService();
62   service_->Init();
63 }
64
65 testing::AssertionResult SharedModuleServiceUnitTest::InstallExtension(
66     const Extension* extension) {
67   // Verify the extension is not already installed.
68   if (registry_->GetExtensionById(extension->id(),
69                                   ExtensionRegistry::ENABLED)) {
70     return testing::AssertionFailure() << "Extension already installed.";
71   }
72
73   // Notify the service that the extension is installed. This adds it to the
74   // registry, notifies interested parties, etc.
75   service_->OnExtensionInstalled(extension,
76                                  syncer::StringOrdinal(),
77                                  false,  // No requirement errors.
78                                  NOT_BLACKLISTED,
79                                  false);  // Don't wait for idle.
80
81   // Verify that the extension is now installed.
82   if (!registry_->GetExtensionById(extension->id(),
83                                    ExtensionRegistry::ENABLED)) {
84     return testing::AssertionFailure() << "Could not install extension.";
85   }
86
87   return testing::AssertionSuccess();
88 }
89
90 TEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) {
91   // Create an extension that has a dependency.
92   std::string import_id = id_util::GenerateId("id");
93   std::string extension_id = id_util::GenerateId("extension_id");
94   scoped_refptr<Extension> extension =
95       CreateExtensionImportingModule(import_id, extension_id);
96
97   PendingExtensionManager* pending_extension_manager =
98       service_->pending_extension_manager();
99
100   // Verify that we don't currently want to install the imported module.
101   EXPECT_FALSE(pending_extension_manager->IsIdPending(import_id));
102
103   // Try to satisfy imports for the extension. This should queue the imported
104   // module's installation.
105   service_->shared_module_service()->SatisfyImports(extension);
106   EXPECT_TRUE(pending_extension_manager->IsIdPending(import_id));
107 }
108
109 TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) {
110   // Create a module which exports a resource, and install it.
111   scoped_ptr<base::DictionaryValue> manifest =
112       DictionaryBuilder()
113           .Set("name", "Shared Module")
114           .Set("version", "1.0")
115           .Set("manifest_version", 2)
116           .Set("export",
117                DictionaryBuilder().Set("resources",
118                                        ListBuilder().Append("foo.js"))).Build();
119   scoped_refptr<Extension> shared_module =
120       ExtensionBuilder().SetManifest(manifest.Pass())
121                         .AddFlags(Extension::FROM_WEBSTORE)
122                         .SetID(id_util::GenerateId("shared_module"))
123                         .Build();
124
125   EXPECT_TRUE(InstallExtension(shared_module));
126
127   std::string extension_id = id_util::GenerateId("extension_id");
128   // Create and install an extension that imports our new module.
129   scoped_refptr<Extension> importing_extension =
130       CreateExtensionImportingModule(shared_module->id(), extension_id);
131   EXPECT_TRUE(InstallExtension(importing_extension));
132
133   // Uninstall the extension that imports our module.
134   base::string16 error;
135   service_->UninstallExtension(importing_extension->id(),
136                                false,  // Not external uninstall.
137                                &error);
138   EXPECT_TRUE(error.empty());
139
140   // Since the module was only referenced by that single extension, it should
141   // have been uninstalled as a side-effect of uninstalling the extension that
142   // depended upon it.
143   EXPECT_FALSE(registry_->GetExtensionById(shared_module->id(),
144                                            ExtensionRegistry::EVERYTHING));
145 }
146
147 TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) {
148   std::string whitelisted_id = id_util::GenerateId("whitelisted");
149   std::string nonwhitelisted_id = id_util::GenerateId("nonwhitelisted");
150   // Create a module which exports to a restricted whitelist.
151   scoped_ptr<base::DictionaryValue> manifest =
152       DictionaryBuilder()
153           .Set("name", "Shared Module")
154           .Set("version", "1.0")
155           .Set("manifest_version", 2)
156           .Set("export",
157                DictionaryBuilder().Set("whitelist",
158                                        ListBuilder()
159                                            .Append(whitelisted_id))
160                                   .Set("resources",
161                                        ListBuilder().Append("*"))).Build();
162   scoped_refptr<Extension> shared_module =
163       ExtensionBuilder().SetManifest(manifest.Pass())
164                         .AddFlags(Extension::FROM_WEBSTORE)
165                         .SetID(id_util::GenerateId("shared_module"))
166                         .Build();
167
168   EXPECT_TRUE(InstallExtension(shared_module));
169
170   // Create and install an extension with the whitelisted ID.
171   scoped_refptr<Extension> whitelisted_extension =
172       CreateExtensionImportingModule(shared_module->id(), whitelisted_id);
173   EXPECT_TRUE(InstallExtension(whitelisted_extension));
174
175   // Try to install an extension with an ID that is not whitelisted.
176   scoped_refptr<Extension> nonwhitelisted_extension =
177       CreateExtensionImportingModule(shared_module->id(), nonwhitelisted_id);
178   EXPECT_FALSE(InstallExtension(nonwhitelisted_extension));
179 }
180
181 }  // namespace extensions