// Copyright (c) 2012 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/ssl/ssl_config_service.h"

#include <vector>

#include "base/basictypes.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

class MockSSLConfigService : public SSLConfigService {
 public:
  explicit MockSSLConfigService(const SSLConfig& config) : config_(config) {}

  // SSLConfigService implementation
  virtual void GetSSLConfig(SSLConfig* config) OVERRIDE {
    *config = config_;
  }

  // Sets the SSLConfig to be returned by GetSSLConfig and processes any
  // updates.
  void SetSSLConfig(const SSLConfig& config) {
    SSLConfig old_config = config_;
    config_ = config;
    ProcessConfigUpdate(old_config, config_);
  }

 private:
  virtual ~MockSSLConfigService() {}

  SSLConfig config_;
};

class MockSSLConfigServiceObserver : public SSLConfigService::Observer {
 public:
  MockSSLConfigServiceObserver() {}
  virtual ~MockSSLConfigServiceObserver() {}

  MOCK_METHOD0(OnSSLConfigChanged, void());
};

}  // namespace

TEST(SSLConfigServiceTest, NoChangesWontNotifyObservers) {
  SSLConfig initial_config;
  initial_config.rev_checking_enabled = true;
  initial_config.false_start_enabled = false;
  initial_config.version_min = SSL_PROTOCOL_VERSION_SSL3;
  initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_1;

  scoped_refptr<MockSSLConfigService> mock_service(
      new MockSSLConfigService(initial_config));
  MockSSLConfigServiceObserver observer;
  mock_service->AddObserver(&observer);

  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(0);
  mock_service->SetSSLConfig(initial_config);

  mock_service->RemoveObserver(&observer);
}

TEST(SSLConfigServiceTest, ConfigUpdatesNotifyObservers) {
  SSLConfig initial_config;
  initial_config.rev_checking_enabled = true;
  initial_config.false_start_enabled = false;
  initial_config.version_min = SSL_PROTOCOL_VERSION_SSL3;
  initial_config.version_max = SSL_PROTOCOL_VERSION_TLS1_1;

  scoped_refptr<MockSSLConfigService> mock_service(
      new MockSSLConfigService(initial_config));
  MockSSLConfigServiceObserver observer;
  mock_service->AddObserver(&observer);

  // Test that the basic boolean preferences trigger updates.
  initial_config.rev_checking_enabled = false;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  initial_config.false_start_enabled = true;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  // Test that changing the SSL version range triggers updates.
  initial_config.version_min = SSL_PROTOCOL_VERSION_TLS1;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  initial_config.version_max = SSL_PROTOCOL_VERSION_SSL3;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  // Test that disabling certain cipher suites triggers an update.
  std::vector<uint16> disabled_ciphers;
  disabled_ciphers.push_back(0x0004u);
  disabled_ciphers.push_back(0xBEEFu);
  disabled_ciphers.push_back(0xDEADu);
  initial_config.disabled_cipher_suites = disabled_ciphers;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  // Ensure that changing a disabled cipher suite, while still maintaining
  // sorted order, triggers an update.
  disabled_ciphers[1] = 0xCAFEu;
  initial_config.disabled_cipher_suites = disabled_ciphers;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  // Ensure that removing a disabled cipher suite, while still keeping some
  // cipher suites disabled, triggers an update.
  disabled_ciphers.pop_back();
  initial_config.disabled_cipher_suites = disabled_ciphers;
  EXPECT_CALL(observer, OnSSLConfigChanged()).Times(1);
  mock_service->SetSSLConfig(initial_config);

  mock_service->RemoveObserver(&observer);
}

}  // namespace net
