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 "content/public/child/fixed_received_data.h"
11 #include "extensions/common/message_bundle.h"
12 #include "ipc/ipc_sender.h"
13 #include "ipc/ipc_sync_message.h"
14 #include "net/base/net_errors.h"
15 #include "net/url_request/redirect_info.h"
16 #include "net/url_request/url_request_status.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
24 using testing::Invoke
;
26 using testing::Return
;
28 static const char* const kExtensionUrl_1
=
29 "chrome-extension://some_id/popup.css";
31 static const char* const kExtensionUrl_2
=
32 "chrome-extension://some_id2/popup.css";
34 static const char* const kExtensionUrl_3
=
35 "chrome-extension://some_id3/popup.css";
37 void MessageDeleter(IPC::Message
* message
) {
41 class MockIpcMessageSender
: public IPC::Sender
{
43 MockIpcMessageSender() {
44 ON_CALL(*this, Send(_
))
45 .WillByDefault(DoAll(Invoke(MessageDeleter
), Return(true)));
48 virtual ~MockIpcMessageSender() {}
50 MOCK_METHOD1(Send
, bool(IPC::Message
* message
));
53 DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender
);
56 class MockRequestPeer
: public content::RequestPeer
{
59 virtual ~MockRequestPeer() {}
61 MOCK_METHOD2(OnUploadProgress
, void(uint64 position
, uint64 size
));
62 MOCK_METHOD2(OnReceivedRedirect
,
63 bool(const net::RedirectInfo
& redirect_info
,
64 const content::ResourceResponseInfo
& info
));
65 MOCK_METHOD1(OnReceivedResponse
,
66 void(const content::ResourceResponseInfo
& info
));
67 MOCK_METHOD2(OnDownloadedData
, void(int len
, int encoded_data_length
));
68 void OnReceivedData(scoped_ptr
<RequestPeer::ReceivedData
> data
) override
{
69 OnReceivedDataInternal(data
->payload(), data
->length(),
70 data
->encoded_length());
72 MOCK_METHOD3(OnReceivedDataInternal
,
73 void(const char* data
,
75 int encoded_data_length
));
76 MOCK_METHOD6(OnCompletedRequest
, void(
78 bool was_ignored_by_handler
,
79 bool stale_copy_in_cache
,
80 const std::string
& security_info
,
81 const base::TimeTicks
& completion_time
,
82 int64_t total_transfer_size
));
83 void OnReceivedCompletedResponse(const content::ResourceResponseInfo
& info
,
84 scoped_ptr
<RequestPeer::ReceivedData
> data
,
86 bool was_ignored_by_handler
,
87 bool stale_copy_in_cache
,
88 const std::string
& security_info
,
89 const base::TimeTicks
& completion_time
,
90 int64_t total_transfer_size
) override
{
92 OnReceivedCompletedResponseInternal(
93 info
, data
->payload(), data
->length(), data
->encoded_length(),
94 error_code
, was_ignored_by_handler
, stale_copy_in_cache
,
95 security_info
, completion_time
, total_transfer_size
);
97 OnReceivedCompletedResponseInternal(info
, nullptr, 0, 0, error_code
,
98 was_ignored_by_handler
,
99 stale_copy_in_cache
, security_info
,
100 completion_time
, total_transfer_size
);
103 MOCK_METHOD10(OnReceivedCompletedResponseInternal
,
104 void(const content::ResourceResponseInfo
& info
,
107 int encoded_data_length
,
109 bool was_ignored_by_handler
,
110 bool stale_copy_in_cache
,
111 const std::string
& security_info
,
112 const base::TimeTicks
& completion_time
,
113 int64_t total_transfer_size
));
116 DISALLOW_COPY_AND_ASSIGN(MockRequestPeer
);
121 class ExtensionLocalizationPeerTest
: public testing::Test
{
123 void SetUp() override
{
124 sender_
.reset(new MockIpcMessageSender());
125 original_peer_
.reset(new MockRequestPeer());
127 ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
128 original_peer_
.get(), sender_
.get(), "text/css",
129 GURL(kExtensionUrl_1
)));
132 ExtensionLocalizationPeer
* CreateExtensionLocalizationPeer(
133 const std::string
& mime_type
,
134 const GURL
& request_url
) {
135 return ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
136 original_peer_
.get(), sender_
.get(), mime_type
, request_url
);
139 std::string
GetData(ExtensionLocalizationPeer
* filter_peer
) {
140 EXPECT_TRUE(NULL
!= filter_peer
);
141 return filter_peer
->data_
;
144 void SetData(ExtensionLocalizationPeer
* filter_peer
,
145 const std::string
& data
) {
146 EXPECT_TRUE(NULL
!= filter_peer
);
147 filter_peer
->data_
= data
;
150 scoped_ptr
<MockIpcMessageSender
> sender_
;
151 scoped_ptr
<MockRequestPeer
> original_peer_
;
152 scoped_ptr
<ExtensionLocalizationPeer
> filter_peer_
;
155 TEST_F(ExtensionLocalizationPeerTest
, CreateWithWrongMimeType
) {
157 CreateExtensionLocalizationPeer("text/html", GURL(kExtensionUrl_1
)));
158 EXPECT_TRUE(NULL
== filter_peer_
.get());
161 TEST_F(ExtensionLocalizationPeerTest
, CreateWithValidInput
) {
162 EXPECT_TRUE(NULL
!= filter_peer_
.get());
165 TEST_F(ExtensionLocalizationPeerTest
, OnReceivedData
) {
166 EXPECT_TRUE(GetData(filter_peer_
.get()).empty());
168 const std::string
data_chunk("12345");
169 filter_peer_
->OnReceivedData(make_scoped_ptr(new content::FixedReceivedData(
170 data_chunk
.data(), data_chunk
.length(), -1)));
172 EXPECT_EQ(data_chunk
, GetData(filter_peer_
.get()));
174 filter_peer_
->OnReceivedData(make_scoped_ptr(new content::FixedReceivedData(
175 data_chunk
.data(), data_chunk
.length(), -1)));
176 EXPECT_EQ(data_chunk
+ data_chunk
, GetData(filter_peer_
.get()));
179 MATCHER_P(IsURLRequestEqual
, status
, "") { return arg
.status() == status
; }
181 TEST_F(ExtensionLocalizationPeerTest
, OnCompletedRequestBadURLRequestStatus
) {
182 // It will self-delete once it exits OnCompletedRequest.
183 ExtensionLocalizationPeer
* filter_peer
= filter_peer_
.release();
185 EXPECT_CALL(*original_peer_
, OnReceivedCompletedResponseInternal(
186 _
, nullptr, 0, 0, net::ERR_ABORTED
, false,
187 false, "", base::TimeTicks(), -1));
189 filter_peer
->OnCompletedRequest(
190 net::ERR_FAILED
, false, false, std::string(), base::TimeTicks(), -1);
193 TEST_F(ExtensionLocalizationPeerTest
, OnCompletedRequestEmptyData
) {
194 // It will self-delete once it exits OnCompletedRequest.
195 ExtensionLocalizationPeer
* filter_peer
= filter_peer_
.release();
197 EXPECT_CALL(*original_peer_
, OnReceivedDataInternal(_
, _
, _
)).Times(0);
198 EXPECT_CALL(*sender_
, Send(_
)).Times(0);
200 EXPECT_CALL(*original_peer_
, OnReceivedCompletedResponseInternal(
201 _
, nullptr, 0, 0, net::OK
, false, false, "",
202 base::TimeTicks(), -1));
204 filter_peer
->OnCompletedRequest(
205 net::OK
, false, false, std::string(), base::TimeTicks(), -1);
208 TEST_F(ExtensionLocalizationPeerTest
, OnCompletedRequestNoCatalogs
) {
209 // It will self-delete once it exits OnCompletedRequest.
210 ExtensionLocalizationPeer
* filter_peer
= filter_peer_
.release();
212 SetData(filter_peer
, "some text");
214 EXPECT_CALL(*sender_
, Send(_
));
216 std::string data
= GetData(filter_peer
);
217 EXPECT_CALL(*original_peer_
,
218 OnReceivedCompletedResponseInternal(
219 _
, StrEq(data
.c_str()), data
.size(), -1, net::OK
, false,
220 false, "", base::TimeTicks(), -1)).Times(2);
222 filter_peer
->OnCompletedRequest(
223 net::OK
, false, false, std::string(), base::TimeTicks(), -1);
225 // Test if Send gets called again (it shouldn't be) when first call returned
226 // an empty dictionary.
228 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_1
));
229 SetData(filter_peer
, "some text");
230 filter_peer
->OnCompletedRequest(
231 net::OK
, false, false, std::string(), base::TimeTicks(), -1);
234 TEST_F(ExtensionLocalizationPeerTest
, OnCompletedRequestWithCatalogs
) {
235 // It will self-delete once it exits OnCompletedRequest.
236 ExtensionLocalizationPeer
* filter_peer
=
237 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_2
));
239 extensions::L10nMessagesMap messages
;
240 messages
.insert(std::make_pair("text", "new text"));
241 extensions::ExtensionToL10nMessagesMap
& l10n_messages_map
=
242 *extensions::GetExtensionToL10nMessagesMap();
243 l10n_messages_map
["some_id2"] = messages
;
245 SetData(filter_peer
, "some __MSG_text__");
247 // We already have messages in memory, Send will be skipped.
248 EXPECT_CALL(*sender_
, Send(_
)).Times(0);
250 // __MSG_text__ gets replaced with "new text".
251 std::string
data("some new text");
252 EXPECT_CALL(*original_peer_
,
253 OnReceivedCompletedResponseInternal(
254 _
, StrEq(data
.c_str()), data
.size(), -1, net::OK
, false,
255 false, std::string(), base::TimeTicks(), -1));
257 filter_peer
->OnCompletedRequest(
258 net::OK
, false, false, std::string(), base::TimeTicks(), -1);
261 TEST_F(ExtensionLocalizationPeerTest
, OnCompletedRequestReplaceMessagesFails
) {
262 // It will self-delete once it exits OnCompletedRequest.
263 ExtensionLocalizationPeer
* filter_peer
=
264 CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_3
));
266 extensions::L10nMessagesMap messages
;
267 messages
.insert(std::make_pair("text", "new text"));
268 extensions::ExtensionToL10nMessagesMap
& l10n_messages_map
=
269 *extensions::GetExtensionToL10nMessagesMap();
270 l10n_messages_map
["some_id3"] = messages
;
272 std::string
message("some __MSG_missing_message__");
273 SetData(filter_peer
, message
);
275 // We already have messages in memory, Send will be skipped.
276 EXPECT_CALL(*sender_
, Send(_
)).Times(0);
278 EXPECT_CALL(*original_peer_
,
279 OnReceivedCompletedResponseInternal(
280 _
, StrEq(message
.c_str()), message
.size(), -1, net::OK
, false,
281 false, "", base::TimeTicks(), -1));
283 filter_peer
->OnCompletedRequest(
284 net::OK
, false, false, std::string(), base::TimeTicks(), -1);