// 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 <vector>

#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
#include "content/public/test/mock_special_storage_policy.h"
#include "content/public/test/mock_storage_client.h"
#include "net/base/net_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/browser/quota/quota_manager_proxy.h"
#include "webkit/browser/quota/storage_monitor.h"
#include "webkit/browser/quota/storage_observer.h"

using quota::HostStorageObservers;
using quota::kQuotaErrorNotSupported;
using quota::kQuotaStatusOk;
using quota::kStorageTypePersistent;
using quota::kStorageTypeTemporary;
using quota::QuotaClient;
using quota::QuotaManager;
using quota::QuotaStatusCode;
using quota::SpecialStoragePolicy;
using quota::StorageMonitor;
using quota::StorageObserver;
using quota::StorageObserverList;
using quota::StorageType;
using quota::StorageTypeObservers;

namespace content {

namespace {

const char kDefaultOrigin[] = "http://www.foo.com/";
const char kAlternativeOrigin[] = "http://www.bar.com/";

class MockObserver : public StorageObserver {
 public:
  const StorageObserver::Event& LastEvent() const {
    CHECK(!events_.empty());
    return events_.back();
  }

  int EventCount() const {
    return events_.size();
  }

  // StorageObserver implementation:
  virtual void OnStorageEvent(const StorageObserver::Event& event) OVERRIDE {
    events_.push_back(event);
  }

 private:
  std::vector<StorageObserver::Event> events_;
};

// A mock quota manager for overriding GetUsageAndQuotaForWebApps().
class UsageMockQuotaManager : public QuotaManager {
 public:
  UsageMockQuotaManager(SpecialStoragePolicy* special_storage_policy)
      : QuotaManager(
            false,
            base::FilePath(),
            base::MessageLoopProxy::current().get(),
            base::MessageLoopProxy::current().get(),
            special_storage_policy),
        callback_usage_(0),
        callback_quota_(0),
        callback_status_(kQuotaStatusOk),
        initialized_(false) {
  }

  void SetCallbackParams(int64 usage, int64 quota, QuotaStatusCode status) {
    initialized_ = true;
    callback_quota_ = quota;
    callback_usage_ = usage;
    callback_status_ = status;
  }

  void InvokeCallback() {
    delayed_callback_.Run(callback_status_, callback_usage_, callback_quota_);
  }

  virtual void GetUsageAndQuotaForWebApps(
      const GURL& origin,
      StorageType type,
      const GetUsageAndQuotaCallback& callback) OVERRIDE {
    if (initialized_)
      callback.Run(callback_status_, callback_usage_, callback_quota_);
    else
      delayed_callback_ = callback;
  }

 protected:
  virtual ~UsageMockQuotaManager() {}

 private:
  int64 callback_usage_;
  int64 callback_quota_;
  QuotaStatusCode callback_status_;
  bool initialized_;
  GetUsageAndQuotaCallback delayed_callback_;
};

}  // namespace

class StorageMonitorTestBase : public testing::Test {
 protected:
  void DispatchPendingEvents(StorageObserverList& observer_list) {
    observer_list.DispatchPendingEvent();
  }

  const StorageObserver::Event* GetPendingEvent(
      const StorageObserverList& observer_list) {
    return observer_list.notification_timer_.IsRunning()
                ? &observer_list.pending_event_ : NULL;
  }

  const StorageObserver::Event* GetPendingEvent(
      const HostStorageObservers& host_observers) {
    return GetPendingEvent(host_observers.observers_);
  }

  int GetRequiredUpdatesCount(const StorageObserverList& observer_list) {
    int count = 0;
    for (StorageObserverList::StorageObserverStateMap::const_iterator it =
            observer_list.observers_.begin();
         it != observer_list.observers_.end(); ++it) {
      if (it->second.requires_update)
        ++count;
    }

    return count;
  }

  int GetRequiredUpdatesCount(const HostStorageObservers& host_observers) {
    return GetRequiredUpdatesCount(host_observers.observers_);
  }

  void SetLastNotificationTime(StorageObserverList& observer_list,
                               StorageObserver* observer) {
    ASSERT_TRUE(observer_list.observers_.find(observer) !=
                observer_list.observers_.end());

    StorageObserverList::ObserverState& state =
        observer_list.observers_[observer];
    state.last_notification_time = base::TimeTicks::Now() - state.rate;
  }

