// Copyright 2014 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 <limits.h>

#include <string>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_clock.h"
#include "net/base/sdch_manager.h"
#include "net/base/sdch_observer.h"
#include "net/log/net_log.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace net {

//------------------------------------------------------------------------------
// Provide sample data and compression results with a sample VCDIFF dictionary.
// Note an SDCH dictionary has extra meta-data before the VCDIFF dictionary.
static const char kTestVcdiffDictionary[] = "DictionaryFor"
    "SdchCompression1SdchCompression2SdchCompression3SdchCompression\n";

//------------------------------------------------------------------------------

class MockSdchObserver : public SdchObserver {
 public:
  MockSdchObserver()
      : dictionary_added_notifications_(0),
        dictionary_removed_notifications_(0),
        dictionary_used_notifications_(0),
        get_dictionary_notifications_(0),
        clear_dictionaries_notifications_(0) {}

  int dictionary_added_notifications() const {
    return dictionary_added_notifications_;
  }
  int dictionary_removed_notifications() const {
    return dictionary_removed_notifications_;
  }
  std::string last_server_hash() const { return last_server_hash_; }
  int dictionary_used_notifications() const {
    return dictionary_used_notifications_;
  }
  const GURL& last_dictionary_request_url() const {
    return last_dictionary_request_url_;
  }
  const GURL& last_dictionary_url() const { return last_dictionary_url_; }
  int get_dictionary_notifications() const {
    return get_dictionary_notifications_;
  }

  int clear_dictionary_notifications() const {
    return clear_dictionaries_notifications_;
  }

  // SdchObserver implementation
  void OnDictionaryAdded(const GURL& dictionary_url,
                         const std::string& server_hash) override {
    last_server_hash_ = server_hash;
    last_dictionary_url_ = dictionary_url;
    ++dictionary_added_notifications_;
  }
  void OnDictionaryRemoved(const std::string& server_hash) override {
    last_server_hash_ = server_hash;
    ++dictionary_removed_notifications_;
  }
  void OnDictionaryUsed(const std::string& server_hash) override {
    last_server_hash_ = server_hash;
    ++dictionary_used_notifications_;
  }

  void OnGetDictionary(const GURL& request_url,
                       const GURL& dictionary_url) override {
    ++get_dictionary_notifications_;
    last_dictionary_request_url_ = request_url;
    last_dictionary_url_ = dictionary_url;
  }
  void OnClearDictionaries() override {
    ++clear_dictionaries_notifications_;
  }

 private:
  int dictionary_added_notifications_;
  int dictionary_removed_notifications_;
  int dictionary_used_notifications_;
  int get_dictionary_notifications_;
  int clear_dictionaries_notifications_;

  std::string last_server_hash_;
  GURL last_dictionary_request_url_;
  GURL last_dictionary_url_;

  DISALLOW_COPY_AND_ASSIGN(MockSdchObserver);
};

class SdchManagerTest : public testing::Test {
 protected:
  SdchManagerTest()
      : sdch_manager_(new SdchManager),
        default_support_(sdch_manager_->sdch_enabled()) { }

  ~SdchManagerTest() override {}

  SdchManager* sdch_manager() { return sdch_manager_.get(); }

  // Reset globals back to default state.
  void TearDown() override {
    SdchManager::EnableSdchSupport(default_support_);
  }

  // Attempt to add a dictionary to the manager and probe for success or
  // failure.
  bool AddSdchDictionary(const std::string& dictionary_text,
                         const GURL& gurl) {
    return sdch_manager_->AddSdchDictionary(dictionary_text, gurl, nullptr) ==
           SDCH_OK;
  }

 private:
  scoped_ptr<SdchManager> sdch_manager_;
  bool default_support_;
};

static std::string NewSdchDictionary(const std::string& domain) {
  std::string dictionary;
  if (!domain.empty()) {
    dictionary.append("Domain: ");
    dictionary.append(domain);
    dictionary.append("\n");
  }
  dictionary.append("\n");
  dictionary.append(kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1);
  return dictionary;
}

TEST_F(SdchManagerTest, DomainSupported) {
  GURL google_url("http://www.google.com");

  SdchManager::EnableSdchSupport(false);
  EXPECT_EQ(SDCH_DISABLED, sdch_manager()->IsInSupportedDomain(google_url));
  SdchManager::EnableSdchSupport(true);
  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(google_url));
}

