Chromium Code Reviews| Index: extensions/browser/renderer_startup_helper_unittest.cc |
| diff --git a/extensions/browser/renderer_startup_helper_unittest.cc b/extensions/browser/renderer_startup_helper_unittest.cc |
| index 56ff5bb1d3828da22ae64b87a40cb7786371463a..08701e70f7f4d945f5cf3abadb9fd064bfb5006d 100644 |
| --- a/extensions/browser/renderer_startup_helper_unittest.cc |
| +++ b/extensions/browser/renderer_startup_helper_unittest.cc |
| @@ -6,12 +6,16 @@ |
| #include "base/memory/ptr_util.h" |
| #include "base/stl_util.h" |
| +#include "components/crx_file/id_util.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_types.h" |
| #include "content/public/test/mock_render_process_host.h" |
| +#include "extensions/browser/extension_prefs.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/extension_registry_factory.h" |
| +#include "extensions/browser/extension_util.h" |
| #include "extensions/browser/extensions_test.h" |
| +#include "extensions/browser/test_extensions_browser_client.h" |
| #include "extensions/common/extension_builder.h" |
| #include "extensions/common/extension_messages.h" |
| @@ -29,11 +33,14 @@ class RendererStartupHelperTest : public ExtensionsTest { |
| ExtensionRegistryFactory::GetForBrowserContext(browser_context()); |
| render_process_host_ = |
| base::MakeUnique<content::MockRenderProcessHost>(browser_context()); |
| + incognito_render_process_host_ = |
| + base::MakeUnique<content::MockRenderProcessHost>(incognito_context()); |
| extension_ = CreateExtension("ext_1"); |
| } |
| void TearDown() override { |
| render_process_host_.reset(); |
| + incognito_render_process_host_.reset(); |
| helper_.reset(); |
| ExtensionsTest::TearDown(); |
| } |
| @@ -53,7 +60,7 @@ class RendererStartupHelperTest : public ExtensionsTest { |
| content::NotificationService::NoDetails()); |
| } |
| - scoped_refptr<Extension> CreateExtension(const std::string& extension_id) { |
| + scoped_refptr<Extension> CreateExtension(const std::string& id_input) { |
| std::unique_ptr<base::DictionaryValue> manifest = |
| DictionaryBuilder() |
| .Set("name", "extension") |
| @@ -61,13 +68,10 @@ class RendererStartupHelperTest : public ExtensionsTest { |
| .Set("manifest_version", 2) |
| .Set("version", "0.1") |
| .Build(); |
| - return ExtensionBuilder() |
| - .SetManifest(std::move(manifest)) |
| - .SetID(extension_id) |
| - .Build(); |
| + return CreateExtension(id_input, std::move(manifest)); |
| } |
| - scoped_refptr<Extension> CreateTheme(const std::string& extension_id) { |
| + scoped_refptr<Extension> CreateTheme(const std::string& id_input) { |
| std::unique_ptr<base::DictionaryValue> manifest = |
| DictionaryBuilder() |
| .Set("name", "theme") |
| @@ -76,10 +80,25 @@ class RendererStartupHelperTest : public ExtensionsTest { |
| .Set("manifest_version", 2) |
| .Set("version", "0.1") |
| .Build(); |
| - return ExtensionBuilder() |
| - .SetManifest(std::move(manifest)) |
| - .SetID(extension_id) |
| - .Build(); |
| + return CreateExtension(id_input, std::move(manifest)); |
| + } |
| + |
| + scoped_refptr<Extension> CreatePlatformApp(const std::string& id_input) { |
| + std::unique_ptr<base::Value> background = |
| + DictionaryBuilder() |
| + .Set("scripts", ListBuilder().Append("background.js").Build()) |
| + .Build(); |
| + std::unique_ptr<base::DictionaryValue> manifest = |
| + DictionaryBuilder() |
| + .Set("name", "platform_app") |
| + .Set("description", "a platform app") |
| + .Set("app", DictionaryBuilder() |
| + .Set("background", std::move(background)) |
| + .Build()) |
| + .Set("manifest_version", 2) |
| + .Set("version", "0.1") |
| + .Build(); |
| + return CreateExtension(id_input, std::move(manifest)); |
| } |
| void AddExtensionToRegistry(scoped_refptr<Extension> extension) { |
| @@ -115,9 +134,20 @@ class RendererStartupHelperTest : public ExtensionsTest { |
| std::unique_ptr<RendererStartupHelper> helper_; |
| ExtensionRegistry* registry_; // Weak. |
| std::unique_ptr<content::MockRenderProcessHost> render_process_host_; |
| + std::unique_ptr<content::MockRenderProcessHost> |
| + incognito_render_process_host_; |
| scoped_refptr<Extension> extension_; |
| private: |
| + scoped_refptr<Extension> CreateExtension( |
| + const std::string& id_input, |
| + std::unique_ptr<base::DictionaryValue> manifest) { |
| + return ExtensionBuilder() |
| + .SetManifest(std::move(manifest)) |
| + .SetID(crx_file::id_util::GenerateId(id_input)) |
| + .Build(); |
| + } |
| + |
| DISALLOW_COPY_AND_ASSIGN(RendererStartupHelperTest); |
| }; |
| @@ -243,4 +273,90 @@ TEST_F(RendererStartupHelperTest, LoadTheme) { |
| EXPECT_FALSE(IsExtensionLoaded(*extension)); |
| } |
| +// Tests that only incognito-enabled extensions are loaded in an incognito |
| +// context. |
| +TEST_F(RendererStartupHelperTest, ExtensionInIncognitoRenderer) { |
| + // Initialize the incognito renderer. |
| + EXPECT_FALSE(IsProcessInitialized(incognito_render_process_host_.get())); |
| + SimulateRenderProcessCreated(incognito_render_process_host_.get()); |
| + EXPECT_TRUE(IsProcessInitialized(incognito_render_process_host_.get())); |
| + |
| + IPC::TestSink& sink = render_process_host_->sink(); |
| + IPC::TestSink& incognito_sink = incognito_render_process_host_->sink(); |
| + |
| + // Enable the extension. It should not be loaded in the initialized incognito |
| + // renderer. |
| + sink.ClearMessages(); |
| + incognito_sink.ClearMessages(); |
| + EXPECT_FALSE(util::IsIncognitoEnabled(extension_->id(), browser_context())); |
| + EXPECT_FALSE(IsExtensionLoaded(*extension_)); |
| + AddExtensionToRegistry(extension_); |
| + helper_->OnExtensionLoaded(*extension_); |
| + EXPECT_EQ(0u, sink.message_count()); |
| + EXPECT_EQ(0u, incognito_sink.message_count()); |
| + EXPECT_TRUE(IsExtensionLoaded(*extension_)); |
| + EXPECT_FALSE(IsExtensionLoadedInProcess( |
| + *extension_, incognito_render_process_host_.get())); |
| + EXPECT_FALSE( |
| + IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| + |
| + // Initialize the normal renderer. The extension should get loaded in it. |
| + sink.ClearMessages(); |
| + incognito_sink.ClearMessages(); |
| + EXPECT_FALSE(IsProcessInitialized(render_process_host_.get())); |
| + SimulateRenderProcessCreated(render_process_host_.get()); |
| + EXPECT_TRUE(IsProcessInitialized(render_process_host_.get())); |
| + EXPECT_TRUE( |
| + IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
|
Devlin
2017/04/04 15:15:05
add
EXPECT_FALSE(IsExtensionLoadedInProcess(*exten
karandeepb
2017/04/04 19:46:16
Done.
|
| + EXPECT_LE(1u, sink.message_count()); |
| + EXPECT_EQ(0u, incognito_sink.message_count()); |
| + |
| + // Enable the extension in incognito mode. This will reload the extension. |
| + sink.ClearMessages(); |
| + incognito_sink.ClearMessages(); |
| + ExtensionPrefs::Get(browser_context()) |
| + ->SetIsIncognitoEnabled(extension_->id(), true); |
| + helper_->OnExtensionUnloaded(*extension_); |
| + helper_->OnExtensionLoaded(*extension_); |
| + EXPECT_TRUE(IsExtensionLoadedInProcess(*extension_, |
| + incognito_render_process_host_.get())); |
| + EXPECT_TRUE( |
| + IsExtensionLoadedInProcess(*extension_, render_process_host_.get())); |
| + // The extension would not have been unloaded from the incognito renderer |
| + // since it wasn't loaded. |
| + ASSERT_EQ(1u, incognito_sink.message_count()); |
| + EXPECT_EQ(ExtensionMsg_Loaded::ID, incognito_sink.GetMessageAt(0)->type()); |
| + // The extension would be first unloaded and then loaded from the normal |
| + // renderer. |
| + ASSERT_EQ(2u, sink.message_count()); |
| + EXPECT_EQ(ExtensionMsg_Unloaded::ID, sink.GetMessageAt(0)->type()); |
| + EXPECT_EQ(ExtensionMsg_Loaded::ID, sink.GetMessageAt(1)->type()); |
| +} |
| + |
| +// Tests that platform apps are always loaded in an incognito renderer. |
| +TEST_F(RendererStartupHelperTest, PlatformAppInIncognitoRenderer) { |
| + // Initialize the incognito renderer. |
| + EXPECT_FALSE(IsProcessInitialized(incognito_render_process_host_.get())); |
| + SimulateRenderProcessCreated(incognito_render_process_host_.get()); |
| + EXPECT_TRUE(IsProcessInitialized(incognito_render_process_host_.get())); |
| + |
| + IPC::TestSink& incognito_sink = incognito_render_process_host_->sink(); |
| + |
| + scoped_refptr<Extension> platform_app(CreatePlatformApp("platform_app")); |
| + ASSERT_TRUE(platform_app->is_platform_app()); |
| + EXPECT_FALSE(util::IsIncognitoEnabled(platform_app->id(), browser_context())); |
| + EXPECT_FALSE(util::CanBeIncognitoEnabled(platform_app.get())); |
| + |
| + // Enable the app. It should get loaded in the incognito renderer even though |
| + // IsIncognitoEnabled returns false for it, since it can't be enabled for |
| + // incognito. |
| + incognito_sink.ClearMessages(); |
| + AddExtensionToRegistry(platform_app); |
| + helper_->OnExtensionLoaded(*platform_app); |
| + EXPECT_TRUE(IsExtensionLoadedInProcess(*platform_app, |
| + incognito_render_process_host_.get())); |
| + ASSERT_EQ(1u, incognito_sink.message_count()); |
| + EXPECT_EQ(ExtensionMsg_Loaded::ID, incognito_sink.GetMessageAt(0)->type()); |
| +} |
| + |
| } // namespace extensions |