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
3 // found in the LICENSE file.
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/renderer/extensions/extension_localization_peer.h"
10 #include "extensions/common/message_bundle.h"
11 #include "ipc/ipc_sender.h"
12 #include "ipc/ipc_sync_message.h"
13 #include "net/base/net_errors.h"
14 #include "net/url_request/url_request_status.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::Invoke;
22 using testing::Return;
24 static const char* const kExtensionUrl_1 =
25 "chrome-extension://some_id/popup.css";
27 static const char* const kExtensionUrl_2 =
28 "chrome-extension://some_id2/popup.css";
30 static const char* const kExtensionUrl_3 =
31 "chrome-extension://some_id3/popup.css";
33 void MessageDeleter(IPC::Message* message) {
37 class MockIpcMessageSender : public IPC::Sender {
39 MockIpcMessageSender() {
40 ON_CALL(*this, Send(_))
41 .WillByDefault(DoAll(Invoke(MessageDeleter), Return(true)));
44 virtual ~MockIpcMessageSender() {}
46 MOCK_METHOD1(Send, bool(IPC::Message* message));
49 DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender);
52 class MockResourceLoaderBridgePeer : public content::RequestPeer {
54 MockResourceLoaderBridgePeer() {}
55 virtual ~MockResourceLoaderBridgePeer() {}
57 MOCK_METHOD2(OnUploadProgress, void(uint64 position, uint64 size));
58 MOCK_METHOD4(OnReceivedRedirect, bool(
60 const webkit_glue::ResourceResponseInfo& info,
61 bool* has_new_first_party_for_cookies,
62 GURL* new_first_party_for_cookies));
63 MOCK_METHOD1(OnReceivedResponse, void(
64 const webkit_glue::ResourceResponseInfo& info));
65 MOCK_METHOD2(OnDownloadedData, void(int len, int encoded_data_length));
66 MOCK_METHOD3(OnReceivedData, void(const char* data,
68 int encoded_data_length));
69 MOCK_METHOD6(OnCompletedRequest, void(
71 bool was_ignored_by_handler,
72 bool stale_copy_in_cache,
73 const std::string& security_info,
74 const base::TimeTicks& completion_time,
75 int64_t total_transfer_size));
78 DISALLOW_COPY_AND_ASSIGN(MockResourceLoaderBridgePeer);
81 class ExtensionLocalizationPeerTest : public testing::Test {
83 virtual void SetUp() {
84 sender_.reset(new MockIpcMessageSender());
85 original_peer_.reset(new MockResourceLoaderBridgePeer());
87 ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
88 original_peer_.get(), sender_.get(), "text/css",
89 GURL(kExtensionUrl_1)));
92 ExtensionLocalizationPeer* CreateExtensionLocalizationPeer(
93 const std::string& mime_type,
94 const GURL& request_url) {
95 return ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
96 original_peer_.get(), sender_.get(), mime_type, request_url);
99 std::string GetData(ExtensionLocalizationPeer* filter_peer) {
100 EXPECT_TRUE(NULL != filter_peer);
101 return filter_peer->data_;
104 void SetData(ExtensionLocalizationPeer* filter_peer,
105 const std::string& data) {
106 EXPECT_TRUE(NULL != filter_peer);
107 filter_peer->data_ = data;
110 scoped_ptr<MockIpcMessageSender> sender_;
111 scoped_ptr<MockResourceLoaderBridgePeer> original_peer_;
112 scoped_ptr<ExtensionLocalizationPeer> filter_peer_;
115 TEST_F(ExtensionLocalizationPeerTest, CreateWithWrongMimeType) {
117 CreateExtensionLocalizationPeer("text/html", GURL(kExtensionUrl_1)));
118 EXPECT_TRUE(NULL == filter_peer_.get());
121 TEST_F(ExtensionLocalizationPeerTest, CreateWithValidInput) {
122 EXPECT_TRUE(NULL != filter_peer_.get());
125 TEST_F(ExtensionLocalizationPeerTest, OnReceivedData) {
126 EXPECT_TRUE(GetData(filter_peer_.get()).empty());
128 const std::string data_chunk("12345");
129 filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1);
131 EXPECT_EQ(data_chunk, GetData(filter_peer_.get()));
133 filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1);
134 EXPECT_EQ(data_chunk + data_chunk, GetData(filter_peer_.get()));
137 MATCHER_P(IsURLRequestEqual, status, "") { return arg.status() == status; }
139 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestBadURLRequestStatus) {
140 // It will self-delete once it exits OnCompletedRequest.
141 ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
143 EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
144 EXPECT_CALL(*original_peer_, OnCompletedRequest(
145 net::ERR_ABORTED, false, false, "", base::TimeTicks(), -1));
147 filter_peer->OnCompletedRequest(
148 net::ERR_FAILED, false, false, std::string(), base::TimeTicks(), -1);
151 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestEmptyData) {
152 // It will self-delete once it exits OnCompletedRequest.
153 ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
155 EXPECT_CALL(*original_peer_, OnReceivedData(_, _, _)).Times(0);
156 EXPECT_CALL(*sender_, Send(_)).Times(0);
158 EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
159 EXPECT_CALL(*original_peer_, OnCompletedRequest(
160 net::OK, false, false, "", base::TimeTicks(), -1));
162 filter_peer->OnCompletedRequest(
163 net::OK, false, false, std::string(), base::TimeTicks(), -1);
166 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestNoCatalogs) {
167 // It will self-delete once it exits OnCompletedRequest.
168 ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
170 SetData(filter_peer, "some text");
172 EXPECT_CALL(*sender_, Send(_));
174 std::string data = GetData(filter_peer);
175 EXPECT_CALL(*original_peer_,
176 OnReceivedData(StrEq(data.data()), data.length(), -1)).Times(2);
178 EXPECT_CALL(*original_peer_, OnReceivedResponse(_)).Times(2);
179 EXPECT_CALL(*original_peer_, OnCompletedRequest(
180 net::OK, false, false, "", base::TimeTicks(), -1)).Times(2);
182 filter_peer->OnCompletedRequest(
183 net::OK, false, false, std::string(), base::TimeTicks(), -1);
185 // Test if Send gets called again (it shouldn't be) when first call returned
186 // an empty dictionary.
188 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_1));
189 SetData(filter_peer, "some text");
190 filter_peer->OnCompletedRequest(
191 net::OK, false, false, std::string(), base::TimeTicks(), -1);
194 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestWithCatalogs) {
195 // It will self-delete once it exits OnCompletedRequest.
196 ExtensionLocalizationPeer* filter_peer =
197 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_2));
199 extensions::L10nMessagesMap messages;
200 messages.insert(std::make_pair("text", "new text"));
201 extensions::ExtensionToL10nMessagesMap& l10n_messages_map =
202 *extensions::GetExtensionToL10nMessagesMap();
203 l10n_messages_map["some_id2"] = messages;
205 SetData(filter_peer, "some __MSG_text__");
207 // We already have messages in memory, Send will be skipped.
208 EXPECT_CALL(*sender_, Send(_)).Times(0);
210 // __MSG_text__ gets replaced with "new text".
211 std::string data("some new text");
212 EXPECT_CALL(*original_peer_,
213 OnReceivedData(StrEq(data.data()), data.length(), -1));
215 EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
216 EXPECT_CALL(*original_peer_, OnCompletedRequest(
217 net::OK, false, false, "", base::TimeTicks(), -1));
219 filter_peer->OnCompletedRequest(
220 net::OK, false, false, std::string(), base::TimeTicks(), -1);
223 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestReplaceMessagesFails) {
224 // It will self-delete once it exits OnCompletedRequest.
225 ExtensionLocalizationPeer* filter_peer =
226 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_3));
228 extensions::L10nMessagesMap messages;
229 messages.insert(std::make_pair("text", "new text"));
230 extensions::ExtensionToL10nMessagesMap& l10n_messages_map =
231 *extensions::GetExtensionToL10nMessagesMap();
232 l10n_messages_map["some_id3"] = messages;
234 std::string message("some __MSG_missing_message__");
235 SetData(filter_peer, message);
237 // We already have messages in memory, Send will be skipped.
238 EXPECT_CALL(*sender_, Send(_)).Times(0);
240 // __MSG_missing_message__ is missing, so message stays the same.
241 EXPECT_CALL(*original_peer_,
242 OnReceivedData(StrEq(message.data()), message.length(), -1));
244 EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
245 EXPECT_CALL(*original_peer_, OnCompletedRequest(
246 net::OK, false, false, "", base::TimeTicks(), -1));
248 filter_peer->OnCompletedRequest(
249 net::OK, false, false, std::string(), base::TimeTicks(), -1);