blob: 15658b5e306cabb0eaf2b999114d3baf7926ec3a [file] [log] [blame]
// 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 "base/compiler_specific.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/api/dial/dial_device_data.h"
#include "chrome/browser/extensions/api/dial/dial_registry.h"
#include "chrome/browser/extensions/api/dial/dial_service.h"
#include "chrome/test/base/testing_profile.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using base::Time;
using base::TimeDelta;
using ::testing::A;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::InSequence;
namespace extensions {
class MockDialObserver : public DialRegistry::Observer {
public:
MOCK_METHOD1(OnDialDeviceEvent,
void(const DialRegistry::DeviceList& devices));
MOCK_METHOD1(OnDialError, void(DialRegistry::DialErrorCode type));
};
class MockDialService : public DialService {
public:
virtual ~MockDialService() {}
MOCK_METHOD0(Discover, bool());
MOCK_METHOD1(AddObserver, void(DialService::Observer*));
MOCK_METHOD1(RemoveObserver, void(DialService::Observer*));
MOCK_METHOD1(HasObserver, bool(DialService::Observer*));
};
class MockDialRegistry : public DialRegistry {
public:
MockDialRegistry(Observer *dial_api,
const base::TimeDelta& refresh_interval,
const base::TimeDelta& expiration,
const size_t max_devices)
: DialRegistry(dial_api, refresh_interval, expiration, max_devices) {
time_ = Time::Now();
}
virtual ~MockDialRegistry() {
// Don't let the DialRegistry delete this.
DialService* tmp = dial_.release();
if (tmp != NULL)
CHECK_EQ(&mock_service_, tmp);
}
// Returns the mock Dial service.
MockDialService& mock_service() {
return mock_service_;
}
// Set to mock out the current time.
Time time_;
protected:
virtual base::Time Now() const OVERRIDE {
return time_;
}
virtual DialService* CreateDialService() OVERRIDE {
return &mock_service_;
}
virtual void ClearDialService() OVERRIDE {
// Release the pointer but don't delete the object because the test owns it.
CHECK_EQ(&mock_service_, dial_.release());
}
private:
MockDialService mock_service_;
};
class DialRegistryTest : public testing::Test {
public:
DialRegistryTest()
: first_device_("first", GURL("http://127.0.0.1/dd.xml"), Time::Now()),
second_device_("second", GURL("http://127.0.0.2/dd.xml"), Time::Now()),
third_device_("third", GURL("http://127.0.0.3/dd.xml"), Time::Now()) {
registry_.reset(new MockDialRegistry(&mock_observer_,
TimeDelta::FromSeconds(1000),
TimeDelta::FromSeconds(10),
10));
list_with_first_device_.push_back(first_device_);
list_with_second_device_.push_back(second_device_);
}
protected:
scoped_ptr<MockDialRegistry> registry_;
MockDialObserver mock_observer_;
const DialDeviceData first_device_;
const DialDeviceData second_device_;
const DialDeviceData third_device_;
const DialRegistry::DeviceList empty_list_;
DialRegistry::DeviceList list_with_first_device_;
DialRegistry::DeviceList list_with_second_device_;
// Must instantiate a MessageLoop for the thread, as the registry starts a
// RepeatingTimer when there are listeners.
base::MessageLoop message_loop_;
void SetListenerExpectations() {
EXPECT_CALL(registry_->mock_service(),
AddObserver(A<DialService::Observer*>()))
.Times(1);
EXPECT_CALL(registry_->mock_service(),
RemoveObserver(A<DialService::Observer*>()))
.Times(1);
}
};
TEST_F(DialRegistryTest, TestAddRemoveListeners) {
SetListenerExpectations();
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(1);
EXPECT_FALSE(registry_->repeating_timer_.IsRunning());
registry_->OnListenerAdded();
EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
registry_->OnListenerAdded();
EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
registry_->OnListenerRemoved();
EXPECT_TRUE(registry_->repeating_timer_.IsRunning());
registry_->OnListenerRemoved();
EXPECT_FALSE(registry_->repeating_timer_.IsRunning());
}
TEST_F(DialRegistryTest, TestNoDevicesDiscovered) {
SetListenerExpectations();
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(1);
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
};
TEST_F(DialRegistryTest, TestDevicesDiscovered) {
DialRegistry::DeviceList expected_list2;
expected_list2.push_back(first_device_);
expected_list2.push_back(second_device_);
SetListenerExpectations();
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(2);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
.Times(2);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list2))
.Times(1);
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, first_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->DoDiscovery();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, second_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
}
TEST_F(DialRegistryTest, TestDeviceExpires) {
SetListenerExpectations();
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(2);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(2);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
.Times(2);
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, first_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->time_ = Time::Now() + TimeDelta::FromSeconds(30);
registry_->DoDiscovery();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
}
TEST_F(DialRegistryTest, TestExpiredDeviceIsRediscovered) {
std::vector<Time> discovery_times;
discovery_times.push_back(Time::Now());
discovery_times.push_back(discovery_times[0] + TimeDelta::FromSeconds(30));
discovery_times.push_back(discovery_times[1] + TimeDelta::FromSeconds(30));
DialDeviceData rediscovered_device("first",
GURL("http://127.0.0.1/dd.xml"),
discovery_times[2]);
SetListenerExpectations();
// TODO(mfoltz): Convert other tests to use InSequence to make expectations
// more obvious.
InSequence s;
EXPECT_CALL(registry_->mock_service(), Discover());
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
EXPECT_CALL(registry_->mock_service(), Discover());
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
EXPECT_CALL(registry_->mock_service(), Discover());
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_));
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_));
registry_->time_ = discovery_times[0];
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, first_device_);
registry_->OnDiscoveryFinished(NULL);
// Will expire "first" device as it is not discovered this time.
registry_->time_ = discovery_times[1];
registry_->DoDiscovery();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDiscoveryFinished(NULL);
// "first" device is rediscovered 30 seconds later. We pass a device object
// with a newer discovery time so it is not pruned immediately.
registry_->time_ = discovery_times[2];
registry_->DoDiscovery();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, rediscovered_device);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
}
TEST_F(DialRegistryTest, TestRemovingListenerDoesNotClearList) {
EXPECT_CALL(registry_->mock_service(),
AddObserver(A<DialService::Observer*>()))
.Times(2);
EXPECT_CALL(registry_->mock_service(),
RemoveObserver(A<DialService::Observer*>()))
.Times(2);
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(2);
InSequence s;
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
.Times(2);
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, first_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
}
TEST_F(DialRegistryTest, TestNetworkEventConnectionLost) {
SetListenerExpectations();
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(1);
InSequence s;
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialError(
DialRegistry::DIAL_NETWORK_DISCONNECTED)).Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(1);
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, first_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
registry_->OnDiscoveryRequest(NULL);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
}
TEST_F(DialRegistryTest, TestNetworkEventConnectionRestored) {
DialRegistry::DeviceList expected_list3;
expected_list3.push_back(second_device_);
expected_list3.push_back(third_device_);
// A disconnection should shutdown the DialService, so we expect the observer
// to be added twice.
EXPECT_CALL(registry_->mock_service(),
AddObserver(A<DialService::Observer*>()))
.Times(2);
EXPECT_CALL(registry_->mock_service(),
RemoveObserver(A<DialService::Observer*>()))
.Times(2);
EXPECT_CALL(registry_->mock_service(), Discover())
.Times(2);
InSequence s;
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_first_device_))
.Times(1);
EXPECT_CALL(mock_observer_,
OnDialError(DialRegistry::DIAL_NETWORK_DISCONNECTED))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(empty_list_))
.Times(2);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(list_with_second_device_))
.Times(1);
EXPECT_CALL(mock_observer_, OnDialDeviceEvent(expected_list3))
.Times(1);
registry_->OnListenerAdded();
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, first_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_NONE);
registry_->OnDiscoveryRequest(NULL);
registry_->OnDiscoveryFinished(NULL);
registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_WIFI);
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, second_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->OnNetworkChanged(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
registry_->OnDiscoveryRequest(NULL);
registry_->OnDeviceDiscovered(NULL, third_device_);
registry_->OnDiscoveryFinished(NULL);
registry_->OnListenerRemoved();
}
} // namespace extensions