1// Copyright (c) 2011 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 "chrome/browser/chromeos/login/signed_settings_helper.h"
6
7#include "chrome/browser/chromeos/cros/cros_library.h"
8#include "chrome/browser/chromeos/cros_settings_names.h"
9#include "chrome/browser/chromeos/login/mock_ownership_service.h"
10#include "chrome/browser/chromeos/login/owner_manager.h"
11#include "chrome/browser/chromeos/login/signed_settings.h"
12#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
13#include "chrome/browser/policy/proto/device_management_backend.pb.h"
14#include "content/browser/browser_thread.h"
15#include "testing/gmock/include/gmock/gmock.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18using ::testing::_;
19using ::testing::A;
20using ::testing::AtLeast;
21using ::testing::InSequence;
22using ::testing::Invoke;
23using ::testing::Return;
24using ::testing::ReturnRef;
25using ::testing::SaveArg;
26using ::testing::WithArg;
27
28namespace em = enterprise_management;
29namespace chromeos {
30
31class MockSignedSettingsHelperCallback : public SignedSettingsHelper::Callback {
32 public:
33  MOCK_METHOD2(OnCheckWhitelistCompleted, void(
34      SignedSettings::ReturnCode code, const std::string& email));
35  MOCK_METHOD2(OnWhitelistCompleted, void(
36      SignedSettings::ReturnCode code, const std::string& email));
37  MOCK_METHOD2(OnUnwhitelistCompleted, void(
38      SignedSettings::ReturnCode code, const std::string& email));
39  MOCK_METHOD3(OnStorePropertyCompleted, void(
40      SignedSettings::ReturnCode code,
41      const std::string& name,
42      const std::string& value));
43  MOCK_METHOD3(OnRetrievePropertyCompleted, void(
44      SignedSettings::ReturnCode code,
45      const std::string& name,
46      const std::string& value));
47};
48
49class SignedSettingsHelperTest : public ::testing::Test,
50                                 public SignedSettingsHelper::TestDelegate {
51 public:
52  SignedSettingsHelperTest()
53      : fake_email_("fakey@example.com"),
54        fake_prop_(kAccountsPrefAllowGuest),
55        fake_value_("false"),
56        message_loop_(MessageLoop::TYPE_UI),
57        ui_thread_(BrowserThread::UI, &message_loop_),
58        file_thread_(BrowserThread::FILE),
59        pending_ops_(0) {
60  }
61
62  virtual void SetUp() {
63    file_thread_.Start();
64    SignedSettingsHelper::Get()->set_test_delegate(this);
65  }
66
67  virtual void TearDown() {
68    SignedSettingsHelper::Get()->set_test_delegate(NULL);
69  }
70
71  virtual void OnOpCreated(SignedSettings* op) {
72    // Use MockOwnershipService for all SignedSettings op.
73    op->set_service(&m_);
74  }
75
76  virtual void OnOpStarted(SignedSettings* op) {
77  }
78
79  virtual void OnOpCompleted(SignedSettings* op) {
80    --pending_ops_;
81    if (!pending_ops_)
82      MessageLoop::current()->Quit();
83  }
84
85  static void OnKeyOpComplete(OwnerManager::Delegate* op) {
86    op->OnKeyOpComplete(OwnerManager::SUCCESS, std::vector<uint8>());
87  }
88
89  em::PolicyData BuildPolicyData() {
90    em::PolicyData to_return;
91    em::ChromeDeviceSettingsProto pol;
92    to_return.set_policy_type(SignedSettings::kDevicePolicyType);
93    to_return.set_policy_value(pol.SerializeAsString());
94    return to_return;
95  }
96
97  const std::string fake_email_;
98  const std::string fake_prop_;
99  const std::string fake_value_;
100  MockOwnershipService m_;
101
102  MessageLoop message_loop_;
103  BrowserThread ui_thread_;
104  BrowserThread file_thread_;
105
106  int pending_ops_;
107
108  ScopedStubCrosEnabler stub_cros_enabler_;
109};
110
111TEST_F(SignedSettingsHelperTest, SerializedOps) {
112  MockSignedSettingsHelperCallback cb;
113
114  EXPECT_CALL(m_, GetStatus(_))
115      .Times(2)
116      .WillRepeatedly(Return(OwnershipService::OWNERSHIP_TAKEN));
117  EXPECT_CALL(m_, has_cached_policy())
118      .Times(5)
119      .WillRepeatedly(Return(true));
120  em::PolicyData fake_pol = BuildPolicyData();
121  EXPECT_CALL(m_, cached_policy())
122      .Times(5)
123      .WillRepeatedly(ReturnRef(fake_pol));
124  EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
125      .Times(3)
126      .WillRepeatedly(SaveArg<0>(&fake_pol));
127
128  InSequence s;
129  EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>()))
130      .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete)));
131  EXPECT_CALL(cb, OnWhitelistCompleted(SignedSettings::SUCCESS, _))
132      .Times(1);
133
134  EXPECT_CALL(cb, OnCheckWhitelistCompleted(SignedSettings::SUCCESS, _))
135      .Times(1);
136
137  EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>()))
138      .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete)));
139  EXPECT_CALL(cb, OnUnwhitelistCompleted(SignedSettings::SUCCESS, _))
140      .Times(1);
141
142  EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>()))
143      .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete)));
144  EXPECT_CALL(cb, OnStorePropertyCompleted(SignedSettings::SUCCESS, _, _))
145      .Times(1);
146
147  EXPECT_CALL(cb, OnRetrievePropertyCompleted(SignedSettings::SUCCESS, _, _))
148      .Times(1);
149
150  pending_ops_ = 5;
151  SignedSettingsHelper::Get()->StartWhitelistOp(fake_email_, true, &cb);
152  SignedSettingsHelper::Get()->StartCheckWhitelistOp(fake_email_, &cb);
153  SignedSettingsHelper::Get()->StartWhitelistOp(fake_email_, false, &cb);
154  SignedSettingsHelper::Get()->StartStorePropertyOp(fake_prop_, fake_value_,
155      &cb);
156  SignedSettingsHelper::Get()->StartRetrieveProperty(fake_prop_, &cb);
157
158  message_loop_.Run();
159}
160
161TEST_F(SignedSettingsHelperTest, CanceledOps) {
162  MockSignedSettingsHelperCallback cb;
163
164  EXPECT_CALL(m_, GetStatus(_))
165      .Times(2)
166      .WillRepeatedly(Return(OwnershipService::OWNERSHIP_TAKEN));
167  EXPECT_CALL(m_, has_cached_policy())
168      .Times(6)
169      .WillRepeatedly(Return(true));
170  em::PolicyData fake_pol = BuildPolicyData();
171  EXPECT_CALL(m_, cached_policy())
172      .Times(7)
173      .WillRepeatedly(ReturnRef(fake_pol));
174  EXPECT_CALL(m_, set_cached_policy(A<const em::PolicyData&>()))
175      .Times(3)
176      .WillRepeatedly(SaveArg<0>(&fake_pol));
177
178  InSequence s;
179
180  EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>()))
181      .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete)));
182  EXPECT_CALL(cb, OnWhitelistCompleted(SignedSettings::SUCCESS, _))
183      .Times(1);
184
185  EXPECT_CALL(cb, OnCheckWhitelistCompleted(SignedSettings::SUCCESS, _))
186      .Times(1);
187
188  EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>()))
189      .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete)));
190  EXPECT_CALL(cb, OnUnwhitelistCompleted(SignedSettings::SUCCESS, _))
191      .Times(1);
192
193  // CheckWhitelistOp for cb_to_be_canceled still gets executed but callback
194  // does not happen.
195
196  EXPECT_CALL(m_, StartSigningAttempt(_, A<OwnerManager::Delegate*>()))
197      .WillOnce(WithArg<1>(Invoke(&SignedSettingsHelperTest::OnKeyOpComplete)));
198  EXPECT_CALL(cb, OnStorePropertyCompleted(SignedSettings::SUCCESS, _, _))
199      .Times(1);
200
201  EXPECT_CALL(cb, OnRetrievePropertyCompleted(SignedSettings::SUCCESS, _, _))
202      .Times(1);
203
204  pending_ops_ = 6;
205  SignedSettingsHelper::Get()->StartWhitelistOp(fake_email_, true, &cb);
206  SignedSettingsHelper::Get()->StartCheckWhitelistOp(fake_email_, &cb);
207  SignedSettingsHelper::Get()->StartWhitelistOp(fake_email_, false, &cb);
208
209  MockSignedSettingsHelperCallback cb_to_be_canceled;
210  SignedSettingsHelper::Get()->StartCheckWhitelistOp(fake_email_,
211      &cb_to_be_canceled);
212  SignedSettingsHelper::Get()->CancelCallback(&cb_to_be_canceled);
213
214  SignedSettingsHelper::Get()->StartStorePropertyOp(fake_prop_, fake_value_,
215      &cb);
216  SignedSettingsHelper::Get()->StartRetrieveProperty(fake_prop_, &cb);
217
218  message_loop_.Run();
219}
220
221}  // namespace chromeos
222