blob: 6a508a2b7402f0d89304b5b99418eb4866d7097c [file] [log] [blame]
[email protected]6f9832e2012-04-11 19:45:181// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2bf5f4152010-12-14 20:56:012// 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"
[email protected]3b63f8f42011-03-28 01:54:1514#include "base/memory/scoped_ptr.h"
[email protected]2bf5f4152010-12-14 20:56:0115#include "base/win/registry.h"
16#include "chrome_frame/infobars/infobar_content.h"
[email protected]2bf5f4152010-12-14 20:56:0117#include "chrome_frame/ready_mode/internal/ready_mode_state.h"
18#include "chrome_frame/ready_mode/internal/ready_prompt_content.h"
19#include "chrome_frame/ready_mode/internal/ready_prompt_window.h"
20#include "chrome_frame/ready_mode/internal/registry_ready_mode_state.h"
[email protected]28efc582011-01-24 19:27:3221#include "chrome_frame/ready_mode/internal/url_launcher.h"
[email protected]2bf5f4152010-12-14 20:56:0122#include "chrome_frame/simple_resource_loader.h"
23#include "chrome_frame/test/chrome_frame_test_utils.h"
24
25namespace {
26
27class SetResourceInstance {
28 public:
29 SetResourceInstance() : res_dll_(NULL), old_res_dll_(NULL) {
30 SimpleResourceLoader* loader_instance = SimpleResourceLoader::GetInstance();
31 EXPECT_TRUE(loader_instance != NULL);
32 if (loader_instance != NULL) {
33 res_dll_ = loader_instance->GetResourceModuleHandle();
34 EXPECT_TRUE(res_dll_ != NULL);
35 if (res_dll_ != NULL) {
36 old_res_dll_ = ATL::_AtlBaseModule.SetResourceInstance(res_dll_);
37 }
38 }
39 }
40
41 ~SetResourceInstance() {
42 if (old_res_dll_ != NULL) {
43 CHECK_EQ(res_dll_, ATL::_AtlBaseModule.SetResourceInstance(old_res_dll_));
44 }
45 }
46
47 private:
48 HMODULE res_dll_;
49 HMODULE old_res_dll_;
50}; // class SetResourceInstance
51
52class SimpleWindow : public CWindowImpl<SimpleWindow,
53 CWindow,
54 CFrameWinTraits> {
55 public:
56 virtual ~SimpleWindow() {
57 if (IsWindow())
58 DestroyWindow();
59 }
60
61 static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM l_param) {
62 HWND* out = reinterpret_cast<HWND*>(l_param);
63 EXPECT_TRUE(out != NULL);
64
65 if (out == NULL)
66 return FALSE;
67
68 EXPECT_TRUE(*out == NULL || ::IsChild(*out, hwnd));
69
70 if (*out == NULL)
71 *out = hwnd;
72
73 return TRUE;
74 }
75
76 HWND GetZeroOrOneChildWindows() {
77 HWND child = NULL;
78 EnumChildWindows(m_hWnd, EnumChildProc, reinterpret_cast<LPARAM>(&child));
79 return child;
80 }
81
82 BEGIN_MSG_MAP(SimpleWindow)
83 END_MSG_MAP()
84}; // class SimpleWindow
85
86class MockInfobarContentFrame : public InfobarContent::Frame {
87 public:
88 // InfobarContent::Frame implementation
89 MOCK_METHOD0(GetFrameWindow, HWND(void));
90 MOCK_METHOD0(CloseInfobar, void(void));
91}; // class Frame
92
93class MockReadyModeState : public ReadyModeState {
94 public:
95 // ReadyModeState implementation
96 MOCK_METHOD0(TemporarilyDeclineChromeFrame, void(void));
97 MOCK_METHOD0(PermanentlyDeclineChromeFrame, void(void));
98 MOCK_METHOD0(AcceptChromeFrame, void(void));
99}; // class MockReadyModeState
100
[email protected]28efc582011-01-24 19:27:32101class MockUrlLauncher : public UrlLauncher {
102 public:
103 // UrlLauncher implementation
104 MOCK_METHOD1(LaunchUrl, void(const std::wstring& url));
105}; // class MockUrlLauncher
106
[email protected]2bf5f4152010-12-14 20:56:01107} // namespace
108
109class ReadyPromptTest : public testing::Test {
110 public:
[email protected]6e58a952011-01-12 19:28:50111 ReadyPromptTest() : hwnd_(NULL) {}
[email protected]2bf5f4152010-12-14 20:56:01112
113 void SetUp() {
114 hwnd_ = window_.Create(NULL);
115 EXPECT_TRUE(hwnd_ != NULL);
116 window_.ShowWindow(SW_SHOW);
117 EXPECT_TRUE(window_.IsWindowVisible());
118 EXPECT_CALL(frame_, GetFrameWindow()).Times(testing::AnyNumber())
119 .WillRepeatedly(testing::Return(hwnd_));
120 }
121
122 protected:
123 SimpleWindow window_;
124 HWND hwnd_;
125 MockInfobarContentFrame frame_;
126 SetResourceInstance set_resource_instance_;
127}; // class ReadyPromptTest
128
129class ReadyPromptWindowTest : public ReadyPromptTest {
130 public:
131 void SetUp() {
132 ReadyPromptTest::SetUp();
133
134 // owned by ReadyPromptWindow
135 state_ = new MockReadyModeState();
[email protected]28efc582011-01-24 19:27:32136 url_launcher_ = new MockUrlLauncher();
137
138 ready_prompt_window_ = ReadyPromptWindow::CreateInstance(
139 &frame_, state_, url_launcher_);
[email protected]2bf5f4152010-12-14 20:56:01140
141 ASSERT_TRUE(ready_prompt_window_ != NULL);
142 RECT position = {0, 0, 800, 39};
143 ASSERT_TRUE(ready_prompt_window_->SetWindowPos(HWND_TOP, &position,
144 SWP_SHOWWINDOW));
145 }
146
147 protected:
148 MockReadyModeState* state_;
[email protected]28efc582011-01-24 19:27:32149 MockUrlLauncher* url_launcher_;
[email protected]2bf5f4152010-12-14 20:56:01150 base::WeakPtr<ReadyPromptWindow> ready_prompt_window_;
151}; // class ReadyPromptWindowTest
152
153class ReadyPromptWindowButtonTest : public ReadyPromptWindowTest {
154 public:
155 void TearDown() {
156 ASSERT_TRUE(ready_prompt_window_ != NULL);
157 ASSERT_TRUE(ready_prompt_window_->DestroyWindow());
158 ASSERT_TRUE(ready_prompt_window_ == NULL);
159 ASSERT_FALSE(message_loop_.WasTimedOut());
160
161 ReadyPromptWindowTest::TearDown();
162 }
163
164 protected:
165 struct ClickOnCaptionData {
166 const wchar_t* target_caption;
167 bool found;
168 }; // struct ClickOnCaptionData
169
170 static BOOL CALLBACK ClickOnCaptionProc(HWND hwnd, LPARAM l_param) {
171 wchar_t window_caption[256] = {0};
172 size_t buffer_length = arraysize(window_caption);
173
174 ClickOnCaptionData* data = reinterpret_cast<ClickOnCaptionData*>(l_param);
175 EXPECT_TRUE(data->target_caption != NULL);
176
177 if (data->target_caption == NULL)
178 return FALSE;
179
180 if (wcsnlen(data->target_caption, buffer_length + 1) == buffer_length + 1)
181 return FALSE;
182
183 if (::GetWindowText(hwnd, window_caption, buffer_length) ==
184 static_cast<int>(buffer_length)) {
185 return TRUE;
186 }
187
188 if (wcscmp(data->target_caption, window_caption) == 0) {
189 EXPECT_FALSE(data->found);
190
191 CRect client_rect;
192 EXPECT_TRUE(::GetClientRect(hwnd, client_rect));
193
194 CPoint center_point(client_rect.CenterPoint());
195 LPARAM coordinates = (center_point.y << 16) | center_point.x;
196
197 ::PostMessage(hwnd, WM_LBUTTONDOWN, 0, coordinates);
198 ::PostMessage(hwnd, WM_LBUTTONUP, 0, coordinates);
199
200 data->found = true;
201 }
202
203 return TRUE;
204 }
205
206 bool ClickOnCaption(const std::wstring& caption) {
207 ClickOnCaptionData data = {caption.c_str(), false};
208
209 ::EnumChildWindows(hwnd_, ClickOnCaptionProc,
210 reinterpret_cast<LPARAM>(&data));
211 return data.found;
212 }
213
214 void RunUntilCloseInfobar() {
215 EXPECT_CALL(frame_, CloseInfobar()).WillOnce(QUIT_LOOP(message_loop_));
[email protected]6f9832e2012-04-11 19:45:18216 ASSERT_NO_FATAL_FAILURE(message_loop_.RunFor(
217 base::TimeDelta::FromSeconds(5)));
[email protected]2bf5f4152010-12-14 20:56:01218 }
219
220 chrome_frame_test::TimedMsgLoop message_loop_;
221}; // class ReadyPromptWindowButtonTest
222
[email protected]801df8f52011-08-26 20:20:54223TEST_F(ReadyPromptTest, ReadyPromptContentTest) {
[email protected]2bf5f4152010-12-14 20:56:01224 // owned by ReadyPromptContent
225 MockReadyModeState* state = new MockReadyModeState();
[email protected]28efc582011-01-24 19:27:32226 MockUrlLauncher* url_launcher = new MockUrlLauncher();
227
228 scoped_ptr<ReadyPromptContent> content_(new ReadyPromptContent(state,
229 url_launcher));
[email protected]2bf5f4152010-12-14 20:56:01230
231 content_->InstallInFrame(&frame_);
232
233 // Ensure that, if a child is created, it is not visible yet.
234 HWND child_hwnd = window_.GetZeroOrOneChildWindows();
235 if (child_hwnd != NULL) {
236 CWindow child(child_hwnd);
237 RECT child_dimensions;
238 EXPECT_TRUE(child.GetClientRect(&child_dimensions));
239 EXPECT_FALSE(child.IsWindowVisible() && !::IsRectEmpty(&child_dimensions));
240 }
241
242 int desired_height = content_->GetDesiredSize(400, 0);
243 EXPECT_GT(desired_height, 0);
244 RECT dimensions = {10, 15, 410, 20};
245 content_->SetDimensions(dimensions);
246
247 child_hwnd = window_.GetZeroOrOneChildWindows();
248 EXPECT_TRUE(child_hwnd != NULL);
249
250 if (child_hwnd != NULL) {
251 CWindow child(child_hwnd);
252 EXPECT_TRUE(child.IsWindowVisible());
253 RECT child_dimensions;
254 EXPECT_TRUE(child.GetWindowRect(&child_dimensions));
255 EXPECT_TRUE(window_.ScreenToClient(&child_dimensions));
256 EXPECT_TRUE(::EqualRect(&child_dimensions, &dimensions));
257 }
258
259 // Being visible doesn't change the desired height
260 EXPECT_EQ(desired_height, content_->GetDesiredSize(400, 0));
261
262 content_.reset();
263
264 EXPECT_TRUE(window_.GetZeroOrOneChildWindows() == NULL);
265}
266
267TEST_F(ReadyPromptWindowTest, Destroy) {
268 // Should delete associated mocks, not invoke on ReadyModeState
269 ready_prompt_window_->DestroyWindow();
270}
271
[email protected]28efc582011-01-24 19:27:32272TEST_F(ReadyPromptWindowButtonTest, ClickEnable) {
[email protected]2bf5f4152010-12-14 20:56:01273 EXPECT_CALL(*state_, AcceptChromeFrame());
[email protected]28efc582011-01-24 19:27:32274 ASSERT_TRUE(ClickOnCaption(L"Enable"));
[email protected]2bf5f4152010-12-14 20:56:01275 RunUntilCloseInfobar();
276}
277
[email protected]28efc582011-01-24 19:27:32278TEST_F(ReadyPromptWindowButtonTest, ClickIgnore) {
[email protected]2bf5f4152010-12-14 20:56:01279 EXPECT_CALL(*state_, PermanentlyDeclineChromeFrame());
[email protected]28efc582011-01-24 19:27:32280 ASSERT_TRUE(ClickOnCaption(L"Ignore"));
[email protected]2bf5f4152010-12-14 20:56:01281 RunUntilCloseInfobar();
282}
283
[email protected]6e58a952011-01-12 19:28:50284// TODO(erikwright): test WebBrowserAdapter
285// TODO(erikwright): an integration test of ReadyMode::Configure with a mock
286// IWebBrowser2?