Home | History | Annotate | Download | only in cloud_print
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <string>
      6 
      7 #include "base/command_line.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/prefs/testing_pref_service.h"
     11 #include "base/run_loop.h"
     12 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h"
     13 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.h"
     14 #include "chrome/browser/service_process/service_process_control.h"
     15 #include "chrome/browser/ui/startup/startup_browser_creator.h"
     16 #include "chrome/common/chrome_switches.h"
     17 #include "chrome/common/cloud_print/cloud_print_proxy_info.h"
     18 #include "chrome/common/pref_names.h"
     19 #include "chrome/common/service_messages.h"
     20 #include "chrome/test/base/testing_browser_process.h"
     21 #include "chrome/test/base/testing_pref_service_syncable.h"
     22 #include "chrome/test/base/testing_profile.h"
     23 #include "chrome/test/base/testing_profile_manager.h"
     24 #include "content/public/browser/browser_thread.h"
     25 #include "content/public/test/test_browser_thread.h"
     26 #include "testing/gmock/include/gmock/gmock.h"
     27 #include "testing/gtest/include/gtest/gtest.h"
     28 
     29 using ::testing::Assign;
     30 using ::testing::AtMost;
     31 using ::testing::DeleteArg;
     32 using ::testing::DoAll;
     33 using ::testing::Invoke;
     34 using ::testing::Property;
     35 using ::testing::Return;
     36 using ::testing::ReturnPointee;
     37 using ::testing::WithArgs;
     38 using ::testing::WithoutArgs;
     39 using ::testing::_;
     40 
     41 class MockServiceProcessControl : public ServiceProcessControl {
     42  public:
     43   static std::string EnabledUserId();
     44 
     45   MockServiceProcessControl() : connected_(false) { }
     46 
     47   MOCK_CONST_METHOD0(IsConnected, bool());
     48 
     49   MOCK_METHOD2(Launch, void(const base::Closure&, const base::Closure&));
     50   MOCK_METHOD0(Disconnect, void());
     51 
     52   MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&));
     53   MOCK_METHOD1(OnChannelConnected, void(int32 peer_pid));
     54   MOCK_METHOD0(OnChannelError, void());
     55 
     56   MOCK_METHOD1(Send, bool(IPC::Message*));
     57 
     58   typedef enum {
     59     kServiceStateDisabled,
     60     kServiceStateEnabled,
     61     kServiceStateNone
     62   } ServiceState;
     63 
     64   void SetConnectSuccessMockExpectations(ServiceState state, bool post_task);
     65 
     66   void SetServiceEnabledExpectations();
     67   void SetServiceDisabledExpectations();
     68   void SetWillBeEnabledExpectations();
     69   void SetWillBeDisabledExpectations();
     70 
     71   bool SendEnabledInfo();
     72   bool SendDisabledInfo();
     73 
     74  private:
     75   bool connected_;
     76   cloud_print::CloudPrintProxyInfo info_;
     77 };
     78 
     79 // static
     80 std::string MockServiceProcessControl::EnabledUserId() {
     81   return std::string("dorothy (at) somewhere.otr");
     82 }
     83 
     84 void CallTask(const base::Closure& task) {
     85   if (!task.is_null())
     86     task.Run();
     87 }
     88 
     89 void PostTask(const base::Closure& task) {
     90   if (!task.is_null())
     91     base::MessageLoop::current()->PostTask(FROM_HERE, task);
     92 }
     93 
     94 void MockServiceProcessControl::SetConnectSuccessMockExpectations(
     95     ServiceState service_state,
     96     bool post_task) {
     97   EXPECT_CALL(*this, IsConnected()).WillRepeatedly(ReturnPointee(&connected_));
     98 
     99   EXPECT_CALL(*this, Launch(_, _))
    100       .WillRepeatedly(
    101           DoAll(Assign(&connected_, true),
    102                 WithArgs<0>(Invoke(post_task ? PostTask : CallTask))));
    103 
    104   EXPECT_CALL(*this, Disconnect()).Times(AtMost(1))
    105       .WillRepeatedly(Assign(&connected_, false));
    106 
    107   EXPECT_CALL(*this, Send(_)).Times(0);
    108 
    109   if (service_state == kServiceStateEnabled)
    110     SetServiceEnabledExpectations();
    111   else if (service_state == kServiceStateDisabled)
    112     SetServiceDisabledExpectations();
    113 }
    114 
    115 void MockServiceProcessControl::SetServiceEnabledExpectations() {
    116   EXPECT_CALL(
    117       *this,
    118       Send(Property(&IPC::Message::type,
    119                     static_cast<int32>(ServiceMsg_GetCloudPrintProxyInfo::ID))))
    120       .Times(1).WillOnce(
    121           DoAll(
    122               DeleteArg<0>(),
    123               WithoutArgs(
    124                   Invoke(this, &MockServiceProcessControl::SendEnabledInfo))));
    125 }
    126 
    127 void MockServiceProcessControl::SetServiceDisabledExpectations() {
    128   EXPECT_CALL(
    129       *this,
    130       Send(Property(&IPC::Message::type,
    131                     static_cast<int32>(ServiceMsg_GetCloudPrintProxyInfo::ID))))
    132       .Times(1).WillOnce(
    133           DoAll(
    134               DeleteArg<0>(),
    135               WithoutArgs(
    136                   Invoke(this, &MockServiceProcessControl::SendDisabledInfo))));
    137 }
    138 
    139 void MockServiceProcessControl::SetWillBeEnabledExpectations() {
    140   int32 message_id = ServiceMsg_EnableCloudPrintProxyWithRobot::ID;
    141   EXPECT_CALL(
    142       *this,
    143       Send(Property(&IPC::Message::type, message_id)))
    144       .Times(1).WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    145 }
    146 
    147 void MockServiceProcessControl::SetWillBeDisabledExpectations() {
    148   EXPECT_CALL(
    149       *this,
    150       Send(Property(&IPC::Message::type,
    151                     static_cast<int32>(ServiceMsg_DisableCloudPrintProxy::ID))))
    152       .Times(1).WillOnce(DoAll(DeleteArg<0>(), Return(true)));
    153 }
    154 
    155 bool MockServiceProcessControl::SendEnabledInfo() {
    156   info_.enabled = true;
    157   info_.email = EnabledUserId();
    158   PostTask(base::Bind(&MockServiceProcessControl::OnCloudPrintProxyInfo,
    159                       base::Unretained(this), info_));
    160   return true;
    161 }
    162 
    163 bool MockServiceProcessControl::SendDisabledInfo() {
    164   info_.enabled = false;
    165   info_.email = std::string();
    166   PostTask(base::Bind(&MockServiceProcessControl::OnCloudPrintProxyInfo,
    167                       base::Unretained(this), info_));
    168   return true;
    169 }
    170 
    171 class TestCloudPrintProxyService : public CloudPrintProxyService {
    172  public:
    173   explicit TestCloudPrintProxyService(Profile* profile)
    174       : CloudPrintProxyService(profile) { }
    175 
    176   void Initialize() {
    177     CloudPrintProxyService::Initialize();
    178     base::RunLoop().RunUntilIdle();
    179   }
    180 
    181   void RefreshStatusFromService() {
    182     CloudPrintProxyService::RefreshStatusFromService();
    183     base::RunLoop().RunUntilIdle();
    184   }
    185 
    186   virtual ServiceProcessControl* GetServiceProcessControl() OVERRIDE {
    187     return &process_control_;
    188   }
    189   MockServiceProcessControl* GetMockServiceProcessControl() {
    190     return &process_control_;
    191   }
    192 
    193   void EnableForUser() {
    194     EnableForUserWithRobot("123", "123 (at) gmail.com",
    195                            MockServiceProcessControl::EnabledUserId(),
    196                            base::DictionaryValue());
    197   }
    198 
    199  private:
    200   MockServiceProcessControl process_control_;
    201 };
    202 
    203 class CloudPrintProxyPolicyTest : public ::testing::Test {
    204  public:
    205   CloudPrintProxyPolicyTest()
    206       : ui_thread_(content::BrowserThread::UI, &message_loop_) {
    207   }
    208 
    209   bool LaunchBrowser(const CommandLine& command_line, Profile* profile) {
    210     int return_code = 0;
    211     StartupBrowserCreator browser_creator;
    212     return StartupBrowserCreator::ProcessCmdLineImpl(
    213         command_line, base::FilePath(), false, profile,
    214         StartupBrowserCreator::Profiles(), &return_code, &browser_creator);
    215   }
    216 
    217  protected:
    218   base::MessageLoopForUI message_loop_;
    219   content::TestBrowserThread ui_thread_;
    220   TestingProfile profile_;
    221 };
    222 
    223 TEST_F(CloudPrintProxyPolicyTest, VerifyExpectations) {
    224   MockServiceProcessControl mock_control;
    225   mock_control.SetConnectSuccessMockExpectations(
    226       MockServiceProcessControl::kServiceStateNone, false);
    227 
    228   EXPECT_FALSE(mock_control.IsConnected());
    229   mock_control.Launch(base::Closure(), base::Closure());
    230   EXPECT_TRUE(mock_control.IsConnected());
    231   mock_control.Launch(base::Closure(), base::Closure());
    232   EXPECT_TRUE(mock_control.IsConnected());
    233   mock_control.Disconnect();
    234   EXPECT_FALSE(mock_control.IsConnected());
    235 }
    236 
    237 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyDisabled) {
    238   TestCloudPrintProxyService service(&profile_);
    239 
    240   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    241       MockServiceProcessControl::kServiceStateDisabled, false);
    242 
    243   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    244   prefs->SetUserPref(prefs::kCloudPrintEmail,
    245                      base::Value::CreateStringValue(
    246                          MockServiceProcessControl::EnabledUserId()));
    247 
    248   service.Initialize();
    249 
    250   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    251 }
    252 
    253 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyEnabled) {
    254   TestCloudPrintProxyService service(&profile_);
    255 
    256   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    257       MockServiceProcessControl::kServiceStateEnabled, false);
    258 
    259   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    260   prefs->SetUserPref(prefs::kCloudPrintEmail,
    261                      base::Value::CreateStringValue(std::string()));
    262 
    263   service.Initialize();
    264   service.RefreshStatusFromService();
    265 
    266   EXPECT_EQ(MockServiceProcessControl::EnabledUserId(),
    267             prefs->GetString(prefs::kCloudPrintEmail));
    268 }
    269 
    270 TEST_F(CloudPrintProxyPolicyTest, StartWithPolicySetProxyDisabled) {
    271   TestCloudPrintProxyService service(&profile_);
    272 
    273   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    274       MockServiceProcessControl::kServiceStateDisabled, false);
    275 
    276   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    277   prefs->SetUserPref(prefs::kCloudPrintEmail,
    278                      base::Value::CreateStringValue(std::string()));
    279   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    280                         base::Value::CreateBooleanValue(false));
    281 
    282   service.Initialize();
    283 
    284   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    285 }
    286 
    287 TEST_F(CloudPrintProxyPolicyTest, StartWithPolicySetProxyEnabled) {
    288   TestCloudPrintProxyService service(&profile_);
    289 
    290   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    291       MockServiceProcessControl::kServiceStateEnabled, false);
    292   service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations();
    293 
    294   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    295   prefs->SetUserPref(prefs::kCloudPrintEmail,
    296                      base::Value::CreateStringValue(std::string()));
    297   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    298                         base::Value::CreateBooleanValue(false));
    299 
    300   service.Initialize();
    301 
    302   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    303 }
    304 
    305 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyDisabledThenSetPolicy) {
    306   TestCloudPrintProxyService service(&profile_);
    307 
    308   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    309       MockServiceProcessControl::kServiceStateDisabled, false);
    310 
    311   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    312   prefs->SetUserPref(prefs::kCloudPrintEmail,
    313                      base::Value::CreateStringValue(
    314                          MockServiceProcessControl::EnabledUserId()));
    315 
    316   service.Initialize();
    317 
    318   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    319 
    320   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    321                         base::Value::CreateBooleanValue(false));
    322 
    323   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    324 }
    325 
    326 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyEnabledThenSetPolicy) {
    327   TestCloudPrintProxyService service(&profile_);
    328 
    329   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    330       MockServiceProcessControl::kServiceStateEnabled, false);
    331 
    332   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    333   prefs->SetUserPref(prefs::kCloudPrintEmail,
    334                      base::Value::CreateStringValue(std::string()));
    335 
    336   service.Initialize();
    337   service.RefreshStatusFromService();
    338 
    339   EXPECT_EQ(MockServiceProcessControl::EnabledUserId(),
    340             prefs->GetString(prefs::kCloudPrintEmail));
    341 
    342   service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations();
    343   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    344                         base::Value::CreateBooleanValue(false));
    345 
    346   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    347 }
    348 
    349 TEST_F(CloudPrintProxyPolicyTest,
    350        StartWithPolicySetProxyDisabledThenClearPolicy) {
    351   TestCloudPrintProxyService service(&profile_);
    352 
    353   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    354       MockServiceProcessControl::kServiceStateDisabled, false);
    355 
    356   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    357   prefs->SetUserPref(prefs::kCloudPrintEmail,
    358                      base::Value::CreateStringValue(std::string()));
    359   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    360                         base::Value::CreateBooleanValue(false));
    361 
    362   service.Initialize();
    363 
    364   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    365   prefs->RemoveManagedPref(prefs::kCloudPrintProxyEnabled);
    366   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    367 }
    368 
    369 TEST_F(CloudPrintProxyPolicyTest,
    370        StartWithPolicySetProxyEnabledThenClearPolicy) {
    371   TestCloudPrintProxyService service(&profile_);
    372 
    373   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    374       MockServiceProcessControl::kServiceStateEnabled, false);
    375   service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations();
    376 
    377   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    378   prefs->SetUserPref(prefs::kCloudPrintEmail,
    379                      base::Value::CreateStringValue(std::string()));
    380   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    381                         base::Value::CreateBooleanValue(false));
    382 
    383   service.Initialize();
    384 
    385   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    386   prefs->RemoveManagedPref(prefs::kCloudPrintProxyEnabled);
    387   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    388 }
    389 
    390 TEST_F(CloudPrintProxyPolicyTest, StartWithNoPolicyProxyDisabledThenEnable) {
    391   TestCloudPrintProxyService service(&profile_);
    392 
    393   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    394       MockServiceProcessControl::kServiceStateDisabled, false);
    395 
    396   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    397   prefs->SetUserPref(prefs::kCloudPrintEmail,
    398                      base::Value::CreateStringValue(
    399                          MockServiceProcessControl::EnabledUserId()));
    400 
    401   service.Initialize();
    402   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    403 
    404   service.GetMockServiceProcessControl()->SetWillBeEnabledExpectations();
    405   service.EnableForUser();
    406 
    407   EXPECT_EQ(MockServiceProcessControl::EnabledUserId(),
    408             prefs->GetString(prefs::kCloudPrintEmail));
    409 }
    410 
    411 TEST_F(CloudPrintProxyPolicyTest,
    412        StartWithPolicySetProxyEnabledThenClearPolicyAndEnable) {
    413   TestCloudPrintProxyService service(&profile_);
    414 
    415   service.GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    416       MockServiceProcessControl::kServiceStateEnabled, false);
    417   service.GetMockServiceProcessControl()->SetWillBeDisabledExpectations();
    418 
    419   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    420   prefs->SetUserPref(prefs::kCloudPrintEmail,
    421                      base::Value::CreateStringValue(std::string()));
    422   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    423                         base::Value::CreateBooleanValue(false));
    424 
    425   service.Initialize();
    426 
    427   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    428   service.EnableForUser();
    429   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    430 
    431   prefs->RemoveManagedPref(prefs::kCloudPrintProxyEnabled);
    432   EXPECT_EQ(std::string(), prefs->GetString(prefs::kCloudPrintEmail));
    433 
    434   service.GetMockServiceProcessControl()->SetWillBeEnabledExpectations();
    435   service.EnableForUser();
    436 
    437   EXPECT_EQ(MockServiceProcessControl::EnabledUserId(),
    438             prefs->GetString(prefs::kCloudPrintEmail));
    439 }
    440 
    441 KeyedService* TestCloudPrintProxyServiceFactory(
    442     content::BrowserContext* profile) {
    443   TestCloudPrintProxyService* service =
    444       new TestCloudPrintProxyService(static_cast<Profile*>(profile));
    445 
    446   service->GetMockServiceProcessControl()->SetConnectSuccessMockExpectations(
    447       MockServiceProcessControl::kServiceStateEnabled, true);
    448   service->GetMockServiceProcessControl()->SetWillBeDisabledExpectations();
    449 
    450   service->Initialize();
    451   return service;
    452 }
    453 
    454 TEST_F(CloudPrintProxyPolicyTest, StartupBrowserCreatorWithCommandLine) {
    455   TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService();
    456   prefs->SetUserPref(prefs::kCloudPrintEmail,
    457                      base::Value::CreateStringValue(std::string()));
    458   prefs->SetManagedPref(prefs::kCloudPrintProxyEnabled,
    459                         base::Value::CreateBooleanValue(false));
    460 
    461   CloudPrintProxyServiceFactory::GetInstance()->
    462       SetTestingFactory(&profile_, TestCloudPrintProxyServiceFactory);
    463 
    464   CommandLine command_line(CommandLine::NO_PROGRAM);
    465   command_line.AppendSwitch(switches::kCheckCloudPrintConnectorPolicy);
    466 
    467   EXPECT_FALSE(LaunchBrowser(command_line, &profile_));
    468   base::RunLoop().RunUntilIdle();
    469 }
    470