• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include <map>
6 #include <string>
7 
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/common/extensions/message_bundle.h"
10 #include "chrome/renderer/extensions/extension_localization_peer.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"
17 #include "webkit/child/resource_loader_bridge.h"
18 
19 using testing::_;
20 using testing::DoAll;
21 using testing::Invoke;
22 using testing::StrEq;
23 using testing::Return;
24 
25 static const char* const kExtensionUrl_1 =
26     "chrome-extension://some_id/popup.css";
27 
28 static const char* const kExtensionUrl_2 =
29     "chrome-extension://some_id2/popup.css";
30 
31 static const char* const kExtensionUrl_3 =
32     "chrome-extension://some_id3/popup.css";
33 
MessageDeleter(IPC::Message * message)34 void MessageDeleter(IPC::Message* message) {
35   delete message;
36 }
37 
38 class MockIpcMessageSender : public IPC::Sender {
39  public:
MockIpcMessageSender()40   MockIpcMessageSender() {
41     ON_CALL(*this, Send(_))
42         .WillByDefault(DoAll(Invoke(MessageDeleter), Return(true)));
43   }
44 
~MockIpcMessageSender()45   virtual ~MockIpcMessageSender() {}
46 
47   MOCK_METHOD1(Send, bool(IPC::Message* message));
48 
49  private:
50   DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender);
51 };
52 
53 class MockResourceLoaderBridgePeer
54     : public webkit_glue::ResourceLoaderBridge::Peer {
55  public:
MockResourceLoaderBridgePeer()56   MockResourceLoaderBridgePeer() {}
~MockResourceLoaderBridgePeer()57   virtual ~MockResourceLoaderBridgePeer() {}
58 
59   MOCK_METHOD2(OnUploadProgress, void(uint64 position, uint64 size));
60   MOCK_METHOD4(OnReceivedRedirect, bool(
61       const GURL& new_url,
62       const webkit_glue::ResourceResponseInfo& info,
63       bool* has_new_first_party_for_cookies,
64       GURL* new_first_party_for_cookies));
65   MOCK_METHOD1(OnReceivedResponse, void(
66       const webkit_glue::ResourceResponseInfo& info));
67   MOCK_METHOD2(OnDownloadedData, void(int len, int encoded_data_length));
68   MOCK_METHOD3(OnReceivedData, void(const char* data,
69                                     int data_length,
70                                     int encoded_data_length));
71   MOCK_METHOD4(OnCompletedRequest, void(
72       int error_code,
73       bool was_ignored_by_handler,
74       const std::string& security_info,
75       const base::TimeTicks& completion_time));
76 
77  private:
78   DISALLOW_COPY_AND_ASSIGN(MockResourceLoaderBridgePeer);
79 };
80 
81 class ExtensionLocalizationPeerTest : public testing::Test {
82  protected:
SetUp()83   virtual void SetUp() {
84     sender_.reset(new MockIpcMessageSender());
85     original_peer_.reset(new MockResourceLoaderBridgePeer());
86     filter_peer_.reset(
87         ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
88             original_peer_.get(), sender_.get(), "text/css",
89             GURL(kExtensionUrl_1)));
90   }
91 
CreateExtensionLocalizationPeer(const std::string & mime_type,const GURL & request_url)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);
97   }
98 
GetData(ExtensionLocalizationPeer * filter_peer)99   std::string GetData(ExtensionLocalizationPeer* filter_peer) {
100     EXPECT_TRUE(NULL != filter_peer);
101     return filter_peer->data_;
102   }
103 
SetData(ExtensionLocalizationPeer * filter_peer,const std::string & data)104   void SetData(ExtensionLocalizationPeer* filter_peer,
105                const std::string& data) {
106     EXPECT_TRUE(NULL != filter_peer);
107     filter_peer->data_ = data;
108   }
109 
110   scoped_ptr<MockIpcMessageSender> sender_;
111   scoped_ptr<MockResourceLoaderBridgePeer> original_peer_;
112   scoped_ptr<ExtensionLocalizationPeer> filter_peer_;
113 };
114 
TEST_F(ExtensionLocalizationPeerTest,CreateWithWrongMimeType)115 TEST_F(ExtensionLocalizationPeerTest, CreateWithWrongMimeType) {
116   filter_peer_.reset(
117       CreateExtensionLocalizationPeer("text/html", GURL(kExtensionUrl_1)));
118   EXPECT_TRUE(NULL == filter_peer_.get());
119 }
120 
TEST_F(ExtensionLocalizationPeerTest,CreateWithValidInput)121 TEST_F(ExtensionLocalizationPeerTest, CreateWithValidInput) {
122   EXPECT_TRUE(NULL != filter_peer_.get());
123 }
124 
TEST_F(ExtensionLocalizationPeerTest,OnReceivedData)125 TEST_F(ExtensionLocalizationPeerTest, OnReceivedData) {
126   EXPECT_TRUE(GetData(filter_peer_.get()).empty());
127 
128   const std::string data_chunk("12345");
129   filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1);
130 
131   EXPECT_EQ(data_chunk, GetData(filter_peer_.get()));
132 
133   filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1);
134   EXPECT_EQ(data_chunk + data_chunk, GetData(filter_peer_.get()));
135 }
136 
137 MATCHER_P(IsURLRequestEqual, status, "") { return arg.status() == status; }
138 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestBadURLRequestStatus)139 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestBadURLRequestStatus) {
140   // It will self-delete once it exits OnCompletedRequest.
141   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
142 
143   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
144   EXPECT_CALL(*original_peer_, OnCompletedRequest(
145     net::ERR_ABORTED, false, "", base::TimeTicks()));
146 
147   filter_peer->OnCompletedRequest(
148       net::ERR_FAILED, false, std::string(), base::TimeTicks());
149 }
150 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestEmptyData)151 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestEmptyData) {
152   // It will self-delete once it exits OnCompletedRequest.
153   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
154 
155   EXPECT_CALL(*original_peer_, OnReceivedData(_, _, _)).Times(0);
156   EXPECT_CALL(*sender_, Send(_)).Times(0);
157 
158   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
159   EXPECT_CALL(*original_peer_, OnCompletedRequest(
160       net::OK, false, "", base::TimeTicks()));
161 
162   filter_peer->OnCompletedRequest(
163       net::OK, false, std::string(), base::TimeTicks());
164 }
165 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestNoCatalogs)166 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestNoCatalogs) {
167   // It will self-delete once it exits OnCompletedRequest.
168   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
169 
170   SetData(filter_peer, "some text");
171 
172   EXPECT_CALL(*sender_, Send(_));
173 
174   std::string data = GetData(filter_peer);
175   EXPECT_CALL(*original_peer_,
176               OnReceivedData(StrEq(data.data()), data.length(), -1)).Times(2);
177 
178   EXPECT_CALL(*original_peer_, OnReceivedResponse(_)).Times(2);
179   EXPECT_CALL(*original_peer_, OnCompletedRequest(
180           net::OK, false, "", base::TimeTicks())).Times(2);
181 
182   filter_peer->OnCompletedRequest(
183       net::OK, false, std::string(), base::TimeTicks());
184 
185   // Test if Send gets called again (it shouldn't be) when first call returned
186   // an empty dictionary.
187   filter_peer =
188       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_1));
189   SetData(filter_peer, "some text");
190   filter_peer->OnCompletedRequest(
191       net::OK, false, std::string(), base::TimeTicks());
192 }
193 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestWithCatalogs)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));
198 
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;
204 
205   SetData(filter_peer, "some __MSG_text__");
206 
207   // We already have messages in memory, Send will be skipped.
208   EXPECT_CALL(*sender_, Send(_)).Times(0);
209 
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));
214 
215   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
216   EXPECT_CALL(*original_peer_, OnCompletedRequest(
217       net::OK, false, "", base::TimeTicks()));
218 
219   filter_peer->OnCompletedRequest(
220       net::OK, false, std::string(), base::TimeTicks());
221 }
222 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestReplaceMessagesFails)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));
227 
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;
233 
234   std::string message("some __MSG_missing_message__");
235   SetData(filter_peer, message);
236 
237   // We already have messages in memory, Send will be skipped.
238   EXPECT_CALL(*sender_, Send(_)).Times(0);
239 
240   // __MSG_missing_message__ is missing, so message stays the same.
241   EXPECT_CALL(*original_peer_,
242               OnReceivedData(StrEq(message.data()), message.length(), -1));
243 
244   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
245   EXPECT_CALL(*original_peer_, OnCompletedRequest(
246       net::OK, false, "", base::TimeTicks()));
247 
248   filter_peer->OnCompletedRequest(
249       net::OK, false, std::string(), base::TimeTicks());
250 }
251