Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Side by Side Diff: chrome_frame/test/ready_mode_unittest.cc

Issue 5747002: Implement a ReadyPromptContent that displays a prompt to accept, temporarily ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/ready_mode/ready_mode_manager.h ('k') | tools/grit/resource_ids » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 <atlbase.h>
6 #include <atlapp.h>
7 #include <atlmisc.h>
8 #include <atlwin.h>
9
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12
13 #include "base/logging.h"
14 #include "base/scoped_ptr.h"
15 #include "base/win/registry.h"
16 #include "chrome_frame/infobars/infobar_content.h"
17 #include "chrome_frame/ready_mode/internal/installation_state.h"
18 #include "chrome_frame/ready_mode/internal/ready_mode_state.h"
19 #include "chrome_frame/ready_mode/internal/ready_prompt_content.h"
20 #include "chrome_frame/ready_mode/internal/ready_prompt_window.h"
21 #include "chrome_frame/ready_mode/internal/registry_ready_mode_state.h"
22 #include "chrome_frame/ready_mode/ready_mode_manager.h"
23 #include "chrome_frame/simple_resource_loader.h"
24 #include "chrome_frame/test/chrome_frame_test_utils.h"
25
26 namespace {
27
28 class SetResourceInstance {
29 public:
30 SetResourceInstance() : res_dll_(NULL), old_res_dll_(NULL) {
31 SimpleResourceLoader* loader_instance = SimpleResourceLoader::GetInstance();
32 EXPECT_TRUE(loader_instance != NULL);
33 if (loader_instance != NULL) {
34 res_dll_ = loader_instance->GetResourceModuleHandle();
35 EXPECT_TRUE(res_dll_ != NULL);
36 if (res_dll_ != NULL) {
37 old_res_dll_ = ATL::_AtlBaseModule.SetResourceInstance(res_dll_);
38 }
39 }
40 }
41
42 ~SetResourceInstance() {
43 if (old_res_dll_ != NULL) {
44 CHECK_EQ(res_dll_, ATL::_AtlBaseModule.SetResourceInstance(old_res_dll_));
45 }
46 }
47
48 private:
49 HMODULE res_dll_;
50 HMODULE old_res_dll_;
51 }; // class SetResourceInstance
52
53 class SimpleWindow : public CWindowImpl<SimpleWindow,
54 CWindow,
55 CFrameWinTraits> {
56 public:
57 virtual ~SimpleWindow() {
58 if (IsWindow())
59 DestroyWindow();
60 }
61
62 static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM l_param) {
63 HWND* out = reinterpret_cast<HWND*>(l_param);
64 EXPECT_TRUE(out != NULL);
65
66 if (out == NULL)
67 return FALSE;
68
69 EXPECT_TRUE(*out == NULL || ::IsChild(*out, hwnd));
70
71 if (*out == NULL)
72 *out = hwnd;
73
74 return TRUE;
75 }
76
77 HWND GetZeroOrOneChildWindows() {
78 HWND child = NULL;
79 EnumChildWindows(m_hWnd, EnumChildProc, reinterpret_cast<LPARAM>(&child));
80 return child;
81 }
82
83 BEGIN_MSG_MAP(SimpleWindow)
84 END_MSG_MAP()
85 }; // class SimpleWindow
86
87 class MockInfobarContentFrame : public InfobarContent::Frame {
88 public:
89 // InfobarContent::Frame implementation
90 MOCK_METHOD0(GetFrameWindow, HWND(void));
91 MOCK_METHOD0(CloseInfobar, void(void));
92 }; // class Frame
93
94 class MockReadyModeState : public ReadyModeState {
95 public:
96 // ReadyModeState implementation
97 MOCK_METHOD0(TemporarilyDeclineChromeFrame, void(void));
98 MOCK_METHOD0(PermanentlyDeclineChromeFrame, void(void));
99 MOCK_METHOD0(AcceptChromeFrame, void(void));
100 }; // class MockReadyModeState
101
102 ACTION_P(ReturnPointee, pointer) {
103 return *pointer;
104 }
105
106 ACTION_P2(SetPointeeTo, pointer, value) {
107 *pointer = value;
108 }
109
110 class MockInstallationState : public InstallationState {
111 public:
112 // InstallationState implementation
113 MOCK_METHOD0(IsProductInstalled, bool(void));
114 MOCK_METHOD0(IsProductRegistered, bool(void));
115 MOCK_METHOD0(InstallProduct, bool(void));
116 MOCK_METHOD0(UnregisterProduct, bool(void));
117 }; // class MockInstallationState
118
119 class MockRegistryReadyModeStateObserver
120 : public RegistryReadyModeState::Observer {
121 public:
122 // RegistryReadyModeState::Observer implementation
123 MOCK_METHOD0(OnStateChange, void(void));
124 }; // class MockRegistryReadyModeStateObserver
125
126 } // namespace
127
128 class ReadyPromptTest : public testing::Test {
129 public:
130 ReadyPromptTest() : hwnd_(NULL) {};
131
132 void SetUp() {
133 hwnd_ = window_.Create(NULL);
134 EXPECT_TRUE(hwnd_ != NULL);
135 window_.ShowWindow(SW_SHOW);
136 EXPECT_TRUE(window_.IsWindowVisible());
137 EXPECT_CALL(frame_, GetFrameWindow()).Times(testing::AnyNumber())
138 .WillRepeatedly(testing::Return(hwnd_));
139 }
140
141 protected:
142 SimpleWindow window_;
143 HWND hwnd_;
144 MockInfobarContentFrame frame_;
145 SetResourceInstance set_resource_instance_;
146 }; // class ReadyPromptTest
147
148 class ReadyPromptWindowTest : public ReadyPromptTest {
149 public:
150 void SetUp() {
151 ReadyPromptTest::SetUp();
152
153 // owned by ReadyPromptWindow
154 state_ = new MockReadyModeState();
155 ready_prompt_window_ = (new ReadyPromptWindow())->Initialize(&frame_,
156 state_);
157
158 ASSERT_TRUE(ready_prompt_window_ != NULL);
159 RECT position = {0, 0, 800, 39};
160 ASSERT_TRUE(ready_prompt_window_->SetWindowPos(HWND_TOP, &position,
161 SWP_SHOWWINDOW));
162 }
163
164 protected:
165 MockReadyModeState* state_;
166 base::WeakPtr<ReadyPromptWindow> ready_prompt_window_;
167 }; // class ReadyPromptWindowTest
168
169 class ReadyPromptWindowButtonTest : public ReadyPromptWindowTest {
170 public:
171 void TearDown() {
172 ASSERT_TRUE(ready_prompt_window_ != NULL);
173 ASSERT_TRUE(ready_prompt_window_->DestroyWindow());
174 ASSERT_TRUE(ready_prompt_window_ == NULL);
175 ASSERT_FALSE(message_loop_.WasTimedOut());
176
177 ReadyPromptWindowTest::TearDown();
178 }
179
180 protected:
181 struct ClickOnCaptionData {
182 const wchar_t* target_caption;
183 bool found;
184 }; // struct ClickOnCaptionData
185
186 static BOOL CALLBACK ClickOnCaptionProc(HWND hwnd, LPARAM l_param) {
187 wchar_t window_caption[256] = {0};
188 size_t buffer_length = arraysize(window_caption);
189
190 ClickOnCaptionData* data = reinterpret_cast<ClickOnCaptionData*>(l_param);
191 EXPECT_TRUE(data->target_caption != NULL);
192
193 if (data->target_caption == NULL)
194 return FALSE;
195
196 if (wcsnlen(data->target_caption, buffer_length + 1) == buffer_length + 1)
197 return FALSE;
198
199 if (::GetWindowText(hwnd, window_caption, buffer_length) ==
200 static_cast<int>(buffer_length)) {
201 return TRUE;
202 }
203
204 if (wcscmp(data->target_caption, window_caption) == 0) {
205 EXPECT_FALSE(data->found);
206
207 CRect client_rect;
208 EXPECT_TRUE(::GetClientRect(hwnd, client_rect));
209
210 CPoint center_point(client_rect.CenterPoint());
211 LPARAM coordinates = (center_point.y << 16) | center_point.x;
212
213 ::PostMessage(hwnd, WM_LBUTTONDOWN, 0, coordinates);
214 ::PostMessage(hwnd, WM_LBUTTONUP, 0, coordinates);
215
216 data->found = true;
217 }
218
219 return TRUE;
220 }
221
222 bool ClickOnCaption(const std::wstring& caption) {
223 ClickOnCaptionData data = {caption.c_str(), false};
224
225 ::EnumChildWindows(hwnd_, ClickOnCaptionProc,
226 reinterpret_cast<LPARAM>(&data));
227 return data.found;
228 }
229
230 void RunUntilCloseInfobar() {
231 EXPECT_CALL(frame_, CloseInfobar()).WillOnce(QUIT_LOOP(message_loop_));
232 ASSERT_NO_FATAL_FAILURE(message_loop_.RunFor(5)); // seconds
233 }
234
235 chrome_frame_test::TimedMsgLoop message_loop_;
236 }; // class ReadyPromptWindowButtonTest
237
238 TEST_F(ReadyPromptTest, ReadyPromptContentTest) {
239 // owned by ReadyPromptContent
240 MockReadyModeState* state = new MockReadyModeState();
241 scoped_ptr<ReadyPromptContent> content_(new ReadyPromptContent(state));
242
243 content_->InstallInFrame(&frame_);
244
245 // Ensure that, if a child is created, it is not visible yet.
246 HWND child_hwnd = window_.GetZeroOrOneChildWindows();
247 if (child_hwnd != NULL) {
248 CWindow child(child_hwnd);
249 RECT child_dimensions;
250 EXPECT_TRUE(child.GetClientRect(&child_dimensions));
251 EXPECT_FALSE(child.IsWindowVisible() && !::IsRectEmpty(&child_dimensions));
252 }
253
254 int desired_height = content_->GetDesiredSize(400, 0);
255 EXPECT_GT(desired_height, 0);
256 RECT dimensions = {10, 15, 410, 20};
257 content_->SetDimensions(dimensions);
258
259 child_hwnd = window_.GetZeroOrOneChildWindows();
260 EXPECT_TRUE(child_hwnd != NULL);
261
262 if (child_hwnd != NULL) {
263 CWindow child(child_hwnd);
264 EXPECT_TRUE(child.IsWindowVisible());
265 RECT child_dimensions;
266 EXPECT_TRUE(child.GetWindowRect(&child_dimensions));
267 EXPECT_TRUE(window_.ScreenToClient(&child_dimensions));
268 EXPECT_TRUE(::EqualRect(&child_dimensions, &dimensions));
269 }
270
271 // Being visible doesn't change the desired height
272 EXPECT_EQ(desired_height, content_->GetDesiredSize(400, 0));
273
274 content_.reset();
275
276 EXPECT_TRUE(window_.GetZeroOrOneChildWindows() == NULL);
277 }
278
279 TEST_F(ReadyPromptWindowTest, Destroy) {
280 // Should delete associated mocks, not invoke on ReadyModeState
281 ready_prompt_window_->DestroyWindow();
282 }
283
284 TEST_F(ReadyPromptWindowButtonTest, ClickYes) {
285 EXPECT_CALL(*state_, AcceptChromeFrame());
286 ASSERT_TRUE(ClickOnCaption(L"&Yes"));
287 RunUntilCloseInfobar();
288 }
289
290 TEST_F(ReadyPromptWindowButtonTest, ClickRemindMeLater) {
291 EXPECT_CALL(*state_, TemporarilyDeclineChromeFrame());
292 ASSERT_TRUE(ClickOnCaption(L"Remind me &Later"));
293 RunUntilCloseInfobar();
294 }
295
296 TEST_F(ReadyPromptWindowButtonTest, ClickNo) {
297 EXPECT_CALL(*state_, PermanentlyDeclineChromeFrame());
298 ASSERT_TRUE(ClickOnCaption(L"&No"));
299 RunUntilCloseInfobar();
300 }
301
302 class ReadyModeRegistryTest : public testing::Test {
303 public:
304 class TimeControlledRegistryReadyModeState : public RegistryReadyModeState {
305 public:
306 TimeControlledRegistryReadyModeState(
307 const std::wstring& key_name,
308 base::TimeDelta temporary_decline_duration,
309 InstallationState* installation_state,
310 Observer* observer)
311 : RegistryReadyModeState(key_name, temporary_decline_duration,
312 installation_state, observer),
313 now_(base::Time::Now()) {
314 }
315
316 base::Time now_;
317
318 protected:
319 virtual base::Time GetNow() {
320 return now_;
321 }
322 }; // class TimeControlledRegistryReadyModeState
323
324 ReadyModeRegistryTest()
325 : is_product_registered_(true),
326 is_product_installed_(false),
327 observer_(NULL),
328 installation_state_(NULL) {
329 }
330
331 virtual void SetUp() {
332 base::win::RegKey key;
333 ASSERT_TRUE(key.Create(HKEY_CURRENT_USER, kRootKey, KEY_ALL_ACCESS));
334 observer_ = new MockRegistryReadyModeStateObserver();
335 installation_state_ = new MockInstallationState();
336
337 EXPECT_CALL(*installation_state_, IsProductRegistered())
338 .Times(testing::AnyNumber())
339 .WillRepeatedly(ReturnPointee(&is_product_registered_));
340 EXPECT_CALL(*installation_state_, IsProductInstalled())
341 .Times(testing::AnyNumber())
342 .WillRepeatedly(ReturnPointee(&is_product_installed_));
343
344 ready_mode_state_.reset(new TimeControlledRegistryReadyModeState(
345 kRootKey,
346 base::TimeDelta::FromSeconds(kTemporaryDeclineDurationInSeconds),
347 installation_state_,
348 observer_));
349 }
350
351 virtual void TearDown() {
352 base::win::RegKey key;
353 EXPECT_TRUE(key.Open(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS));
354 EXPECT_TRUE(key.DeleteKey(kRootKey));
355 }
356
357 protected:
358 void AdjustClockBySeconds(int seconds) {
359 ready_mode_state_->now_ += base::TimeDelta::FromSeconds(seconds);
360 }
361
362 void ExpectUnregisterProductAndReturn(bool success) {
363 EXPECT_CALL(*installation_state_, UnregisterProduct())
364 .WillOnce(testing::DoAll(
365 SetPointeeTo(&is_product_registered_, !success),
366 testing::Return(success)));
367 }
368
369 void ExpectInstallProductAndReturn(bool success) {
370 EXPECT_CALL(*installation_state_, InstallProduct())
371 .WillOnce(testing::DoAll(SetPointeeTo(&is_product_installed_, success),
372 testing::Return(success)));
373 }
374
375 bool is_product_registered_;
376 bool is_product_installed_;
377 MockInstallationState* installation_state_;
378 MockRegistryReadyModeStateObserver* observer_;
379
380 scoped_ptr<TimeControlledRegistryReadyModeState> ready_mode_state_;
381 base::win::RegKey config_key;
382 static const wchar_t kRootKey[];
383 static const int kTemporaryDeclineDurationInSeconds;
384 }; // class ReadyModeRegistryTest
385
386 const int ReadyModeRegistryTest::kTemporaryDeclineDurationInSeconds = 2;
387 const wchar_t ReadyModeRegistryTest::kRootKey[] = L"chrome_frame_unittests";
388
389 TEST_F(ReadyModeRegistryTest, CallNothing) {
390 // expect it to delete the two mocks... Google Mock fails if they are leaked.
391 }
392
393 TEST_F(ReadyModeRegistryTest, NotInstalledStatus) {
394 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
395 }
396
397 TEST_F(ReadyModeRegistryTest, NotRegisteredStatus) {
398 is_product_registered_ = false;
399 ASSERT_EQ(READY_MODE_PERMANENTLY_DECLINED, ready_mode_state_->GetStatus());
400 }
401
402 TEST_F(ReadyModeRegistryTest, InstalledStatus) {
403 is_product_installed_ = true;
404 ASSERT_EQ(READY_MODE_ACCEPTED, ready_mode_state_->GetStatus());
405 }
406
407 TEST_F(ReadyModeRegistryTest, TemporarilyDeclineChromeFrame) {
408 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
409
410 EXPECT_CALL(*observer_, OnStateChange());
411 ready_mode_state_->TemporarilyDeclineChromeFrame();
412
413 ASSERT_EQ(READY_MODE_TEMPORARILY_DECLINED, ready_mode_state_->GetStatus());
414
415 AdjustClockBySeconds(kTemporaryDeclineDurationInSeconds + 1);
416 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
417 }
418
419 TEST_F(ReadyModeRegistryTest, TemporarilyDeclineChromeFrameSetClockBack) {
420 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
421
422 EXPECT_CALL(*observer_, OnStateChange());
423 ready_mode_state_->TemporarilyDeclineChromeFrame();
424
425 ASSERT_EQ(READY_MODE_TEMPORARILY_DECLINED, ready_mode_state_->GetStatus());
426
427 AdjustClockBySeconds(kTemporaryDeclineDurationInSeconds + 1);
428 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
429 }
430
431 TEST_F(ReadyModeRegistryTest, PermanentlyDeclineChromeFrame) {
432 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
433
434 EXPECT_CALL(*observer_, OnStateChange());
435 ExpectUnregisterProductAndReturn(true);
436 ready_mode_state_->PermanentlyDeclineChromeFrame();
437
438 ASSERT_EQ(READY_MODE_PERMANENTLY_DECLINED, ready_mode_state_->GetStatus());
439 }
440
441 TEST_F(ReadyModeRegistryTest, PermanentlyDeclineChromeFrameFailUnregister) {
442 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
443
444 EXPECT_CALL(*observer_, OnStateChange());
445 ExpectUnregisterProductAndReturn(false);
446 ready_mode_state_->PermanentlyDeclineChromeFrame();
447
448 ASSERT_EQ(READY_MODE_PERMANENTLY_DECLINED, ready_mode_state_->GetStatus());
449 }
450
451 TEST_F(ReadyModeRegistryTest, AcceptChromeFrame) {
452 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
453
454 EXPECT_CALL(*observer_, OnStateChange());
455 ExpectInstallProductAndReturn(true);
456 ready_mode_state_->AcceptChromeFrame();
457
458 ASSERT_EQ(READY_MODE_ACCEPTED, ready_mode_state_->GetStatus());
459 }
460
461 // TODO(erikwright): What do we actually want to happen if the install fails?
462 // Stay in Ready Mode? Attempt to unregister (deactivate ready mode)?
463 //
464 // Which component is responsible for messaging the user? The installer? The
465 // InstallationState implementation? The ReadyModeState implementation?
466 TEST_F(ReadyModeRegistryTest, AcceptChromeFrameInstallFails) {
467 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
468
469 ExpectInstallProductAndReturn(false);
470 ready_mode_state_->AcceptChromeFrame();
471
472 ASSERT_EQ(READY_MODE_ACTIVE, ready_mode_state_->GetStatus());
473 }
OLDNEW
« no previous file with comments | « chrome_frame/ready_mode/ready_mode_manager.h ('k') | tools/grit/resource_ids » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698