TEST_F(SdchManagerTest, DomainBlacklisting) {
  GURL test_url("http://www.test.com");
  GURL google_url("http://www.google.com");

  sdch_manager()->BlacklistDomain(test_url, SDCH_OK);
  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
            sdch_manager()->IsInSupportedDomain(test_url));
  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(google_url));

  sdch_manager()->BlacklistDomain(google_url, SDCH_OK);
  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
            sdch_manager()->IsInSupportedDomain(google_url));
}

TEST_F(SdchManagerTest, DomainBlacklistingCaseSensitivity) {
  GURL test_url("http://www.TesT.com");
  GURL test2_url("http://www.tEst.com");

  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(test_url));
  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(test2_url));
  sdch_manager()->BlacklistDomain(test_url, SDCH_OK);
  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
            sdch_manager()->IsInSupportedDomain(test2_url));
}

TEST_F(SdchManagerTest, BlacklistingReset) {
  GURL gurl("http://mytest.DoMain.com");
  std::string domain(gurl.host());

  sdch_manager()->ClearBlacklistings();
  EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
  EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 0);
  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl));
}

TEST_F(SdchManagerTest, BlacklistingSingleBlacklist) {
  GURL gurl("http://mytest.DoMain.com");
  std::string domain(gurl.host());
  sdch_manager()->ClearBlacklistings();

  sdch_manager()->BlacklistDomain(gurl, SDCH_OK);
  EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 1);
  EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 1);

  // Check that any domain lookup reduces the blacklist counter.
  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
            sdch_manager()->IsInSupportedDomain(gurl));
  EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl));
}

TEST_F(SdchManagerTest, BlacklistingExponential) {
  GURL gurl("http://mytest.DoMain.com");
  std::string domain(gurl.host());
  sdch_manager()->ClearBlacklistings();

  int exponential = 1;
  for (int i = 1; i < 100; ++i) {
    sdch_manager()->BlacklistDomain(gurl, SDCH_OK);
    EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), exponential);

    EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential);
    EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
              sdch_manager()->IsInSupportedDomain(gurl));
    EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential - 1);

    // Simulate a large number of domain checks (which eventually remove the
    // blacklisting).
    sdch_manager()->ClearDomainBlacklisting(domain);
    EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
    EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl));

    // Predict what exponential backoff will be.
    exponential = 1 + 2 * exponential;
    if (exponential < 0)
      exponential = INT_MAX;  // We don't wrap.
  }
}

TEST_F(SdchManagerTest, CanSetExactMatchDictionary) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Perfect match should work.
  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://" + dictionary_domain)));
}

TEST_F(SdchManagerTest, CanAdvertiseDictionaryOverHTTP) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://" + dictionary_domain)));

  // HTTP target URL can advertise dictionary.
  EXPECT_TRUE(sdch_manager()->GetDictionarySet(
      GURL("http://" + dictionary_domain + "/test")));
}

TEST_F(SdchManagerTest, CanNotAdvertiseDictionaryOverHTTPS) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://" + dictionary_domain)));

  // HTTPS target URL should NOT advertise dictionary.
  EXPECT_FALSE(sdch_manager()->GetDictionarySet(
      GURL("https://" + dictionary_domain + "/test")));
}

TEST_F(SdchManagerTest, CanUseHTTPSDictionaryOverHTTPSIfEnabled) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("https://" + dictionary_domain)));

  GURL target_url("https://" + dictionary_domain + "/test");
  // HTTPS target URL should advertise dictionary if secure scheme support is
  // enabled.
  EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_url));

  // Dictionary should be available.
  std::string client_hash;
  std::string server_hash;
  sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
  SdchProblemCode problem_code;
  scoped_ptr<SdchManager::DictionarySet> dict_set(
      sdch_manager()->GetDictionarySetByHash(
          target_url, server_hash, &problem_code));
  EXPECT_EQ(SDCH_OK, problem_code);
  EXPECT_TRUE(dict_set.get());
  EXPECT_TRUE(dict_set->GetDictionaryText(server_hash));
}

TEST_F(SdchManagerTest, CanNotUseHTTPDictionaryOverHTTPS) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://" + dictionary_domain)));

  GURL target_url("https://" + dictionary_domain + "/test");
  // HTTPS target URL should not advertise dictionary acquired over HTTP even if
  // secure scheme support is enabled.
  EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url));

  std::string client_hash;
  std::string server_hash;
  sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
  SdchProblemCode problem_code;
  scoped_ptr<SdchManager::DictionarySet> dict_set(
      sdch_manager()->GetDictionarySetByHash(
          target_url, server_hash, &problem_code));
  EXPECT_FALSE(dict_set.get());
  EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME, problem_code);
}

