OLD | NEW |
| (Empty) |
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 <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/memory/scoped_ptr.h" | |
15 #include "base/win/registry.h" | |
16 #include "chrome_frame/infobars/infobar_content.h" | |
17 #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" | |
21 #include "chrome_frame/ready_mode/internal/url_launcher.h" | |
22 #include "chrome_frame/simple_resource_loader.h" | |
23 #include "chrome_frame/test/chrome_frame_test_utils.h" | |
24 | |
25 namespace { | |
26 | |
27 class 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 | |
52 class 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 | |
86 class 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 | |
93 class 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 | |
101 class MockUrlLauncher : public UrlLauncher { | |
102 public: | |
103 // UrlLauncher implementation | |
104 MOCK_METHOD1(LaunchUrl, void(const std::wstring& url)); | |
105 }; // class MockUrlLauncher | |
106 | |
107 } // namespace | |
108 | |
109 class ReadyPromptTest : public testing::Test { | |
110 public: | |
111 ReadyPromptTest() : hwnd_(NULL) {} | |
112 | |
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 | |
129 class ReadyPromptWindowTest : public ReadyPromptTest { | |
130 public: | |
131 void SetUp() { | |
132 ReadyPromptTest::SetUp(); | |
133 | |
134 // owned by ReadyPromptWindow | |
135 state_ = new MockReadyModeState(); | |
136 url_launcher_ = new MockUrlLauncher(); | |
137 | |
138 ready_prompt_window_ = ReadyPromptWindow::CreateInstance( | |
139 &frame_, state_, url_launcher_); | |
140 | |
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_; | |
149 MockUrlLauncher* url_launcher_; | |
150 base::WeakPtr<ReadyPromptWindow> ready_prompt_window_; | |
151 }; // class ReadyPromptWindowTest | |
152 | |
153 class 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_)); | |
216 ASSERT_NO_FATAL_FAILURE(message_loop_.RunFor( | |
217 base::TimeDelta::FromSeconds(5))); | |
218 } | |
219 | |
220 chrome_frame_test::TimedMsgLoop message_loop_; | |
221 }; // class ReadyPromptWindowButtonTest | |
222 | |
223 TEST_F(ReadyPromptTest, ReadyPromptContentTest) { | |
224 // owned by ReadyPromptContent | |
225 MockReadyModeState* state = new MockReadyModeState(); | |
226 MockUrlLauncher* url_launcher = new MockUrlLauncher(); | |
227 | |
228 scoped_ptr<ReadyPromptContent> content_(new ReadyPromptContent(state, | |
229 url_launcher)); | |
230 | |
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 | |
267 TEST_F(ReadyPromptWindowTest, Destroy) { | |
268 // Should delete associated mocks, not invoke on ReadyModeState | |
269 ready_prompt_window_->DestroyWindow(); | |
270 } | |
271 | |
272 TEST_F(ReadyPromptWindowButtonTest, ClickEnable) { | |
273 EXPECT_CALL(*state_, AcceptChromeFrame()); | |
274 ASSERT_TRUE(ClickOnCaption(L"Enable")); | |
275 RunUntilCloseInfobar(); | |
276 } | |
277 | |
278 TEST_F(ReadyPromptWindowButtonTest, ClickIgnore) { | |
279 EXPECT_CALL(*state_, PermanentlyDeclineChromeFrame()); | |
280 ASSERT_TRUE(ClickOnCaption(L"Ignore")); | |
281 RunUntilCloseInfobar(); | |
282 } | |
283 | |
284 // TODO(erikwright): test WebBrowserAdapter | |
285 // TODO(erikwright): an integration test of ReadyMode::Configure with a mock | |
286 // IWebBrowser2? | |
OLD | NEW |