Home | History | Annotate | Download | only in extensions
      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/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/redirect_info.h"
     15 #include "net/url_request/url_request_status.h"
     16 #include "testing/gmock/include/gmock/gmock.h"
     17 #include "testing/gtest/include/gtest/gtest.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 
     34 void MessageDeleter(IPC::Message* message) {
     35   delete message;
     36 }
     37 
     38 class MockIpcMessageSender : public IPC::Sender {
     39  public:
     40   MockIpcMessageSender() {
     41     ON_CALL(*this, Send(_))
     42         .WillByDefault(DoAll(Invoke(MessageDeleter), Return(true)));
     43   }
     44 
     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 MockRequestPeer : public content::RequestPeer {
     54  public:
     55   MockRequestPeer() {}
     56   virtual ~MockRequestPeer() {}
     57 
     58   MOCK_METHOD2(OnUploadProgress, void(uint64 position, uint64 size));
     59   MOCK_METHOD2(OnReceivedRedirect,
     60                bool(const net::RedirectInfo& redirect_info,
     61                     const content::ResourceResponseInfo& info));
     62   MOCK_METHOD1(OnReceivedResponse,
     63                void(const content::ResourceResponseInfo& info));
     64   MOCK_METHOD2(OnDownloadedData, void(int len, int encoded_data_length));
     65   MOCK_METHOD3(OnReceivedData, void(const char* data,
     66                                     int data_length,
     67                                     int encoded_data_length));
     68   MOCK_METHOD6(OnCompletedRequest, void(
     69       int error_code,
     70       bool was_ignored_by_handler,
     71       bool stale_copy_in_cache,
     72       const std::string& security_info,
     73       const base::TimeTicks& completion_time,
     74       int64_t total_transfer_size));
     75 
     76  private:
     77   DISALLOW_COPY_AND_ASSIGN(MockRequestPeer);
     78 };
     79 
     80 class ExtensionLocalizationPeerTest : public testing::Test {
     81  protected:
     82   virtual void SetUp() {
     83     sender_.reset(new MockIpcMessageSender());
     84     original_peer_.reset(new MockRequestPeer());
     85     filter_peer_.reset(
     86         ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
     87             original_peer_.get(), sender_.get(), "text/css",
     88             GURL(kExtensionUrl_1)));
     89   }
     90 
     91   ExtensionLocalizationPeer* CreateExtensionLocalizationPeer(
     92       const std::string& mime_type,
     93       const GURL& request_url) {
     94     return ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
     95         original_peer_.get(), sender_.get(), mime_type, request_url);
     96   }
     97 
     98   std::string GetData(ExtensionLocalizationPeer* filter_peer) {
     99     EXPECT_TRUE(NULL != filter_peer);
    100     return filter_peer->data_;
    101   }
    102 
    103   void SetData(ExtensionLocalizationPeer* filter_peer,
    104                const std::string& data) {
    105     EXPECT_TRUE(NULL != filter_peer);
    106     filter_peer->data_ = data;
    107   }
    108 
    109   scoped_ptr<MockIpcMessageSender> sender_;
    110   scoped_ptr<MockRequestPeer> original_peer_;
    111   scoped_ptr<ExtensionLocalizationPeer> filter_peer_;
    112 };
    113 
    114 TEST_F(ExtensionLocalizationPeerTest, CreateWithWrongMimeType) {
    115   filter_peer_.reset(
    116       CreateExtensionLocalizationPeer("text/html", GURL(kExtensionUrl_1)));
    117   EXPECT_TRUE(NULL == filter_peer_.get());
    118 }
    119 
    120 TEST_F(ExtensionLocalizationPeerTest, CreateWithValidInput) {
    121   EXPECT_TRUE(NULL != filter_peer_.get());
    122 }
    123 
    124 TEST_F(ExtensionLocalizationPeerTest, OnReceivedData) {
    125   EXPECT_TRUE(GetData(filter_peer_.get()).empty());
    126 
    127   const std::string data_chunk("12345");
    128   filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1);
    129 
    130   EXPECT_EQ(data_chunk, GetData(filter_peer_.get()));
    131 
    132   filter_peer_->OnReceivedData(data_chunk.c_str(), data_chunk.length(), -1);
    133   EXPECT_EQ(data_chunk + data_chunk, GetData(filter_peer_.get()));
    134 }
    135 
    136 MATCHER_P(IsURLRequestEqual, status, "") { return arg.status() == status; }
    137 
    138 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestBadURLRequestStatus) {
    139   // It will self-delete once it exits OnCompletedRequest.
    140   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
    141 
    142   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
    143   EXPECT_CALL(*original_peer_, OnCompletedRequest(
    144       net::ERR_ABORTED, false, false, "", base::TimeTicks(), -1));
    145 
    146   filter_peer->OnCompletedRequest(
    147       net::ERR_FAILED, false, false, std::string(), base::TimeTicks(), -1);
    148 }
    149 
    150 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestEmptyData) {
    151   // It will self-delete once it exits OnCompletedRequest.
    152   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
    153 
    154   EXPECT_CALL(*original_peer_, OnReceivedData(_, _, _)).Times(0);
    155   EXPECT_CALL(*sender_, Send(_)).Times(0);
    156 
    157   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
    158   EXPECT_CALL(*original_peer_, OnCompletedRequest(
    159       net::OK, false, false, "", base::TimeTicks(), -1));
    160 
    161   filter_peer->OnCompletedRequest(
    162       net::OK, false, false, std::string(), base::TimeTicks(), -1);
    163 }
    164 
    165 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestNoCatalogs) {
    166   // It will self-delete once it exits OnCompletedRequest.
    167   ExtensionLocalizationPeer* filter_peer = filter_peer_.release();
    168 
    169   SetData(filter_peer, "some text");
    170 
    171   EXPECT_CALL(*sender_, Send(_));
    172 
    173   std::string data = GetData(filter_peer);
    174   EXPECT_CALL(*original_peer_,
    175               OnReceivedData(StrEq(data.data()), data.length(), -1)).Times(2);
    176 
    177   EXPECT_CALL(*original_peer_, OnReceivedResponse(_)).Times(2);
    178   EXPECT_CALL(*original_peer_, OnCompletedRequest(
    179       net::OK, false, false, "", base::TimeTicks(), -1)).Times(2);
    180 
    181   filter_peer->OnCompletedRequest(
    182       net::OK, false, false, std::string(), base::TimeTicks(), -1);
    183 
    184   // Test if Send gets called again (it shouldn't be) when first call returned
    185   // an empty dictionary.
    186   filter_peer =
    187       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_1));
    188   SetData(filter_peer, "some text");
    189   filter_peer->OnCompletedRequest(
    190       net::OK, false, false, std::string(), base::TimeTicks(), -1);
    191 }
    192 
    193 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestWithCatalogs) {
    194   // It will self-delete once it exits OnCompletedRequest.
    195   ExtensionLocalizationPeer* filter_peer =
    196       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_2));
    197 
    198   extensions::L10nMessagesMap messages;
    199   messages.insert(std::make_pair("text", "new text"));
    200   extensions::ExtensionToL10nMessagesMap& l10n_messages_map =
    201       *extensions::GetExtensionToL10nMessagesMap();
    202   l10n_messages_map["some_id2"] = messages;
    203 
    204   SetData(filter_peer, "some __MSG_text__");
    205 
    206   // We already have messages in memory, Send will be skipped.
    207   EXPECT_CALL(*sender_, Send(_)).Times(0);
    208 
    209   // __MSG_text__ gets replaced with "new text".
    210   std::string data("some new text");
    211   EXPECT_CALL(*original_peer_,
    212               OnReceivedData(StrEq(data.data()), data.length(), -1));
    213 
    214   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
    215   EXPECT_CALL(*original_peer_, OnCompletedRequest(
    216       net::OK, false, false, "", base::TimeTicks(), -1));
    217 
    218   filter_peer->OnCompletedRequest(
    219       net::OK, false, false, std::string(), base::TimeTicks(), -1);
    220 }
    221 
    222 TEST_F(ExtensionLocalizationPeerTest, OnCompletedRequestReplaceMessagesFails) {
    223   // It will self-delete once it exits OnCompletedRequest.
    224   ExtensionLocalizationPeer* filter_peer =
    225       CreateExtensionLocalizationPeer("text/css", GURL(kExtensionUrl_3));
    226 
    227   extensions::L10nMessagesMap messages;
    228   messages.insert(std::make_pair("text", "new text"));
    229   extensions::ExtensionToL10nMessagesMap& l10n_messages_map =
    230       *extensions::GetExtensionToL10nMessagesMap();
    231   l10n_messages_map["some_id3"] = messages;
    232 
    233   std::string message("some __MSG_missing_message__");
    234   SetData(filter_peer, message);
    235 
    236   // We already have messages in memory, Send will be skipped.
    237   EXPECT_CALL(*sender_, Send(_)).Times(0);
    238 
    239   // __MSG_missing_message__ is missing, so message stays the same.
    240   EXPECT_CALL(*original_peer_,
    241               OnReceivedData(StrEq(message.data()), message.length(), -1));
    242 
    243   EXPECT_CALL(*original_peer_, OnReceivedResponse(_));
    244   EXPECT_CALL(*original_peer_, OnCompletedRequest(
    245       net::OK, false, false, "", base::TimeTicks(), -1));
    246 
    247   filter_peer->OnCompletedRequest(
    248       net::OK, false, false, std::string(), base::TimeTicks(), -1);
    249 }
    250