TEST_F(SdchManagerTest, CanNotUseHTTPSDictionaryOverHTTP) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("https://" + dictionary_domain)));

  GURL target_url("http://" + dictionary_domain + "/test");
  // HTTP target URL should not advertise dictionary acquired over HTTPS even if
  // secure scheme support is enabled.
  EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_url));

  std::string client_hash;
  std::string server_hash;
  sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
  SdchProblemCode problem_code;
  scoped_ptr<SdchManager::DictionarySet> dict_set(
      sdch_manager()->GetDictionarySetByHash(
          target_url, server_hash, &problem_code));
  EXPECT_FALSE(dict_set.get());
  EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME, problem_code);
}

TEST_F(SdchManagerTest, FailToSetDomainMismatchDictionary) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Fail the "domain match" requirement.
  EXPECT_FALSE(AddSdchDictionary(dictionary_text,
                                 GURL("http://y.z.google.com")));
}

TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionary) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Fail the HD with D being the domain and H having a dot requirement.
  EXPECT_FALSE(AddSdchDictionary(dictionary_text,
                                 GURL("http://w.x.y.z.google.com")));
}

TEST_F(SdchManagerTest, FailToSetDotHostPrefixDomainDictionaryTrailingDot) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Fail the HD with D being the domain and H having a dot requirement.
  EXPECT_FALSE(AddSdchDictionary(dictionary_text,
                                 GURL("http://w.x.y.z.google.com.")));
}

TEST_F(SdchManagerTest, FailToSetRepeatPrefixWithDotDictionary) {
  // Make sure that a prefix that matches the domain postfix won't confuse
  // the validation checks.
  std::string dictionary_domain("www.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Fail the HD with D being the domain and H having a dot requirement.
  EXPECT_FALSE(AddSdchDictionary(dictionary_text,
                                 GURL("http://www.google.com.www.google.com")));
}

TEST_F(SdchManagerTest, CanSetLeadingDotDomainDictionary) {
  // Make sure that a prefix that matches the domain postfix won't confuse
  // the validation checks.
  std::string dictionary_domain(".google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Verify that a leading dot in the domain is acceptable, as long as the host
  // name does not contain any dots preceding the matched domain name.
  EXPECT_TRUE(AddSdchDictionary(dictionary_text, GURL("http://www.google.com")));
}

TEST_F(SdchManagerTest,
       CanSetLeadingDotDomainDictionaryFromURLWithTrailingDot) {
  // Make sure that a prefix that matches the domain postfix won't confuse
  // the validation checks.
  std::string dictionary_domain(".google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Verify that a leading dot in the domain is acceptable, as long as the host
  // name does not contain any dots preceding the matched domain name.
  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://www.google.com.")));
}

TEST_F(SdchManagerTest, CannotSetLeadingDotDomainDictionary) {
  // Make sure that a prefix that matches the domain postfix won't confuse
  // the validation checks.
  std::string dictionary_domain(".google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Verify that a leading dot in the domain does not affect the name containing
  // dots failure.
  EXPECT_FALSE(AddSdchDictionary(dictionary_text,
                                 GURL("http://www.subdomain.google.com")));
}

TEST_F(SdchManagerTest, CannotSetLeadingDotDomainDictionaryTrailingDot) {
  // Make sure that a prefix that matches the domain postfix won't confuse
  // the validation checks.
  std::string dictionary_domain(".google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Verify that a trailing period in the URL doesn't affect the check.
  EXPECT_FALSE(AddSdchDictionary(dictionary_text,
                                 GURL("http://www.subdomain.google.com.")));
}

// Make sure the order of the tests is not helping us or confusing things.
// See test CanSetExactMatchDictionary above for first try.
TEST_F(SdchManagerTest, CanStillSetExactMatchDictionary) {
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));

  // Perfect match should *STILL* work.
  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://" + dictionary_domain)));
}

// The following are only applicable while we have a latency test in the code,
// and can be removed when that functionality is stripped.
TEST_F(SdchManagerTest, LatencyTestControls) {
  GURL url("http://www.google.com");
  GURL url2("http://www.google2.com");

  // First make sure we default to false.
  EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url));
  EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2));

  // That we can set each to true.
  sdch_manager()->SetAllowLatencyExperiment(url, true);
  EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url));
  EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2));

  sdch_manager()->SetAllowLatencyExperiment(url2, true);
  EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url));
  EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2));

  // And can reset them to false.
  sdch_manager()->SetAllowLatencyExperiment(url, false);
  EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url));
  EXPECT_TRUE(sdch_manager()->AllowLatencyExperiment(url2));

  sdch_manager()->SetAllowLatencyExperiment(url2, false);
  EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url));
  EXPECT_FALSE(sdch_manager()->AllowLatencyExperiment(url2));
}

