15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is relatively complicated. Here's the summary of what it does:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Set up mock D-Bus related objects to mock out D-Bus calls.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Set up a mock proxy resolver to mock out the proxy resolution.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Create ProxyResolutionServiceProvider by injecting the mocks
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Start the service provider.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Request ProxyResolutionServiceProvider to resolve proxy for kSourceURL.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - ProxyResolutionServiceProvider will return the result as a signal.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - Confirm that we receive the signal and check the contents of the signal.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/dbus/service_provider_test_helper.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/mock_exported_object.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We want to know about the proxy info for the URL.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSourceURL[] = "http://www.gmail.com/";
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyResolutionServiceProvider will return the proxy info as a D-Bus
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// signal, to the following signal interface and the signal name.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kReturnSignalInterface[] = "org.chromium.TestInterface";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kReturnSignalName[] = "TestSignal";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The returned proxy info.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kReturnProxyInfo[] = "PROXY cache.example.com:12345";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The error message is empty if proxy resolution is successful.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kReturnEmptyErrorMessage[] = "";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mock for ProxyResolverInterface. We'll inject this to
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ProxyResolutionServiceProvider to mock out the proxy resolution.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockProxyResolver : public ProxyResolverInterface {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD4(ResolveProxy,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               void(const std::string& source_url,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::string& signal_interface,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::string& signal_name,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    scoped_refptr<dbus::ExportedObject> exported_object));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ProxyResolutionServiceProviderTest : public testing::Test {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyResolutionServiceProviderTest()
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : signal_received_successfully_(false) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a mock proxy resolver. Will be owned by
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |proxy_resolution_service|.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockProxyResolver* mock_resolver = new MockProxyResolver;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |mock_resolver_|'s ResolveProxy() will use MockResolveProxy().
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*mock_resolver,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                ResolveProxy(kSourceURL, kReturnSignalInterface,
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             kReturnSignalName, _))
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(Invoke(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            this,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &ProxyResolutionServiceProviderTest::MockResolveProxy));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create the proxy resolution service with the mock bus and the mock
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // resolver injected.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service_provider_.reset(
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ProxyResolutionServiceProvider::CreateForTesting(mock_resolver));
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_helper_.SetUp(kResolveNetworkProxy, service_provider_.get());
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Connect to the signal that will be sent to kReturnSignalInterface and
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // kReturnSignalName. ResolveNetworkProxy() will send the result as a
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // signal. OnSignalReceived() will be called upon the delivery.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_helper_.SetUpReturnSignal(
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kReturnSignalInterface,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        kReturnSignalName,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ProxyResolutionServiceProviderTest::OnSignalReceived,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Unretained(this)),
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&ProxyResolutionServiceProviderTest::OnConnectedToSignal,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::Unretained(this)));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test_helper_.TearDown();
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service_provider_.reset();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a signal is received.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSignalReceived(dbus::Signal* signal) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(kReturnSignalInterface, signal->GetInterface());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(kReturnSignalName, signal->GetMember());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string source_url;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string proxy_info;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string error_message;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The signal should contain three strings.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(signal);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.PopString(&source_url));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.PopString(&proxy_info));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(reader.PopString(&error_message));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check the signal contents.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kSourceURL, source_url);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kReturnProxyInfo, proxy_info);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kReturnEmptyErrorMessage, error_message);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Mark that the signal is received successfully.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    signal_received_successfully_ = true;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when connected to a signal.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnConnectedToSignal(const std::string& signal_interface,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& signal_name,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool success){
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(kReturnSignalInterface, signal_interface);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(kReturnSignalName, signal_name);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(success);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Behaves as |mock_resolver_|'s ResolveProxy().
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MockResolveProxy(const std::string& source_url,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& signal_interface,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& signal_name,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        scoped_refptr<dbus::ExportedObject> exported_object) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (source_url == kSourceURL) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::Signal signal(signal_interface,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          signal_name);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::MessageWriter writer(&signal);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writer.AppendString(kSourceURL);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writer.AppendString(kReturnProxyInfo);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writer.AppendString(kReturnEmptyErrorMessage);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Send the signal back to the requested signal interface and the
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // signal name.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exported_object->SendSignal(&signal);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Unexpected source URL: " << source_url;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool signal_received_successfully_;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ServiceProviderTestHelper test_helper_;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<CrosDBusService::ServiceProviderInterface> service_provider_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProxyResolutionServiceProviderTest, ResolveProxy) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The signal is not yet received.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(signal_received_successfully_);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a method call to resolve proxy config for kSourceURL.
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dbus::MethodCall method_call(kLibCrosServiceInterface, kResolveNetworkProxy);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::MessageWriter writer(&method_call);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(kSourceURL);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(kReturnSignalInterface);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  writer.AppendString(kReturnSignalName);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call the ResolveNetworkProxy method.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<dbus::Response> response(test_helper_.CallMethod(&method_call));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An empty response should be returned.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response.get());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::MessageReader reader(response.get());
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(reader.HasMoreData());
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Confirm that the signal is received successfully.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The contents of the signal are checked in OnSignalReceived().
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(signal_received_successfully_);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
180