  void SetLastNotificationTime(HostStorageObservers& host_observers,
                               StorageObserver* observer) {
    SetLastNotificationTime(host_observers.observers_, observer);
  }

  int GetObserverCount(const HostStorageObservers& host_observers) {
    return host_observers.observers_.ObserverCount();
  }
};

class StorageTestWithManagerBase : public StorageMonitorTestBase {
 public:
  virtual void SetUp() OVERRIDE {
    storage_policy_ = new MockSpecialStoragePolicy();
    quota_manager_ = new UsageMockQuotaManager(storage_policy_.get());
  }

  virtual void TearDown() OVERRIDE {
    // This ensures the quota manager is destroyed correctly.
    quota_manager_ = NULL;
    base::RunLoop().RunUntilIdle();
  }

 protected:
  base::MessageLoop message_loop_;
  scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
  scoped_refptr<UsageMockQuotaManager> quota_manager_;
};

// Tests for StorageObserverList:

typedef StorageMonitorTestBase StorageObserverListTest;

// Test dispatching events to one observer.
TEST_F(StorageObserverListTest, DispatchEventToSingleObserver) {
  // A message loop is required as StorageObserverList may schedule jobs.
  base::MessageLoop loop(base::MessageLoop::TYPE_DEFAULT);

  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  MockObserver mock_observer;
  StorageObserverList observer_list;
  observer_list.AddObserver(&mock_observer, params);

  StorageObserver::Event event;
  event.filter = params.filter;

  // Verify that the first event is dispatched immediately.
  event.quota = 1;
  event.usage = 1;
  observer_list.OnStorageChange(event);
  EXPECT_EQ(1, mock_observer.EventCount());
  EXPECT_EQ(event, mock_observer.LastEvent());
  EXPECT_EQ(NULL, GetPendingEvent(observer_list));
  EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));

  // Verify that the next event is pending.
  event.quota = 2;
  event.usage = 2;
  observer_list.OnStorageChange(event);
  EXPECT_EQ(1, mock_observer.EventCount());
  ASSERT_TRUE(GetPendingEvent(observer_list));
  EXPECT_EQ(event, *GetPendingEvent(observer_list));
  EXPECT_EQ(1, GetRequiredUpdatesCount(observer_list));

  // Fake the last notification time so that an event will be dispatched.
  SetLastNotificationTime(observer_list, &mock_observer);
  event.quota = 3;
  event.usage = 3;
  observer_list.OnStorageChange(event);
  EXPECT_EQ(2, mock_observer.EventCount());
  EXPECT_EQ(event, mock_observer.LastEvent());
  EXPECT_EQ(NULL, GetPendingEvent(observer_list));
  EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));

  // Remove the observer.
  event.quota = 4;
  event.usage = 4;
  observer_list.RemoveObserver(&mock_observer);
  observer_list.OnStorageChange(event);
  EXPECT_EQ(2, mock_observer.EventCount());
  EXPECT_EQ(NULL, GetPendingEvent(observer_list));
}

// Test dispatching events to multiple observers.
TEST_F(StorageObserverListTest, DispatchEventToMultipleObservers) {
  // A message loop is required as StorageObserverList may schedule jobs.
  base::MessageLoop loop(base::MessageLoop::TYPE_DEFAULT);

  MockObserver mock_observer1;
  MockObserver mock_observer2;
  StorageObserverList observer_list;
  StorageObserver::Filter filter(kStorageTypePersistent,
                                 GURL(kDefaultOrigin));
  observer_list.AddObserver(
      &mock_observer1,
      StorageObserver::MonitorParams(
          filter, base::TimeDelta::FromHours(1), false));
  observer_list.AddObserver(
      &mock_observer2,
      StorageObserver::MonitorParams(
          filter, base::TimeDelta::FromHours(2), false));

  StorageObserver::Event event;
  event.filter = filter;

  // Verify that the first event is dispatched immediately.
  event.quota = 1;
  event.usage = 1;
  observer_list.OnStorageChange(event);
  EXPECT_EQ(1, mock_observer1.EventCount());
  EXPECT_EQ(1, mock_observer2.EventCount());
  EXPECT_EQ(event, mock_observer1.LastEvent());
  EXPECT_EQ(event, mock_observer2.LastEvent());
  EXPECT_EQ(NULL, GetPendingEvent(observer_list));
  EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));

  // Fake the last notification time so that observer1 will receive the next
  // event, but it will be pending for observer2.
  SetLastNotificationTime(observer_list, &mock_observer1);
  event.quota = 2;
  event.usage = 2;
  observer_list.OnStorageChange(event);
  EXPECT_EQ(2, mock_observer1.EventCount());
  EXPECT_EQ(1, mock_observer2.EventCount());
  EXPECT_EQ(event, mock_observer1.LastEvent());
  ASSERT_TRUE(GetPendingEvent(observer_list));
  EXPECT_EQ(event, *GetPendingEvent(observer_list));
  EXPECT_EQ(1, GetRequiredUpdatesCount(observer_list));

  // Now dispatch the pending event to observer2.
  SetLastNotificationTime(observer_list, &mock_observer2);
  DispatchPendingEvents(observer_list);
  EXPECT_EQ(2, mock_observer1.EventCount());
  EXPECT_EQ(2, mock_observer2.EventCount());
  EXPECT_EQ(event, mock_observer1.LastEvent());
  EXPECT_EQ(event, mock_observer2.LastEvent());
  EXPECT_EQ(NULL, GetPendingEvent(observer_list));
  EXPECT_EQ(0, GetRequiredUpdatesCount(observer_list));
}

