mobile_activator_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 "chrome/browser/chromeos/mobile/mobile_activator.h"
6
7#include "chrome/browser/chromeos/cros/mock_network_library.h"
8#include "chrome/browser/chromeos/cros/network_library.h"
9#include "content/public/browser/browser_thread.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13using std::string;
14
15using content::BrowserThread;
16using testing::_;
17using testing::Eq;
18using testing::Return;
19
20namespace {
21
22const char kTestServicePath[] = "/a/service/path";
23
24const size_t kNumOTASPStates = 3;
25
26chromeos::MobileActivator::PlanActivationState kOTASPStates[kNumOTASPStates] = {
27  chromeos::MobileActivator::PLAN_ACTIVATION_TRYING_OTASP,
28  chromeos::MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION,
29  chromeos::MobileActivator::PLAN_ACTIVATION_OTASP,
30};
31
32}  // namespace
33namespace chromeos {
34
35class TestMobileActivator : public MobileActivator {
36 public:
37  TestMobileActivator(MockNetworkLibrary* mock_network_library,
38                      CellularNetwork* cellular_network)
39      : mock_network_library_(mock_network_library),
40        cellular_network_(cellular_network) {
41    // Provide reasonable defaults for basic things we're usually not testing.
42    ON_CALL(*this, DCheckOnThread(_))
43        .WillByDefault(Return());
44    ON_CALL(*this, FindMatchingCellularNetwork(_))
45        .WillByDefault(Return(cellular_network));
46    ON_CALL(*this, GetNetworkLibrary())
47        .WillByDefault(Return(mock_network_library_));
48  }
49  virtual ~TestMobileActivator() {}
50
51  MOCK_METHOD3(ChangeState, void(CellularNetwork*,
52                                 MobileActivator::PlanActivationState,
53                                 const std::string&));
54  MOCK_METHOD1(EvaluateCellularNetwork, void(CellularNetwork*));
55  MOCK_METHOD1(FindMatchingCellularNetwork, CellularNetwork*(bool));
56  MOCK_METHOD0(StartOTASPTimer, void(void));
57
58  void InvokeChangeState(CellularNetwork* network,
59                         MobileActivator::PlanActivationState new_state,
60                         const std::string& error_description) {
61    MobileActivator::ChangeState(network, new_state, error_description);
62  }
63
64 private:
65  MOCK_CONST_METHOD0(GetNetworkLibrary, NetworkLibrary*(void));
66  MOCK_CONST_METHOD1(DCheckOnThread, void(const BrowserThread::ID id));
67
68  MockNetworkLibrary* mock_network_library_;
69  CellularNetwork* cellular_network_;
70
71  DISALLOW_COPY_AND_ASSIGN(TestMobileActivator);
72};
73
74class MobileActivatorTest : public testing::Test {
75 public:
76  MobileActivatorTest()
77      : network_library_(),
78        cellular_network_(string(kTestServicePath)),
79        mobile_activator_(&network_library_, &cellular_network_) {}
80  virtual ~MobileActivatorTest() {}
81
82 protected:
83  virtual void SetUp() {}
84  virtual void TearDown() {}
85
86  void set_activator_state(const MobileActivator::PlanActivationState state) {
87    mobile_activator_.state_ = state;
88  }
89  void set_network_activation_state(ActivationState state) {
90    cellular_network_.activation_state_ = state;
91  }
92  void set_connection_state(ConnectionState state) {
93    cellular_network_.state_ = state;
94  }
95
96  MockNetworkLibrary network_library_;
97  MockCellularNetwork cellular_network_;
98  TestMobileActivator mobile_activator_;
99 private:
100  DISALLOW_COPY_AND_ASSIGN(MobileActivatorTest);
101};
102
103TEST_F(MobileActivatorTest, BasicFlowForNewDevices) {
104  // In a new device, we aren't connected to Verizon, we start at START
105  // because we haven't paid Verizon (ever), and the modem isn't even partially
106  // activated.
107  std::string error_description;
108  set_activator_state(MobileActivator::PLAN_ACTIVATION_START);
109  set_connection_state(STATE_IDLE);
110  set_network_activation_state(ACTIVATION_STATE_NOT_ACTIVATED);
111  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION,
112            mobile_activator_.PickNextState(&cellular_network_,
113                                            &error_description));
114  // Now behave as if ChangeState() has initiated an activation.
115  set_activator_state(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION);
116  set_network_activation_state(ACTIVATION_STATE_ACTIVATING);
117  // We'll sit in this state while we wait for the OTASP to finish.
118  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION,
119            mobile_activator_.PickNextState(&cellular_network_,
120                                            &error_description));
121  set_network_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED);
122  // We'll sit in this state until we go online as well.
123  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION,
124            mobile_activator_.PickNextState(&cellular_network_,
125                                            &error_description));
126  set_connection_state(STATE_PORTAL);
127  // After we go online, we go back to START, which acts as a jumping off
128  // point for the two types of initial OTASP.
129  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_START,
130            mobile_activator_.PickNextState(&cellular_network_,
131                                            &error_description));
132  set_activator_state(MobileActivator::PLAN_ACTIVATION_START);
133  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_TRYING_OTASP,
134            mobile_activator_.PickNextState(&cellular_network_,
135                                            &error_description));
136  // Very similar things happen while we're trying OTASP.
137  set_activator_state(MobileActivator::PLAN_ACTIVATION_TRYING_OTASP);
138  set_network_activation_state(ACTIVATION_STATE_ACTIVATING);
139  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_TRYING_OTASP,
140            mobile_activator_.PickNextState(&cellular_network_,
141                                            &error_description));
142  set_network_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED);
143  set_connection_state(STATE_PORTAL);
144  // And when we come back online again and aren't activating, load the portal.
145  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING,
146            mobile_activator_.PickNextState(&cellular_network_,
147                                            &error_description));
148  // The JS drives us through the payment portal.
149  set_activator_state(MobileActivator::PLAN_ACTIVATION_SHOWING_PAYMENT);
150  // The JS also calls us to signal that the portal is done.  This triggers us
151  // to start our final OTASP via the aptly named StartOTASP().
152  EXPECT_CALL(network_library_, SignalCellularPlanPayment());
153  EXPECT_CALL(mobile_activator_,
154              ChangeState(Eq(&cellular_network_),
155                          Eq(MobileActivator::PLAN_ACTIVATION_START_OTASP),
156                          _));
157  EXPECT_CALL(mobile_activator_,
158              EvaluateCellularNetwork(Eq(&cellular_network_)));
159  mobile_activator_.HandleSetTransactionStatus(true);
160  // Evaluate state will defer to PickNextState to select what to do now that
161  // we're in START_ACTIVATION.  PickNextState should decide to start a final
162  // OTASP.
163  set_activator_state(MobileActivator::PLAN_ACTIVATION_START_OTASP);
164  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_OTASP,
165            mobile_activator_.PickNextState(&cellular_network_,
166                                            &error_description));
167  // Similarly to TRYING_OTASP and INITIATING_OTASP above...
168  set_activator_state(MobileActivator::PLAN_ACTIVATION_OTASP);
169  set_network_activation_state(ACTIVATION_STATE_ACTIVATING);
170  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_OTASP,
171            mobile_activator_.PickNextState(&cellular_network_,
172                                            &error_description));
173  set_network_activation_state(ACTIVATION_STATE_ACTIVATED);
174  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_DONE,
175            mobile_activator_.PickNextState(&cellular_network_,
176                                            &error_description));
177}
178
179TEST_F(MobileActivatorTest, OTASPScheduling) {
180  const std::string error;
181  for (size_t i = 0; i < kNumOTASPStates; ++i) {
182    // When activation works, we start a timer to watch for success.
183    EXPECT_CALL(cellular_network_, StartActivation())
184        .Times(1)
185        .WillOnce(Return(true));
186    EXPECT_CALL(mobile_activator_, StartOTASPTimer())
187        .Times(1);
188    set_activator_state(MobileActivator::PLAN_ACTIVATION_START);
189    mobile_activator_.InvokeChangeState(&cellular_network_,
190                                        kOTASPStates[i],
191                                        error);
192    // When activation fails, it's an error, unless we're trying for the final
193    // OTASP, in which case we try again via DELAY_OTASP.
194    EXPECT_CALL(cellular_network_, StartActivation())
195        .Times(1)
196        .WillOnce(Return(false));
197    if (kOTASPStates[i] == MobileActivator::PLAN_ACTIVATION_OTASP) {
198      EXPECT_CALL(mobile_activator_, ChangeState(
199          Eq(&cellular_network_),
200          Eq(MobileActivator::PLAN_ACTIVATION_DELAY_OTASP),
201          _));
202    } else {
203      EXPECT_CALL(mobile_activator_, ChangeState(
204          Eq(&cellular_network_),
205          Eq(MobileActivator::PLAN_ACTIVATION_ERROR),
206          _));
207    }
208    set_activator_state(MobileActivator::PLAN_ACTIVATION_START);
209    mobile_activator_.InvokeChangeState(&cellular_network_,
210                                        kOTASPStates[i],
211                                        error);
212  }
213}
214
215TEST_F(MobileActivatorTest, ReconnectOnDisconnectFromPaymentPortal) {
216  // Most states either don't care if we're offline or expect to be offline at
217  // some point.  For instance the OTASP states expect to go offline during
218  // activation and eventually come back.  There are a few transitions states
219  // like START_OTASP and DELAY_OTASP which don't really depend on the state of
220  // the modem (offline or online) to work correctly.  A few places however,
221  // like when we're displaying the portal care quite a bit about going
222  // offline.  Lets test for those cases.
223  std::string error_description;
224  set_connection_state(STATE_FAILURE);
225  set_network_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED);
226  set_activator_state(MobileActivator::PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING);
227  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_RECONNECTING,
228            mobile_activator_.PickNextState(&cellular_network_,
229                                            &error_description));
230  set_activator_state(MobileActivator::PLAN_ACTIVATION_SHOWING_PAYMENT);
231  EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_RECONNECTING,
232            mobile_activator_.PickNextState(&cellular_network_,
233                                            &error_description));
234}
235
236TEST_F(MobileActivatorTest, StartAtStart) {
237  EXPECT_CALL(network_library_,
238              AddNetworkManagerObserver(Eq(&mobile_activator_)));
239  EXPECT_CALL(network_library_, HasRecentCellularPlanPayment()).
240      WillOnce(Return(false));
241  EXPECT_CALL(mobile_activator_,
242              EvaluateCellularNetwork(Eq(&cellular_network_)));
243  mobile_activator_.StartActivation();
244  EXPECT_EQ(mobile_activator_.state(), MobileActivator::PLAN_ACTIVATION_START);
245}
246
247}  // namespace chromeos
248