| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <map> | 5 #include <map> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "chrome/renderer/extensions/extension_localization_peer.h" | 9 #include "chrome/renderer/extensions/extension_localization_peer.h" |
| 10 #include "extensions/common/message_bundle.h" | 10 #include "extensions/common/message_bundle.h" |
| 11 #include "ipc/ipc_sender.h" | 11 #include "ipc/ipc_sender.h" |
| 12 #include "ipc/ipc_sync_message.h" | 12 #include "ipc/ipc_sync_message.h" |
| 13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/url_request/redirect_info.h" | 14 #include "net/url_request/redirect_info.h" |
| 15 #include "net/url_request/url_request_status.h" | 15 #include "net/url_request/url_request_status.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 namespace { |
| 20 |
| 19 using testing::_; | 21 using testing::_; |
| 20 using testing::DoAll; | 22 using testing::DoAll; |
| 21 using testing::Invoke; | 23 using testing::Invoke; |
| 22 using testing::StrEq; | 24 using testing::StrEq; |
| 23 using testing::Return; | 25 using testing::Return; |
| 26 using ReceivedData = content::RequestPeer::ReceivedData; |
| 24 | 27 |
| 25 static const char* const kExtensionUrl_1 = | 28 static const char* const kExtensionUrl_1 = |
| 26 "chrome-extension://some_id/popup.css"; | 29 "chrome-extension://some_id/popup.css"; |
| 27 | 30 |
| 28 static const char* const kExtensionUrl_2 = | 31 static const char* const kExtensionUrl_2 = |
| 29 "chrome-extension://some_id2/popup.css"; | 32 "chrome-extension://some_id2/popup.css"; |
| 30 | 33 |
| 31 static const char* const kExtensionUrl_3 = | 34 static const char* const kExtensionUrl_3 = |
| 32 "chrome-extension://some_id3/popup.css"; | 35 "chrome-extension://some_id3/popup.css"; |
| 33 | 36 |
| 34 void MessageDeleter(IPC::Message* message) { | 37 void MessageDeleter(IPC::Message* message) { |
| 35 delete message; | 38 delete message; |
| 36 } | 39 } |
| 37 | 40 |
| 41 class FixedReceivedData final : public ReceivedData { |
| 42 public: |
| 43 FixedReceivedData(const char* payload, int length, int encoded_length) |
| 44 : data_(&payload[0], &payload[length]), encoded_length_(encoded_length) {} |
| 45 ~FixedReceivedData() override {} |
| 46 |
| 47 const char* payload() const override { |
| 48 // TODO(yhirano): Use |data_.data()| when we can use c++11. |
| 49 return data_.empty() ? nullptr : &data_[0]; |
| 50 } |
| 51 int length() const override { return data_.size(); } |
| 52 int encoded_length() const override { return encoded_length_; } |
| 53 |
| 54 private: |
| 55 const std::vector<char> data_; |
| 56 const int encoded_length_; |
| 57 |
| 58 DISALLOW_COPY_AND_ASSIGN(FixedReceivedData); |
| 59 }; |
| 60 |
| 38 class MockIpcMessageSender : public IPC::Sender { | 61 class MockIpcMessageSender : public IPC::Sender { |
| 39 public: | 62 public: |
| 40 MockIpcMessageSender() { | 63 MockIpcMessageSender() { |
| 41 ON_CALL(*this, Send(_)) | 64 ON_CALL(*this, Send(_)) |
| 42 .WillByDefault(DoAll(Invoke(MessageDeleter), Return(true))); | 65 .WillByDefault(DoAll(Invoke(MessageDeleter), Return(true))); |
| 43 } | 66 } |
| 44 | 67 |
| 45 virtual ~MockIpcMessageSender() {} | 68 virtual ~MockIpcMessageSender() {} |
| 46 | 69 |
| 47 MOCK_METHOD1(Send, bool(IPC::Message* message)); | 70 MOCK_METHOD1(Send, bool(IPC::Message* message)); |
| 48 | 71 |
| 49 private: | 72 private: |
| 50 DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender); | 73 DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender); |
| 51 }; | 74 }; |
| 52 | 75 |
| 53 class MockRequestPeer : public content::RequestPeer { | 76 class MockRequestPeer : public content::RequestPeer { |
| 54 public: | 77 public: |
| 55 MockRequestPeer() {} | 78 MockRequestPeer() {} |
| 56 virtual ~MockRequestPeer() {} | 79 virtual ~MockRequestPeer() {} |
| 57 | 80 |
| 58 MOCK_METHOD2(OnUploadProgress, void(uint64 position, uint64 size)); | 81 MOCK_METHOD2(OnUploadProgress, void(uint64 position, uint64 size)); |
| 59 MOCK_METHOD2(OnReceivedRedirect, | 82 MOCK_METHOD2(OnReceivedRedirect, |
| 60 bool(const net::RedirectInfo& redirect_info, | 83 bool(const net::RedirectInfo& redirect_info, |
| 61 const content::ResourceResponseInfo& info)); | 84 const content::ResourceResponseInfo& info)); |
| 62 MOCK_METHOD1(OnReceivedResponse, | 85 MOCK_METHOD1(OnReceivedResponse, |
| 63 void(const content::ResourceResponseInfo& info)); | 86 void(const content::ResourceResponseInfo& info)); |
| 64 MOCK_METHOD2(OnDownloadedData, void(int len, int encoded_data_length)); | 87 MOCK_METHOD2(OnDownloadedData, void(int len, int encoded_data_length)); |
| 65 MOCK_METHOD3(OnReceivedData, void(const char* data, | 88 void OnReceivedData(scoped_ptr<ReceivedData> data) override { |
| 66 int data_length, | 89 OnReceivedDataInternal(data->payload(), data->length(), |
| 67 int encoded_data_length)); | 90 data->encoded_length()); |
| 91 } |
| 92 MOCK_METHOD3(OnReceivedDataInternal, |
| 93 void(const char* data, |
| 94 int data_length, |
| 95 int encoded_data_length)); |
| 68 MOCK_METHOD6(OnCompletedRequest, void( | 96 MOCK_METHOD6(OnCompletedRequest, void( |
| 69 int error_code, | 97 int error_code, |
| 70 bool was_ignored_by_handler, | 98 bool was_ignored_by_handler, |
| 71 bool stale_copy_in_cache, | 99 bool stale_copy_in_cache, |
| 72 const std::string& security_info, | 100 const std::string& security_info, |
| 73 const base::TimeTicks& completion_time, | 101 const base::TimeTicks& completion_time, |
| 74 int64_t total_transfer_size)); | 102 int64_t total_transfer_size)); |
| 75 | 103 |
| 76 private: | 104 private: |
| 77 DISALLOW_COPY_AND_ASSIGN(MockRequestPeer); | 105 DISALLOW_COPY_AND_ASSIGN(MockRequestPeer); |
| 78 }; | 106 }; |
| 79 | 107 |
| 108 } // namespace |
| 109 |
| 80 class ExtensionLocalizationPeerTest : public testing::Test { | 110 class ExtensionLocalizationPeerTest : public testing::Test { |
| 81 protected: | 111 protected: |
| 82 void SetUp() override { | 112 void SetUp() override { |
| 83 sender_.reset(new MockIpcMessageSender()); | 113 sender_.reset(new MockIpcMessageSender()); |
| 84 original_peer_.reset(new MockRequestPeer()); | 114 original_peer_.reset(new MockRequestPeer()); |
| 85 filter_peer_.reset( | 115 filter_peer_.reset( |
| 86 ExtensionLocalizationPeer::CreateExtensionLocalizationPeer( | 116 ExtensionLocalizationPeer::CreateExtensionLocalizationPeer( |
| 87 original_peer_.get(), sender_.get(), "text/css", | 117 original_peer_.get(), sender_.get(), "text/css", |
| 88 GURL(kExtensionUrl_1))); | 118 GURL(kExtensionUrl_1))); |
| 89 } | 119 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 118 } | 148 } |
| 119 | 149 |
| 120 TEST_F(ExtensionLocalizationPeerTest, CreateWithValidInput) { | 150 TEST_F(ExtensionLocalizationPeerTest, CreateWithValidInput) { |
| 121 EXPECT_TRUE(NULL != filter_peer_.get()); | 151 EXPECT_TRUE(NULL != filter_peer_.get()); |
| 122 } | 152 } |
| 123 | 153 |
| 124 TEST_F(ExtensionLocalizationPeerTest, OnReceivedData) { | 154 TEST_F(ExtensionLocalizationPeerTest, OnReceivedData) { |
| 125 EXPECT_TRUE(GetData(filter_peer_.get()).empty()); | 155 EXPECT_TRUE(GetData(filter_peer_.get()).empty()); |
| 126 | 156 |
| 127 const std::string data_chunk("12345"); | 157 const std::string data_chunk("12345"); |
| 128 filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1); | 158 filter_peer_->OnReceivedData(make_scoped_ptr( |
| 159 new FixedReceivedData(data_chunk.c_str(), data_chunk.length(), -1))); |
| 129 | 160 |
| 130 EXPECT_EQ(data_chunk, GetData(filter_peer_.get())); | 161 EXPECT_EQ(data_chunk, GetData(filter_peer_.get())); |
| 131 | 162 |
| 132 filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1); | 163 filter_peer_->OnReceivedData(make_scoped_ptr( |
| 164 new FixedReceivedData(data_chunk.c_str(), data_chunk.length(), -1))); |
| 133 EXPECT_EQ(data_chunk + data_chunk, GetData(filter_peer_.get())); | 165 EXPECT_EQ(data_chunk + data_chunk, GetData(filter_peer_.get())); |
| 134 } | 166 } |
| 135 | 167 |
| 136 MATCHER_P(IsURLRequestEqual, status, "") { return arg.status() == status; } | 168 MATCHER_P(IsURLRequestEqual, status, "") { return arg.status() == status; } |
| 137 | 169 |
| 138 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestBadURLRequestStatus) { | 170 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestBadURLRequestStatus) { |
| 139 // It will self-delete once it exits OnCompletedRequest. | 171 // It will self-delete once it exits OnCompletedRequest. |
| 140 ExtensionLocalizationPeer* filter_peer = filter_peer_.release(); | 172 ExtensionLocalizationPeer* filter_peer = filter_peer_.release(); |
| 141 | 173 |
| 142 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); | 174 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); |
| 143 EXPECT_CALL(*original_peer_, OnCompletedRequest( | 175 EXPECT_CALL(*original_peer_, OnCompletedRequest( |
| 144 net::ERR_ABORTED, false, false, "", base::TimeTicks(), -1)); | 176 net::ERR_ABORTED, false, false, "", base::TimeTicks(), -1)); |
| 145 | 177 |
| 146 filter_peer->OnCompletedRequest( | 178 filter_peer->OnCompletedRequest( |
| 147 net::ERR_FAILED, false, false, std::string(), base::TimeTicks(), -1); | 179 net::ERR_FAILED, false, false, std::string(), base::TimeTicks(), -1); |
| 148 } | 180 } |
| 149 | 181 |
| 150 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestEmptyData) { | 182 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestEmptyData) { |
| 151 // It will self-delete once it exits OnCompletedRequest. | 183 // It will self-delete once it exits OnCompletedRequest. |
| 152 ExtensionLocalizationPeer* filter_peer = filter_peer_.release(); | 184 ExtensionLocalizationPeer* filter_peer = filter_peer_.release(); |
| 153 | 185 |
| 154 EXPECT_CALL(*original_peer_, OnReceivedData(_, _, _)).Times(0); | 186 EXPECT_CALL(*original_peer_, OnReceivedDataInternal(_, _, _)).Times(0); |
| 155 EXPECT_CALL(*sender_, Send(_)).Times(0); | 187 EXPECT_CALL(*sender_, Send(_)).Times(0); |
| 156 | 188 |
| 157 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); | 189 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); |
| 158 EXPECT_CALL(*original_peer_, OnCompletedRequest( | 190 EXPECT_CALL(*original_peer_, OnCompletedRequest( |
| 159 net::OK, false, false, "", base::TimeTicks(), -1)); | 191 net::OK, false, false, "", base::TimeTicks(), -1)); |
| 160 | 192 |
| 161 filter_peer->OnCompletedRequest( | 193 filter_peer->OnCompletedRequest( |
| 162 net::OK, false, false, std::string(), base::TimeTicks(), -1); | 194 net::OK, false, false, std::string(), base::TimeTicks(), -1); |
| 163 } | 195 } |
| 164 | 196 |
| 165 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestNoCatalogs) { | 197 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestNoCatalogs) { |
| 166 // It will self-delete once it exits OnCompletedRequest. | 198 // It will self-delete once it exits OnCompletedRequest. |
| 167 ExtensionLocalizationPeer* filter_peer = filter_peer_.release(); | 199 ExtensionLocalizationPeer* filter_peer = filter_peer_.release(); |
| 168 | 200 |
| 169 SetData(filter_peer, "some text"); | 201 SetData(filter_peer, "some text"); |
| 170 | 202 |
| 171 EXPECT_CALL(*sender_, Send(_)); | 203 EXPECT_CALL(*sender_, Send(_)); |
| 172 | 204 |
| 173 std::string data = GetData(filter_peer); | 205 std::string data = GetData(filter_peer); |
| 174 EXPECT_CALL(*original_peer_, | 206 EXPECT_CALL(*original_peer_, |
| 175 OnReceivedData(StrEq(data.data()), data.length(), -1)).Times(2); | 207 OnReceivedDataInternal(StrEq(data.data()), data.length(), -1)) |
| 176 | 208 .Times(2); |
| 177 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)).Times(2); | 209 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)).Times(2); |
| 178 EXPECT_CALL(*original_peer_, OnCompletedRequest( | 210 EXPECT_CALL(*original_peer_, OnCompletedRequest( |
| 179 net::OK, false, false, "", base::TimeTicks(), -1)).Times(2); | 211 net::OK, false, false, "", base::TimeTicks(), -1)).Times(2); |
| 180 | 212 |
| 181 filter_peer->OnCompletedRequest( | 213 filter_peer->OnCompletedRequest( |
| 182 net::OK, false, false, std::string(), base::TimeTicks(), -1); | 214 net::OK, false, false, std::string(), base::TimeTicks(), -1); |
| 183 | 215 |
| 184 // Test if Send gets called again (it shouldn't be) when first call returned | 216 // Test if Send gets called again (it shouldn't be) when first call returned |
| 185 // an empty dictionary. | 217 // an empty dictionary. |
| 186 filter_peer = | 218 filter_peer = |
| (...skipping 15 matching lines...) Expand all Loading... |
| 202 l10n_messages_map["some_id2"] = messages; | 234 l10n_messages_map["some_id2"] = messages; |
| 203 | 235 |
| 204 SetData(filter_peer, "some __MSG_text__"); | 236 SetData(filter_peer, "some __MSG_text__"); |
| 205 | 237 |
| 206 // We already have messages in memory, Send will be skipped. | 238 // We already have messages in memory, Send will be skipped. |
| 207 EXPECT_CALL(*sender_, Send(_)).Times(0); | 239 EXPECT_CALL(*sender_, Send(_)).Times(0); |
| 208 | 240 |
| 209 // __MSG_text__ gets replaced with "new text". | 241 // __MSG_text__ gets replaced with "new text". |
| 210 std::string data("some new text"); | 242 std::string data("some new text"); |
| 211 EXPECT_CALL(*original_peer_, | 243 EXPECT_CALL(*original_peer_, |
| 212 OnReceivedData(StrEq(data.data()), data.length(), -1)); | 244 OnReceivedDataInternal(StrEq(data.data()), data.length(), -1)); |
| 213 | 245 |
| 214 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); | 246 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); |
| 215 EXPECT_CALL(*original_peer_, OnCompletedRequest( | 247 EXPECT_CALL(*original_peer_, OnCompletedRequest( |
| 216 net::OK, false, false, "", base::TimeTicks(), -1)); | 248 net::OK, false, false, "", base::TimeTicks(), -1)); |
| 217 | 249 |
| 218 filter_peer->OnCompletedRequest( | 250 filter_peer->OnCompletedRequest( |
| 219 net::OK, false, false, std::string(), base::TimeTicks(), -1); | 251 net::OK, false, false, std::string(), base::TimeTicks(), -1); |
| 220 } | 252 } |
| 221 | 253 |
| 222 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestReplaceMessagesFails) { | 254 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestReplaceMessagesFails) { |
| 223 // It will self-delete once it exits OnCompletedRequest. | 255 // It will self-delete once it exits OnCompletedRequest. |
| 224 ExtensionLocalizationPeer* filter_peer = | 256 ExtensionLocalizationPeer* filter_peer = |
| 225 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_3)); | 257 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_3)); |
| 226 | 258 |
| 227 extensions::L10nMessagesMap messages; | 259 extensions::L10nMessagesMap messages; |
| 228 messages.insert(std::make_pair("text", "new text")); | 260 messages.insert(std::make_pair("text", "new text")); |
| 229 extensions::ExtensionToL10nMessagesMap& l10n_messages_map = | 261 extensions::ExtensionToL10nMessagesMap& l10n_messages_map = |
| 230 *extensions::GetExtensionToL10nMessagesMap(); | 262 *extensions::GetExtensionToL10nMessagesMap(); |
| 231 l10n_messages_map["some_id3"] = messages; | 263 l10n_messages_map["some_id3"] = messages; |
| 232 | 264 |
| 233 std::string message("some __MSG_missing_message__"); | 265 std::string message("some __MSG_missing_message__"); |
| 234 SetData(filter_peer, message); | 266 SetData(filter_peer, message); |
| 235 | 267 |
| 236 // We already have messages in memory, Send will be skipped. | 268 // We already have messages in memory, Send will be skipped. |
| 237 EXPECT_CALL(*sender_, Send(_)).Times(0); | 269 EXPECT_CALL(*sender_, Send(_)).Times(0); |
| 238 | 270 |
| 239 // __MSG_missing_message__ is missing, so message stays the same. | 271 // __MSG_missing_message__ is missing, so message stays the same. |
| 240 EXPECT_CALL(*original_peer_, | 272 EXPECT_CALL(*original_peer_, OnReceivedDataInternal(StrEq(message.data()), |
| 241 OnReceivedData(StrEq(message.data()), message.length(), -1)); | 273 message.length(), -1)); |
| 242 | 274 |
| 243 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); | 275 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)); |
| 244 EXPECT_CALL(*original_peer_, OnCompletedRequest( | 276 EXPECT_CALL(*original_peer_, OnCompletedRequest( |
| 245 net::OK, false, false, "", base::TimeTicks(), -1)); | 277 net::OK, false, false, "", base::TimeTicks(), -1)); |
| 246 | 278 |
| 247 filter_peer->OnCompletedRequest( | 279 filter_peer->OnCompletedRequest( |
| 248 net::OK, false, false, std::string(), base::TimeTicks(), -1); | 280 net::OK, false, false, std::string(), base::TimeTicks(), -1); |
| 249 } | 281 } |
| OLD | NEW |