// Ensure that the |origin| field in events match the origin specified by the
// observer on registration.
TEST_F(StorageObserverListTest, ReplaceEventOrigin) {
  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  MockObserver mock_observer;
  StorageObserverList observer_list;
  observer_list.AddObserver(&mock_observer, params);

  StorageObserver::Event dispatched_event;
  dispatched_event.filter = params.filter;
  dispatched_event.filter.origin = GURL("https://www.foo.com/bar");
  observer_list.OnStorageChange(dispatched_event);

  EXPECT_EQ(params.filter.origin, mock_observer.LastEvent().filter.origin);
}

// Tests for HostStorageObservers:

typedef StorageTestWithManagerBase HostStorageObserversTest;

// Verify that HostStorageObservers is initialized after the first usage change.
TEST_F(HostStorageObserversTest, InitializeOnUsageChange) {
  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  const int64 kUsage = 324554;
  const int64 kQuota = 234354354;
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);

  MockObserver mock_observer;
  HostStorageObservers host_observers(quota_manager_.get());
  host_observers.AddObserver(&mock_observer, params);

  // Verify that HostStorageObservers dispatches the first event correctly.
  StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
  host_observers.NotifyUsageChange(params.filter, 87324);
  EXPECT_EQ(1, mock_observer.EventCount());
  EXPECT_EQ(expected_event, mock_observer.LastEvent());
  EXPECT_TRUE(host_observers.is_initialized());

  // Verify that HostStorageObservers handles subsequent usage changes
  // correctly.
  const int64 kDelta = 2345;
  expected_event.usage += kDelta;
  SetLastNotificationTime(host_observers, &mock_observer);
  host_observers.NotifyUsageChange(params.filter, kDelta);
  EXPECT_EQ(2, mock_observer.EventCount());
  EXPECT_EQ(expected_event, mock_observer.LastEvent());
}

// Verify that HostStorageObservers is initialized after the adding the first
// observer that elected to receive the initial state.
TEST_F(HostStorageObserversTest, InitializeOnObserver) {
  const int64 kUsage = 74387;
  const int64 kQuota = 92834743;
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
  HostStorageObservers host_observers(quota_manager_.get());

  // |host_observers| should not be initialized after the first observer is
  // added because it did not elect to receive the initial state.
  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  MockObserver mock_observer1;
  host_observers.AddObserver(&mock_observer1, params);
  EXPECT_FALSE(host_observers.is_initialized());
  EXPECT_EQ(0, mock_observer1.EventCount());

  // |host_observers| should be initialized after the second observer is
  // added.
  MockObserver mock_observer2;
  params.dispatch_initial_state = true;
  host_observers.AddObserver(&mock_observer2, params);
  StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
  EXPECT_EQ(0, mock_observer1.EventCount());
  EXPECT_EQ(1, mock_observer2.EventCount());
  EXPECT_EQ(expected_event, mock_observer2.LastEvent());
  EXPECT_TRUE(host_observers.is_initialized());
  EXPECT_EQ(NULL, GetPendingEvent(host_observers));
  EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));

  // Verify that both observers will receive events after a usage change.
  const int64 kDelta = 2345;
  expected_event.usage += kDelta;
  SetLastNotificationTime(host_observers, &mock_observer2);
  host_observers.NotifyUsageChange(params.filter, kDelta);
  EXPECT_EQ(1, mock_observer1.EventCount());
  EXPECT_EQ(2, mock_observer2.EventCount());
  EXPECT_EQ(expected_event, mock_observer1.LastEvent());
  EXPECT_EQ(expected_event, mock_observer2.LastEvent());
  EXPECT_EQ(NULL, GetPendingEvent(host_observers));
  EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));

  // Verify that the addition of a third observer only causes an event to be
  // dispatched to the new observer.
  MockObserver mock_observer3;
  params.dispatch_initial_state = true;
  host_observers.AddObserver(&mock_observer3, params);
  EXPECT_EQ(1, mock_observer1.EventCount());
  EXPECT_EQ(2, mock_observer2.EventCount());
  EXPECT_EQ(1, mock_observer3.EventCount());
  EXPECT_EQ(expected_event, mock_observer3.LastEvent());
}

