| Index: net/filter/sdch_policy_delegate_unittest.cc | 
| diff --git a/net/filter/sdch_policy_delegate_unittest.cc b/net/filter/sdch_policy_delegate_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..0c43162c52fa4b6fa1c03d0a94683eeb2581beea | 
| --- /dev/null | 
| +++ b/net/filter/sdch_policy_delegate_unittest.cc | 
| @@ -0,0 +1,192 @@ | 
| +// Copyright 2015 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "net/filter/sdch_policy_delegate.h" | 
| + | 
| +#include "base/memory/ptr_util.h" | 
| +#include "base/strings/string_util.h" | 
| +#include "net/filter/mock_stream_source.h" | 
| +#include "net/filter/sdch_stream_source.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace net { | 
| + | 
| +class TestContext : public SdchPolicyDelegate::Context { | 
| + public: | 
| +  TestContext() | 
| +      : mime_type_("text/plain"), | 
| +        url_("https://foobar.com"), | 
| +        response_code_(200), | 
| +        cached_content_(false) {} | 
| +  ~TestContext() override {} | 
| + | 
| +  bool GetMimeType(std::string* mime_type) const override { | 
| +    *mime_type = mime_type_; | 
| +    return !mime_type_.empty(); | 
| +  } | 
| + | 
| +  bool GetURL(GURL* url) const override { | 
| +    *url = url_; | 
| +    return !url_.is_empty(); | 
| +  } | 
| + | 
| +  base::Time GetRequestTime() const override { | 
| +    return base::Time::Now();  // XXX | 
| +  } | 
| + | 
| +  bool IsCachedContent() const override { | 
| +    return cached_content_;  // XXX | 
| +  } | 
| + | 
| +  SdchManager* GetSdchManager() const override { | 
| +    return const_cast<SdchManager*>(&manager_);  // XXX | 
| +  } | 
| + | 
| +  SdchManager::DictionarySet* SdchDictionariesAdvertised() const override { | 
| +    return nullptr;  // XXX | 
| +  } | 
| + | 
| +  int64_t GetByteReadCount() const override { | 
| +    return 0;  // XXX | 
| +  } | 
| + | 
| +  int GetResponseCode() const override { return response_code_; } | 
| + | 
| +  void RecordPacketStats(StatisticSelector statistic) const override { | 
| +    // XXX | 
| +  } | 
| + | 
| +  const BoundNetLog& GetNetLog() const override { return net_log_; } | 
| + | 
| +  void set_mime_type(const std::string& mime_type) { mime_type_ = mime_type; } | 
| + | 
| +  void set_url(const GURL& url) { url_ = url; } | 
| + | 
| +  void set_response_code(int response_code) { response_code_ = response_code; } | 
| + | 
| +  void set_cached_content(bool cached_content) { | 
| +    cached_content_ = cached_content; | 
| +  } | 
| + | 
| +  bool IsDomainBlackListed() { | 
| +    return manager_.BlackListDomainCount(url_.host()); | 
| +  } | 
| + | 
| + private: | 
| +  std::string mime_type_; | 
| +  GURL url_; | 
| +  int response_code_; | 
| +  bool cached_content_; | 
| +  SdchManager manager_; | 
| +  BoundNetLog net_log_; | 
| +}; | 
| + | 
| +class MockSdchStreamSource : public SdchStreamSource { | 
| + public: | 
| +  MockSdchStreamSource() | 
| +      : SdchStreamSource(base::WrapUnique(new MockStreamSource()), nullptr), | 
| +        stopped_decoding_(false), | 
| +        replaced_output_(false) {} | 
| +  ~MockSdchStreamSource() override {} | 
| + | 
| +  void StopDecoding() override { stopped_decoding_ = true; } | 
| +  void ReplaceOutput(const char* data, size_t size) override { | 
| +    replaced_output_ = true; | 
| +    output_ = std::string(data, size); | 
| +  } | 
| + | 
| +  bool stopped_decoding() { return stopped_decoding_; } | 
| +  bool replaced_output() { return replaced_output_; } | 
| +  std::string output() { return output_; } | 
| + | 
| +  bool DidGetMetaRefresh() { | 
| +    std::string output = base::ToLowerASCII(output_); | 
| +    return replaced_output_ && output.find("refresh") != output.npos; | 
| +  } | 
| + | 
| + private: | 
| +  bool stopped_decoding_; | 
| +  bool replaced_output_; | 
| +  std::string output_; | 
| +}; | 
| + | 
| +class SdchPolicyDelegateTest : public ::testing::Test { | 
| + public: | 
| +  SdchPolicyDelegateTest() {} | 
| +  void SetUp() override { | 
| +    ::testing::Test::SetUp(); | 
| + | 
| +    // Ownership of context_ is given to delegate_ but this class retains a | 
| +    // pointer to it anyway for testing. | 
| +    context_ = new TestContext(); | 
| +    delegate_.reset(new SdchPolicyDelegate(base::WrapUnique(context_))); | 
| +    source_.reset(new MockSdchStreamSource); | 
| +  } | 
| + | 
| + protected: | 
| +  TestContext* context_; | 
| +  std::unique_ptr<SdchPolicyDelegate> delegate_; | 
| +  std::unique_ptr<MockSdchStreamSource> source_; | 
| +}; | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, Http404DictionaryErrorNotDecoded) { | 
| +  context_->set_response_code(404); | 
| +  EXPECT_TRUE(delegate_->HandleDictionaryError(source_.get())); | 
| +  EXPECT_TRUE(source_->stopped_decoding()); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, HttpNon404HtmlErrorDictionaryErrorBlacklists) { | 
| +  context_->set_mime_type("text/html"); | 
| +  context_->set_response_code(403); | 
| +  EXPECT_TRUE(delegate_->HandleDictionaryError(source_.get())); | 
| +  EXPECT_TRUE(source_->DidGetMetaRefresh()); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, HttpNon404TextErrorDictionaryErrorFails) { | 
| +  context_->set_mime_type("text/plain"); | 
| +  context_->set_response_code(403); | 
| +  EXPECT_FALSE(delegate_->HandleDictionaryError(source_.get())); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, CachedUnencodedDictionaryErrorStopsDecoding) { | 
| +  context_->set_cached_content(true); | 
| +  EXPECT_TRUE(delegate_->HandleDictionaryError(source_.get())); | 
| +  EXPECT_TRUE(source_->stopped_decoding()); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, CachedEncodedDictionaryErrorGetsRefresh) { | 
| +  context_->set_cached_content(true); | 
| +  context_->set_mime_type("text/html"); | 
| +  EXPECT_FALSE(delegate_->GetDictionary("abcdefgh", nullptr)); | 
| +  EXPECT_TRUE(delegate_->HandleDictionaryError(source_.get())); | 
| +  EXPECT_TRUE(source_->DidGetMetaRefresh()); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, CachedHtmlDecodingErrorDoesNotBlacklist) { | 
| +  context_->set_mime_type("text/html"); | 
| +  context_->set_cached_content(true); | 
| +  EXPECT_FALSE(context_->IsDomainBlackListed()); | 
| +  EXPECT_TRUE(delegate_->HandleDecodingError(source_.get())); | 
| +  EXPECT_TRUE(source_->replaced_output()); | 
| +  EXPECT_FALSE(context_->IsDomainBlackListed()); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, HtmlDecodingErrorGetsMetaRefresh) { | 
| +  context_->set_mime_type("text/html"); | 
| +  EXPECT_FALSE(context_->IsDomainBlackListed()); | 
| +  EXPECT_TRUE(delegate_->HandleDecodingError(source_.get())); | 
| +  EXPECT_TRUE(source_->DidGetMetaRefresh()); | 
| +  EXPECT_TRUE(context_->IsDomainBlackListed()); | 
| +} | 
| + | 
| +TEST_F(SdchPolicyDelegateTest, NonHtmlDecodingErrorGetsError) { | 
| +  context_->set_mime_type("text/plain"); | 
| +  EXPECT_FALSE(context_->IsDomainBlackListed()); | 
| +  EXPECT_FALSE(delegate_->HandleDecodingError(source_.get())); | 
| +  EXPECT_FALSE(source_->replaced_output()); | 
| +  EXPECT_FALSE(source_->stopped_decoding()); | 
| +  EXPECT_TRUE(context_->IsDomainBlackListed()); | 
| +} | 
| + | 
| +}  // namespace net | 
|  |