TEST_F(SdchManagerTest, CanUseMultipleManagers) {
  SdchManager second_manager;

  std::string dictionary_domain_1("x.y.z.google.com");
  std::string dictionary_domain_2("x.y.z.chromium.org");

  std::string dictionary_text_1(NewSdchDictionary(dictionary_domain_1));
  std::string dictionary_text_2(NewSdchDictionary(dictionary_domain_2));

  std::string tmp_hash;
  std::string server_hash_1;
  std::string server_hash_2;

  SdchManager::GenerateHash(dictionary_text_1, &tmp_hash, &server_hash_1);
  SdchManager::GenerateHash(dictionary_text_2, &tmp_hash, &server_hash_2);

  // Confirm that if you add directories to one manager, you
  // can't get them from the other.
  EXPECT_TRUE(AddSdchDictionary(dictionary_text_1,
                                GURL("http://" + dictionary_domain_1)));
  scoped_ptr<SdchManager::DictionarySet> dict_set;

  SdchProblemCode problem_code;
  dict_set = sdch_manager()->GetDictionarySetByHash(
      GURL("http://" + dictionary_domain_1 + "/random_url"),
      server_hash_1, &problem_code);
  EXPECT_TRUE(dict_set);
  EXPECT_TRUE(dict_set->GetDictionaryText(server_hash_1));
  EXPECT_EQ(SDCH_OK, problem_code);

  second_manager.AddSdchDictionary(
      dictionary_text_2, GURL("http://" + dictionary_domain_2), nullptr);
  dict_set = second_manager.GetDictionarySetByHash(
      GURL("http://" + dictionary_domain_2 + "/random_url"),
      server_hash_2, &problem_code);
  EXPECT_TRUE(dict_set);
  EXPECT_TRUE(dict_set->GetDictionaryText(server_hash_2));
  EXPECT_EQ(SDCH_OK, problem_code);

  dict_set = sdch_manager()->GetDictionarySetByHash(
      GURL("http://" + dictionary_domain_2 + "/random_url"),
      server_hash_2, &problem_code);
  EXPECT_FALSE(dict_set);
  EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code);

  dict_set = second_manager.GetDictionarySetByHash(
      GURL("http://" + dictionary_domain_1 + "/random_url"),
      server_hash_1, &problem_code);
  EXPECT_FALSE(dict_set);
  EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code);
}

TEST_F(SdchManagerTest, ClearDictionaryData) {
  std::string dictionary_domain("x.y.z.google.com");
  GURL blacklist_url("http://bad.chromium.org");

  std::string dictionary_text(NewSdchDictionary(dictionary_domain));
  std::string tmp_hash;
  std::string server_hash;

  SdchManager::GenerateHash(dictionary_text, &tmp_hash, &server_hash);

  EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                GURL("http://" + dictionary_domain)));

  scoped_ptr<SdchManager::DictionarySet> dict_set;

  SdchProblemCode problem_code;
  dict_set = sdch_manager()->GetDictionarySetByHash(
      GURL("http://" + dictionary_domain + "/random_url"),
      server_hash, &problem_code);
  EXPECT_TRUE(dict_set);
  EXPECT_TRUE(dict_set->GetDictionaryText(server_hash));
  EXPECT_EQ(SDCH_OK, problem_code);

  sdch_manager()->BlacklistDomain(GURL(blacklist_url), SDCH_OK);
  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
            sdch_manager()->IsInSupportedDomain(blacklist_url));

  sdch_manager()->ClearData();

  dict_set = sdch_manager()->GetDictionarySetByHash(
      GURL("http://" + dictionary_domain + "/random_url"),
      server_hash, &problem_code);
  EXPECT_FALSE(dict_set);
  EXPECT_EQ(SDCH_DICTIONARY_HASH_NOT_FOUND, problem_code);
  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(blacklist_url));
}

TEST_F(SdchManagerTest, GetDictionaryNotification) {
  GURL test_request_gurl(GURL("http://www.example.com/data"));
  GURL test_dictionary_gurl(GURL("http://www.example.com/dict"));
  MockSdchObserver observer;
  sdch_manager()->AddObserver(&observer);

  EXPECT_EQ(0, observer.get_dictionary_notifications());
  sdch_manager()->OnGetDictionary(test_request_gurl, test_dictionary_gurl);
  EXPECT_EQ(1, observer.get_dictionary_notifications());
  EXPECT_EQ(test_request_gurl, observer.last_dictionary_request_url());
  EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url());

  sdch_manager()->RemoveObserver(&observer);
  sdch_manager()->OnGetDictionary(test_request_gurl, test_dictionary_gurl);
  EXPECT_EQ(1, observer.get_dictionary_notifications());
  EXPECT_EQ(test_request_gurl, observer.last_dictionary_request_url());
  EXPECT_EQ(test_dictionary_gurl, observer.last_dictionary_url());
}