// Verify that negative usage and quota is changed to zero.
TEST_F(HostStorageObserversTest, NegativeUsageAndQuota) {
  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  const int64 kUsage = -324554;
  const int64 kQuota = -234354354;
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);

  MockObserver mock_observer;
  HostStorageObservers host_observers(quota_manager_.get());
  host_observers.AddObserver(&mock_observer, params);

  StorageObserver::Event expected_event(params.filter, 0, 0);
  host_observers.NotifyUsageChange(params.filter, -87324);
  EXPECT_EQ(expected_event, mock_observer.LastEvent());
}

// Verify that HostStorageObservers can recover from a bad initialization.
TEST_F(HostStorageObserversTest, RecoverFromBadUsageInit) {
  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  MockObserver mock_observer;
  HostStorageObservers host_observers(quota_manager_.get());
  host_observers.AddObserver(&mock_observer, params);

  // Set up the quota manager to return an error status.
  const int64 kUsage = 6656;
  const int64 kQuota = 99585556;
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaErrorNotSupported);

  // Verify that |host_observers| is not initialized and an event has not been
  // dispatched.
  host_observers.NotifyUsageChange(params.filter, 9438);
  EXPECT_EQ(0, mock_observer.EventCount());
  EXPECT_FALSE(host_observers.is_initialized());
  EXPECT_EQ(NULL, GetPendingEvent(host_observers));
  EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));

  // Now ensure that quota manager returns a good status.
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
  host_observers.NotifyUsageChange(params.filter, 9048543);
  StorageObserver::Event expected_event(params.filter, kUsage, kQuota);
  EXPECT_EQ(1, mock_observer.EventCount());
  EXPECT_EQ(expected_event, mock_observer.LastEvent());
  EXPECT_TRUE(host_observers.is_initialized());
}

// Verify that HostStorageObservers handle initialization of the cached usage
// and quota correctly.
TEST_F(HostStorageObserversTest, AsyncInitialization) {
  StorageObserver::MonitorParams params(kStorageTypePersistent,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  MockObserver mock_observer;
  HostStorageObservers host_observers(quota_manager_.get());
  host_observers.AddObserver(&mock_observer, params);

  // Trigger initialization. Leave the mock quota manager uninitialized so that
  // the callback is not invoked.
  host_observers.NotifyUsageChange(params.filter, 7645);
  EXPECT_EQ(0, mock_observer.EventCount());
  EXPECT_FALSE(host_observers.is_initialized());
  EXPECT_EQ(NULL, GetPendingEvent(host_observers));
  EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));

  // Simulate notifying |host_observers| of a usage change before initialization
  // is complete.
  const int64 kUsage = 6656;
  const int64 kQuota = 99585556;
  const int64 kDelta = 327643;
  host_observers.NotifyUsageChange(params.filter, kDelta);
  EXPECT_EQ(0, mock_observer.EventCount());
  EXPECT_FALSE(host_observers.is_initialized());
  EXPECT_EQ(NULL, GetPendingEvent(host_observers));
  EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));

  // Simulate an asynchronous callback from QuotaManager.
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
  quota_manager_->InvokeCallback();
  StorageObserver::Event expected_event(params.filter, kUsage + kDelta, kQuota);
  EXPECT_EQ(1, mock_observer.EventCount());
  EXPECT_EQ(expected_event, mock_observer.LastEvent());
  EXPECT_TRUE(host_observers.is_initialized());
  EXPECT_EQ(NULL, GetPendingEvent(host_observers));
  EXPECT_EQ(0, GetRequiredUpdatesCount(host_observers));
}

