OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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/renderer/user_script_slave.h" |
| 6 |
| 7 #include "base/pickle.h" |
| 8 #include "base/scoped_ptr.h" |
| 9 #include "base/shared_memory.h" |
| 10 #include "base/string_piece.h" |
| 11 #include "chrome/common/extensions/user_script.h" |
| 12 #include "chrome/common/ipc_test_sink.h" |
| 13 #include "chrome/common/render_messages.h" |
| 14 #include "chrome/renderer/mock_render_thread.h" |
| 15 #include "chrome/renderer/render_thread.h" |
| 16 #include "ipc/ipc_message.h" |
| 17 #include "ipc/ipc_sync_message.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 |
| 20 typedef std::vector<UserScript::File> FileList; |
| 21 typedef std::vector<UserScript*> UserScripts; |
| 22 |
| 23 // Valid extension id. |
| 24 const char* const kExtensionId = "nanifionbniojdbjhimhbiajcfajnjde"; |
| 25 // JS script. |
| 26 const char* const kJsScript = |
| 27 "var x = { 'id': '__MSG_@@extension_id__'};"; |
| 28 // CSS style. |
| 29 const char* const kCssScript = |
| 30 "div {url(chrome-extension://__MSG_@@extension_id__/icon.png);}"; |
| 31 const char* const kCssScriptWithReplacedMessage = |
| 32 "div {url(chrome-extension://nanifionbniojdbjhimhbiajcfajnjde/icon.png);}"; |
| 33 |
| 34 class UserScriptSlaveTest : public testing::Test { |
| 35 public: |
| 36 UserScriptSlaveTest() |
| 37 : shared_memory_(NULL) { |
| 38 } |
| 39 |
| 40 virtual void SetUp() { |
| 41 message_sender_.reset(new MockRenderThread()); |
| 42 user_script_slave_.reset(new UserScriptSlave(message_sender_.get())); |
| 43 } |
| 44 |
| 45 virtual void TearDown() { |
| 46 shared_memory_.release(); |
| 47 } |
| 48 |
| 49 UserScripts GetUserScripts() { |
| 50 return user_script_slave_->scripts_; |
| 51 } |
| 52 |
| 53 protected: |
| 54 // Create user script with given extension id. |
| 55 void CreateUserScript(const std::string extension_id) { |
| 56 // Extension id can be empty. |
| 57 user_script_.set_extension_id(extension_id); |
| 58 |
| 59 // Add js script. |
| 60 FileList& js_scripts = user_script_.js_scripts(); |
| 61 UserScript::File js_script; |
| 62 js_script.set_content(base::StringPiece(kJsScript, strlen(kJsScript))); |
| 63 js_scripts.push_back(js_script); |
| 64 |
| 65 // Add css script. |
| 66 FileList& css_scripts = user_script_.css_scripts(); |
| 67 UserScript::File css_script; |
| 68 css_script.set_content(base::StringPiece(kCssScript, strlen(kCssScript))); |
| 69 css_scripts.push_back(css_script); |
| 70 } |
| 71 |
| 72 // Serializes the UserScript object and stores it in the shared memory. |
| 73 bool Serialize(const UserScript& script) { |
| 74 Pickle pickle; |
| 75 pickle.WriteSize(1); |
| 76 script.Pickle(&pickle); |
| 77 for (size_t j = 0; j < script.js_scripts().size(); j++) { |
| 78 base::StringPiece contents = script.js_scripts()[j].GetContent(); |
| 79 pickle.WriteData(contents.data(), contents.length()); |
| 80 } |
| 81 for (size_t j = 0; j < script.css_scripts().size(); j++) { |
| 82 base::StringPiece contents = script.css_scripts()[j].GetContent(); |
| 83 pickle.WriteData(contents.data(), contents.length()); |
| 84 } |
| 85 |
| 86 // Create the shared memory object. |
| 87 shared_memory_.reset(new base::SharedMemory()); |
| 88 |
| 89 if (!shared_memory_->Create(std::wstring(), // anonymous |
| 90 false, // read-only |
| 91 false, // open existing |
| 92 pickle.size())) |
| 93 return false; |
| 94 |
| 95 // Map into our process. |
| 96 if (!shared_memory_->Map(pickle.size())) |
| 97 return false; |
| 98 |
| 99 // Copy the pickle to shared memory. |
| 100 memcpy(shared_memory_->memory(), pickle.data(), pickle.size()); |
| 101 return true; |
| 102 } |
| 103 |
| 104 // User script slave we are testing. |
| 105 scoped_ptr<UserScriptSlave> user_script_slave_; |
| 106 |
| 107 // IPC message sender. |
| 108 scoped_ptr<MockRenderThread> message_sender_; |
| 109 |
| 110 // User script that has css and js files. |
| 111 UserScript user_script_; |
| 112 |
| 113 // Shared memory object used to pass user scripts from browser to renderer. |
| 114 scoped_ptr<base::SharedMemory> shared_memory_; |
| 115 }; |
| 116 |
| 117 TEST_F(UserScriptSlaveTest, MessagesNotReplacedIfScriptDoesntHaveCssScript) { |
| 118 CreateUserScript(kExtensionId); |
| 119 user_script_.css_scripts().clear(); |
| 120 |
| 121 ASSERT_TRUE(Serialize(user_script_)); |
| 122 ASSERT_TRUE(user_script_slave_->UpdateScripts( |
| 123 shared_memory_->handle(), false)); |
| 124 |
| 125 UserScripts scripts = GetUserScripts(); |
| 126 ASSERT_EQ(1U, scripts.size()); |
| 127 ASSERT_EQ(1U, scripts[0]->js_scripts().size()); |
| 128 EXPECT_EQ(0U, scripts[0]->css_scripts().size()); |
| 129 |
| 130 EXPECT_EQ(scripts[0]->js_scripts()[0].GetContent(), kJsScript); |
| 131 |
| 132 // Send was not called to fetch the messages in this case, since we don't |
| 133 // have the css scripts. |
| 134 EXPECT_EQ(0U, message_sender_->sink().message_count()); |
| 135 } |
| 136 |
| 137 TEST_F(UserScriptSlaveTest, MessagesNotReplacedIfScriptDoesntHaveExtensionId) { |
| 138 CreateUserScript(""); |
| 139 ASSERT_TRUE(Serialize(user_script_)); |
| 140 ASSERT_TRUE(user_script_slave_->UpdateScripts( |
| 141 shared_memory_->handle(), false)); |
| 142 |
| 143 UserScripts scripts = GetUserScripts(); |
| 144 ASSERT_EQ(1U, scripts.size()); |
| 145 ASSERT_EQ(1U, scripts[0]->js_scripts().size()); |
| 146 ASSERT_EQ(1U, scripts[0]->css_scripts().size()); |
| 147 |
| 148 EXPECT_EQ(scripts[0]->js_scripts()[0].GetContent(), kJsScript); |
| 149 EXPECT_EQ(scripts[0]->css_scripts()[0].GetContent(), kCssScript); |
| 150 |
| 151 // Send was not called to fetch the messages in this case, since we don't |
| 152 // have the extension id. |
| 153 EXPECT_EQ(0U, message_sender_->sink().message_count()); |
| 154 } |
| 155 |
| 156 TEST_F(UserScriptSlaveTest, MessagesAreReplacedIfScriptHasExtensionId) { |
| 157 CreateUserScript(kExtensionId); |
| 158 ASSERT_TRUE(Serialize(user_script_)); |
| 159 ASSERT_TRUE(user_script_slave_->UpdateScripts( |
| 160 shared_memory_->handle(), false)); |
| 161 |
| 162 UserScripts scripts = GetUserScripts(); |
| 163 ASSERT_EQ(1U, scripts.size()); |
| 164 ASSERT_EQ(1U, scripts[0]->js_scripts().size()); |
| 165 ASSERT_EQ(1U, scripts[0]->css_scripts().size()); |
| 166 |
| 167 // JS scripts should stay the same. |
| 168 EXPECT_STREQ(scripts[0]->js_scripts()[0].GetContent().data(), kJsScript); |
| 169 // We expect only CSS scripts to change. |
| 170 EXPECT_STREQ(scripts[0]->css_scripts()[0].GetContent().data(), |
| 171 kCssScriptWithReplacedMessage); |
| 172 |
| 173 // Send gets always gets called if there is an extension id and css script. |
| 174 ASSERT_EQ(1U, message_sender_->sink().message_count()); |
| 175 EXPECT_TRUE(message_sender_->sink().GetFirstMessageMatching( |
| 176 ViewHostMsg_GetExtensionMessageBundle::ID)); |
| 177 } |
OLD | NEW |