TEST_F(SdchManagerTest, ExpirationCheckedProperly) {
  // Create an SDCH dictionary with an expiration time in the past.
  std::string dictionary_domain("x.y.z.google.com");
  std::string dictionary_text(base::StringPrintf("Domain: %s\nMax-age: -1\n\n",
                                                 dictionary_domain.c_str()));
  dictionary_text.append(
      kTestVcdiffDictionary, sizeof(kTestVcdiffDictionary) - 1);
  std::string client_hash;
  std::string server_hash;
  SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash);
  GURL target_gurl("http://" + dictionary_domain);
  AddSdchDictionary(dictionary_text, target_gurl);

  // It should be visible if looked up by hash whether expired or not.
  SdchProblemCode problem_code;
  scoped_ptr<SdchManager::DictionarySet> hash_set(
      sdch_manager()->GetDictionarySetByHash(
          target_gurl, server_hash, &problem_code).Pass());
  ASSERT_TRUE(hash_set);
  ASSERT_EQ(SDCH_OK, problem_code);

  // Make sure it's not visible for advertisement, but is visible
  // if looked up by hash.
  EXPECT_FALSE(sdch_manager()->GetDictionarySet(target_gurl));
  EXPECT_TRUE(sdch_manager()->GetDictionarySetByHash(
      target_gurl, server_hash, &problem_code));
  EXPECT_EQ(SDCH_OK, problem_code);
}

TEST_F(SdchManagerTest, SdchOnByDefault) {
  GURL google_url("http://www.google.com");
  scoped_ptr<SdchManager> sdch_manager(new SdchManager);

  EXPECT_EQ(SDCH_OK, sdch_manager->IsInSupportedDomain(google_url));
  SdchManager::EnableSdchSupport(false);
  EXPECT_EQ(SDCH_DISABLED, sdch_manager->IsInSupportedDomain(google_url));
}

// Confirm dispatch of notification.
TEST_F(SdchManagerTest, SdchDictionaryUsed) {
  MockSdchObserver observer;
  sdch_manager()->AddObserver(&observer);

  EXPECT_EQ(0, observer.dictionary_used_notifications());
  sdch_manager()->OnDictionaryUsed("xyzzy");
  EXPECT_EQ(1, observer.dictionary_used_notifications());
  EXPECT_EQ("xyzzy", observer.last_server_hash());

  std::string dictionary_domain("x.y.z.google.com");
  GURL target_gurl("http://" + dictionary_domain);
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));
  std::string client_hash;
  std::string server_hash;
  SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash);
  EXPECT_TRUE(AddSdchDictionary(dictionary_text, target_gurl));
  EXPECT_EQ(1, observer.dictionary_used_notifications());

  EXPECT_TRUE(sdch_manager()->GetDictionarySet(target_gurl));
  EXPECT_EQ(1, observer.dictionary_used_notifications());

  sdch_manager()->RemoveObserver(&observer);
  EXPECT_EQ(1, observer.dictionary_used_notifications());
  sdch_manager()->OnDictionaryUsed("plugh");
  EXPECT_EQ(1, observer.dictionary_used_notifications());
}

TEST_F(SdchManagerTest, AddRemoveNotifications) {
  MockSdchObserver observer;
  sdch_manager()->AddObserver(&observer);

  std::string dictionary_domain("x.y.z.google.com");
  GURL target_gurl("http://" + dictionary_domain);
  std::string dictionary_text(NewSdchDictionary(dictionary_domain));
  std::string client_hash;
  std::string server_hash;
  SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash);
  EXPECT_TRUE(AddSdchDictionary(dictionary_text, target_gurl));
  EXPECT_EQ(1, observer.dictionary_added_notifications());
  EXPECT_EQ(target_gurl, observer.last_dictionary_url());
  EXPECT_EQ(server_hash, observer.last_server_hash());

  EXPECT_EQ(SDCH_OK, sdch_manager()->RemoveSdchDictionary(server_hash));
  EXPECT_EQ(1, observer.dictionary_removed_notifications());
  EXPECT_EQ(server_hash, observer.last_server_hash());

  sdch_manager()->RemoveObserver(&observer);
}

}  // namespace net