// Tests for StorageTypeObservers:

typedef StorageTestWithManagerBase StorageTypeObserversTest;

// Test adding and removing observers.
TEST_F(StorageTypeObserversTest, AddRemoveObservers) {
  StorageTypeObservers type_observers(quota_manager_.get());

  StorageObserver::MonitorParams params1(kStorageTypePersistent,
                                         GURL(kDefaultOrigin),
                                         base::TimeDelta::FromHours(1),
                                         false);
  StorageObserver::MonitorParams params2(kStorageTypePersistent,
                                         GURL(kAlternativeOrigin),
                                         base::TimeDelta::FromHours(1),
                                         false);
  std::string host1 = net::GetHostOrSpecFromURL(params1.filter.origin);
  std::string host2 = net::GetHostOrSpecFromURL(params2.filter.origin);

  MockObserver mock_observer1;
  MockObserver mock_observer2;
  MockObserver mock_observer3;
  type_observers.AddObserver(&mock_observer1, params1);
  type_observers.AddObserver(&mock_observer2, params1);

  type_observers.AddObserver(&mock_observer1, params2);
  type_observers.AddObserver(&mock_observer2, params2);
  type_observers.AddObserver(&mock_observer3, params2);

  // Verify that the observers have been removed correctly.
  ASSERT_TRUE(type_observers.GetHostObservers(host1));
  ASSERT_TRUE(type_observers.GetHostObservers(host2));
  EXPECT_EQ(2, GetObserverCount(*type_observers.GetHostObservers(host1)));
  EXPECT_EQ(3, GetObserverCount(*type_observers.GetHostObservers(host2)));

  // Remove an observer for a specific filter.
  type_observers.RemoveObserverForFilter(&mock_observer1, params1.filter);
  ASSERT_TRUE(type_observers.GetHostObservers(host1));
  ASSERT_TRUE(type_observers.GetHostObservers(host2));
  EXPECT_EQ(1, GetObserverCount(*type_observers.GetHostObservers(host1)));
  EXPECT_EQ(3, GetObserverCount(*type_observers.GetHostObservers(host2)));

  // Remove all instances of an observer.
  type_observers.RemoveObserver(&mock_observer2);
  ASSERT_TRUE(type_observers.GetHostObservers(host2));
  EXPECT_EQ(2, GetObserverCount(*type_observers.GetHostObservers(host2)));
  // Observers of host1 has been deleted as it is empty.
  EXPECT_FALSE(type_observers.GetHostObservers(host1));
}

// Tests for StorageMonitor:

class StorageMonitorTest : public StorageTestWithManagerBase {
 public:
  StorageMonitorTest()
      : storage_monitor_(NULL),
        params1_(kStorageTypeTemporary,
                 GURL(kDefaultOrigin),
                 base::TimeDelta::FromHours(1),
                 false),
        params2_(kStorageTypePersistent,
                 GURL(kDefaultOrigin),
                 base::TimeDelta::FromHours(1),
                 false) {
  }

 protected:
  virtual void SetUp() OVERRIDE {
    StorageTestWithManagerBase::SetUp();

    storage_monitor_ = quota_manager_->storage_monitor_.get();
    host_ = net::GetHostOrSpecFromURL(params1_.filter.origin);

    storage_monitor_->AddObserver(&mock_observer1_, params1_);
    storage_monitor_->AddObserver(&mock_observer2_, params1_);

    storage_monitor_->AddObserver(&mock_observer1_, params2_);
    storage_monitor_->AddObserver(&mock_observer2_, params2_);
    storage_monitor_->AddObserver(&mock_observer3_, params2_);
  }

  int GetObserverCount(StorageType storage_type) {
    const StorageTypeObservers* type_observers =
        storage_monitor_->GetStorageTypeObservers(storage_type);
    return StorageMonitorTestBase::GetObserverCount(
                *type_observers->GetHostObservers(host_));
  }

