• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/extension_message_bundle.h"
10 #include "chrome/common/extensions/extension_localization_peer.h"
11 #include "ipc/ipc_message.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/glue/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 static_cast<IPC::SyncMessage*>(message)->GetReplyDeserializer();
36   delete message;
37 }
38 
39 class MockIpcMessageSender : public IPC::Message::Sender {
40  public:
MockIpcMessageSender()41   MockIpcMessageSender() {
42     ON_CALL(*this, Send(_))
43         .WillByDefault(DoAll(Invoke(MessageDeleter), Return(true)));
44   }
45 
~MockIpcMessageSender()46   virtual ~MockIpcMessageSender() {}
47 
48   MOCK_METHOD1(Send, bool(IPC::Message* message));
49 
50  private:
51   DISALLOW_COPY_AND_ASSIGN(MockIpcMessageSender);
52 };
53 
54 class MockResourceLoaderBridgePeer
55     : public webkit_glue::ResourceLoaderBridge::Peer {
56  public:
MockResourceLoaderBridgePeer()57   MockResourceLoaderBridgePeer() {}
~MockResourceLoaderBridgePeer()58   virtual ~MockResourceLoaderBridgePeer() {}
59 
60   MOCK_METHOD2(OnUploadProgress, void(uint64 position, uint64 size));
61   MOCK_METHOD4(OnReceivedRedirect, bool(
62       const GURL& new_url,
63       const webkit_glue::ResourceResponseInfo& info,
64       bool* has_new_first_party_for_cookies,
65       GURL* new_first_party_for_cookies));
66   MOCK_METHOD1(OnReceivedResponse, void(
67       const webkit_glue::ResourceResponseInfo& info));
68   MOCK_METHOD1(OnDownloadedData, void(int len));
69   MOCK_METHOD3(OnReceivedData, void(const char* data,
70                                     int data_length,
71                                     int encoded_data_length));
72   MOCK_METHOD3(OnCompletedRequest, void(
73       const net::URLRequestStatus& status,
74       const std::string& security_info,
75       const base::Time& 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     IsURLRequestEqual(net::URLRequestStatus::CANCELED), "", base::Time()));
146 
147   net::URLRequestStatus status;
148   status.set_status(net::URLRequestStatus::FAILED);
149   filter_peer->OnCompletedRequest(status, "", base::Time());
150 }
151 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestEmptyData)152 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestEmptyData) {
153   // It will self-delete once it exits OnCompletedRequest.
154   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
155 
156   EXPECT_CALL(*original_peer_, OnReceivedData(_, _, _)).Times(0);
157   EXPECT_CALL(*sender_, Send(_)).Times(0);
158 
159   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
160   EXPECT_CALL(*original_peer_, OnCompletedRequest(
161       IsURLRequestEqual(net::URLRequestStatus::SUCCESS), "", base::Time()));
162 
163   net::URLRequestStatus status;
164   status.set_status(net::URLRequestStatus::SUCCESS);
165   filter_peer->OnCompletedRequest(status, "", base::Time());
166 }
167 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestNoCatalogs)168 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestNoCatalogs) {
169   // It will self-delete once it exits OnCompletedRequest.
170   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
171 
172   SetData(filter_peer, "some text");
173 
174   EXPECT_CALL(*sender_, Send(_));
175 
176   std::string data = GetData(filter_peer);
177   EXPECT_CALL(*original_peer_,
178               OnReceivedData(StrEq(data.data()), data.length(), -1)).Times(2);
179 
180   EXPECT_CALL(*original_peer_, OnReceivedResponse(_)).Times(2);
181   EXPECT_CALL(*original_peer_, OnCompletedRequest(
182       IsURLRequestEqual(
183           net::URLRequestStatus::SUCCESS), "", base::Time())).Times(2);
184 
185   net::URLRequestStatus status;
186   status.set_status(net::URLRequestStatus::SUCCESS);
187   filter_peer->OnCompletedRequest(status, "", base::Time());
188 
189   // Test if Send gets called again (it shouldn't be) when first call returned
190   // an empty dictionary.
191   filter_peer =
192       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_1));
193   SetData(filter_peer, "some text");
194   filter_peer->OnCompletedRequest(status, "", base::Time());
195 }
196 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestWithCatalogs)197 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestWithCatalogs) {
198   // It will self-delete once it exits OnCompletedRequest.
199   ExtensionLocalizationPeer* filter_peer =
200       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_2));
201 
202   L10nMessagesMap messages;
203   messages.insert(std::make_pair("text", "new text"));
204   ExtensionToL10nMessagesMap& l10n_messages_map =
205       *GetExtensionToL10nMessagesMap();
206   l10n_messages_map["some_id2"] = messages;
207 
208   SetData(filter_peer, "some __MSG_text__");
209 
210   // We already have messages in memory, Send will be skipped.
211   EXPECT_CALL(*sender_, Send(_)).Times(0);
212 
213   // __MSG_text__ gets replaced with "new text".
214   std::string data("some new text");
215   EXPECT_CALL(*original_peer_,
216               OnReceivedData(StrEq(data.data()), data.length(), -1));
217 
218   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
219   EXPECT_CALL(*original_peer_, OnCompletedRequest(
220       IsURLRequestEqual(net::URLRequestStatus::SUCCESS), "", base::Time()));
221 
222   net::URLRequestStatus status;
223   status.set_status(net::URLRequestStatus::SUCCESS);
224   filter_peer->OnCompletedRequest(status, "", base::Time());
225 }
226 
TEST_F(ExtensionLocalizationPeerTest,OnCompletedRequestReplaceMessagesFails)227 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestReplaceMessagesFails) {
228   // It will self-delete once it exits OnCompletedRequest.
229   ExtensionLocalizationPeer* filter_peer =
230       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_3));
231 
232   L10nMessagesMap messages;
233   messages.insert(std::make_pair("text", "new text"));
234   ExtensionToL10nMessagesMap& l10n_messages_map =
235       *GetExtensionToL10nMessagesMap();
236   l10n_messages_map["some_id3"] = messages;
237 
238   std::string message("some __MSG_missing_message__");
239   SetData(filter_peer, message);
240 
241   // We already have messages in memory, Send will be skipped.
242   EXPECT_CALL(*sender_, Send(_)).Times(0);
243 
244   // __MSG_missing_message__ is missing, so message stays the same.
245   EXPECT_CALL(*original_peer_,
246               OnReceivedData(StrEq(message.data()), message.length(), -1));
247 
248   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
249   EXPECT_CALL(*original_peer_, OnCompletedRequest(
250       IsURLRequestEqual(net::URLRequestStatus::SUCCESS), "", base::Time()));
251 
252   net::URLRequestStatus status;
253   status.set_status(net::URLRequestStatus::SUCCESS);
254   filter_peer->OnCompletedRequest(status, "", base::Time());
255 }
256