  void CheckObserverCount(int expected_temporary, int expected_persistent) {
    ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
                    kStorageTypeTemporary));
    ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
                    kStorageTypeTemporary)->GetHostObservers(host_));
    EXPECT_EQ(expected_temporary, GetObserverCount(kStorageTypeTemporary));

    ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
                    kStorageTypePersistent));
    ASSERT_TRUE(storage_monitor_->GetStorageTypeObservers(
                    kStorageTypePersistent)->GetHostObservers(host_));
    EXPECT_EQ(expected_persistent, GetObserverCount(kStorageTypePersistent));
  }

  StorageMonitor* storage_monitor_;
  StorageObserver::MonitorParams params1_;
  StorageObserver::MonitorParams params2_;
  MockObserver mock_observer1_;
  MockObserver mock_observer2_;
  MockObserver mock_observer3_;
  std::string host_;
};

// Test adding storage observers.
TEST_F(StorageMonitorTest, AddObservers) {
  // Verify that the observers are added correctly.
  CheckObserverCount(2, 3);
}

// Test dispatching events to storage observers.
TEST_F(StorageMonitorTest, EventDispatch) {
  // Verify dispatch of events.
  const int64 kUsage = 5325;
  const int64 kQuota = 903845;
  quota_manager_->SetCallbackParams(kUsage, kQuota, kQuotaStatusOk);
  storage_monitor_->NotifyUsageChange(params1_.filter, 9048543);

  StorageObserver::Event expected_event(params1_.filter, kUsage, kQuota);
  EXPECT_EQ(1, mock_observer1_.EventCount());
  EXPECT_EQ(1, mock_observer2_.EventCount());
  EXPECT_EQ(0, mock_observer3_.EventCount());
  EXPECT_EQ(expected_event, mock_observer1_.LastEvent());
  EXPECT_EQ(expected_event, mock_observer2_.LastEvent());
}

// Test removing all instances of an observer.
TEST_F(StorageMonitorTest, RemoveObserver) {
  storage_monitor_->RemoveObserver(&mock_observer1_);
  CheckObserverCount(1, 2);
}

// Test removing an observer for a specific filter.
TEST_F(StorageMonitorTest, RemoveObserverForFilter) {
  storage_monitor_->RemoveObserverForFilter(&mock_observer1_, params2_.filter);
  CheckObserverCount(2, 2);
}

// Integration test for QuotaManager and StorageMonitor:

class StorageMonitorIntegrationTest : public testing::Test {
 public:
  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
    storage_policy_ = new MockSpecialStoragePolicy();
    quota_manager_ = new QuotaManager(
        false,
        data_dir_.path(),
        base::MessageLoopProxy::current().get(),
        base::MessageLoopProxy::current().get(),
        storage_policy_.get());

    client_ = new MockStorageClient(quota_manager_->proxy(),
                                    NULL,
                                    QuotaClient::kFileSystem,
                                    0);

    quota_manager_->proxy()->RegisterClient(client_);
  }

  virtual void TearDown() OVERRIDE {
    // This ensures the quota manager is destroyed correctly.
    quota_manager_ = NULL;
    base::RunLoop().RunUntilIdle();
  }

 protected:
  base::MessageLoop message_loop_;
  base::ScopedTempDir data_dir_;
  scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
  scoped_refptr<QuotaManager> quota_manager_;
  MockStorageClient* client_;
};

// This test simulates a usage change in a quota client and verifies that a
// storage observer will receive a storage event.
TEST_F(StorageMonitorIntegrationTest, NotifyUsageEvent) {
  const StorageType kTestStorageType = kStorageTypePersistent;
  const int64 kTestUsage = 234743;

  // Register the observer.
  StorageObserver::MonitorParams params(kTestStorageType,
                                        GURL(kDefaultOrigin),
                                        base::TimeDelta::FromHours(1),
                                        false);
  MockObserver mock_observer;
  quota_manager_->AddStorageObserver(&mock_observer, params);

  // Fire a usage change.
  client_->AddOriginAndNotify(GURL(kDefaultOrigin),
                              kTestStorageType,
                              kTestUsage);
  base::RunLoop().RunUntilIdle();

  // Verify that the observer receives it.
  ASSERT_EQ(1, mock_observer.EventCount());
  const StorageObserver::Event& event = mock_observer.LastEvent();
  EXPECT_EQ(params.filter, event.filter);
  EXPECT_EQ(kTestUsage, event.usage);
}

}  // namespace content
