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.
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/gmock/include/gmock/gmock.h"
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"
27 class SetResourceInstance
{
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_
);
41 ~SetResourceInstance() {
42 if (old_res_dll_
!= NULL
) {
43 CHECK_EQ(res_dll_
, ATL::_AtlBaseModule
.SetResourceInstance(old_res_dll_
));
50 }; // class SetResourceInstance
52 class SimpleWindow
: public CWindowImpl
<SimpleWindow
,
56 virtual ~SimpleWindow() {
61 static BOOL CALLBACK
EnumChildProc(HWND hwnd
, LPARAM l_param
) {
62 HWND
* out
= reinterpret_cast<HWND
*>(l_param
);
63 EXPECT_TRUE(out
!= NULL
);
68 EXPECT_TRUE(*out
== NULL
|| ::IsChild(*out
, hwnd
));
76 HWND
GetZeroOrOneChildWindows() {
78 EnumChildWindows(m_hWnd
, EnumChildProc
, reinterpret_cast<LPARAM
>(&child
));
82 BEGIN_MSG_MAP(SimpleWindow
)
84 }; // class SimpleWindow
86 class MockInfobarContentFrame
: public InfobarContent::Frame
{
88 // InfobarContent::Frame implementation
89 MOCK_METHOD0(GetFrameWindow
, HWND(void));
90 MOCK_METHOD0(CloseInfobar
, void(void));
93 class MockReadyModeState
: public ReadyModeState
{
95 // ReadyModeState implementation
96 MOCK_METHOD0(TemporarilyDeclineChromeFrame
, void(void));
97 MOCK_METHOD0(PermanentlyDeclineChromeFrame
, void(void));
98 MOCK_METHOD0(AcceptChromeFrame
, void(void));
99 }; // class MockReadyModeState
101 class MockUrlLauncher
: public UrlLauncher
{
103 // UrlLauncher implementation
104 MOCK_METHOD1(LaunchUrl
, void(const std::wstring
& url
));
105 }; // class MockUrlLauncher
109 class ReadyPromptTest
: public testing::Test
{
111 ReadyPromptTest() : hwnd_(NULL
) {}
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_
));
123 SimpleWindow window_
;
125 MockInfobarContentFrame frame_
;
126 SetResourceInstance set_resource_instance_
;
127 }; // class ReadyPromptTest
129 class ReadyPromptWindowTest
: public ReadyPromptTest
{
132 ReadyPromptTest::SetUp();
134 // owned by ReadyPromptWindow
135 state_
= new MockReadyModeState();
136 url_launcher_
= new MockUrlLauncher();
138 ready_prompt_window_
= ReadyPromptWindow::CreateInstance(
139 &frame_
, state_
, url_launcher_
);
141 ASSERT_TRUE(ready_prompt_window_
!= NULL
);
142 RECT position
= {0, 0, 800, 39};
143 ASSERT_TRUE(ready_prompt_window_
->SetWindowPos(HWND_TOP
, &position
,
148 MockReadyModeState
* state_
;
149 MockUrlLauncher
* url_launcher_
;
150 base::WeakPtr
<ReadyPromptWindow
> ready_prompt_window_
;
151 }; // class ReadyPromptWindowTest
153 class ReadyPromptWindowButtonTest
: public ReadyPromptWindowTest
{
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());
161 ReadyPromptWindowTest::TearDown();
165 struct ClickOnCaptionData
{
166 const wchar_t* target_caption
;
168 }; // struct ClickOnCaptionData
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
);
174 ClickOnCaptionData
* data
= reinterpret_cast<ClickOnCaptionData
*>(l_param
);
175 EXPECT_TRUE(data
->target_caption
!= NULL
);
177 if (data
->target_caption
== NULL
)
180 if (wcsnlen(data
->target_caption
, buffer_length
+ 1) == buffer_length
+ 1)
183 if (::GetWindowText(hwnd
, window_caption
, buffer_length
) ==
184 static_cast<int>(buffer_length
)) {
188 if (wcscmp(data
->target_caption
, window_caption
) == 0) {
189 EXPECT_FALSE(data
->found
);
192 EXPECT_TRUE(::GetClientRect(hwnd
, client_rect
));
194 CPoint
center_point(client_rect
.CenterPoint());
195 LPARAM coordinates
= (center_point
.y
<< 16) | center_point
.x
;
197 ::PostMessage(hwnd
, WM_LBUTTONDOWN
, 0, coordinates
);
198 ::PostMessage(hwnd
, WM_LBUTTONUP
, 0, coordinates
);
206 bool ClickOnCaption(const std::wstring
& caption
) {
207 ClickOnCaptionData data
= {caption
.c_str(), false};
209 ::EnumChildWindows(hwnd_
, ClickOnCaptionProc
,
210 reinterpret_cast<LPARAM
>(&data
));
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)));
220 chrome_frame_test::TimedMsgLoop message_loop_
;
221 }; // class ReadyPromptWindowButtonTest
223 TEST_F(ReadyPromptTest
, ReadyPromptContentTest
) {
224 // owned by ReadyPromptContent
225 MockReadyModeState
* state
= new MockReadyModeState();
226 MockUrlLauncher
* url_launcher
= new MockUrlLauncher();
228 scoped_ptr
<ReadyPromptContent
> content_(new ReadyPromptContent(state
,
231 content_
->InstallInFrame(&frame_
);
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
));
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
);
247 child_hwnd
= window_
.GetZeroOrOneChildWindows();
248 EXPECT_TRUE(child_hwnd
!= NULL
);
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
));
259 // Being visible doesn't change the desired height
260 EXPECT_EQ(desired_height
, content_
->GetDesiredSize(400, 0));
264 EXPECT_TRUE(window_
.GetZeroOrOneChildWindows() == NULL
);
267 TEST_F(ReadyPromptWindowTest
, Destroy
) {
268 // Should delete associated mocks, not invoke on ReadyModeState
269 ready_prompt_window_
->DestroyWindow();
272 TEST_F(ReadyPromptWindowButtonTest
, ClickEnable
) {
273 EXPECT_CALL(*state_
, AcceptChromeFrame());
274 ASSERT_TRUE(ClickOnCaption(L
"Enable"));
275 RunUntilCloseInfobar();
278 TEST_F(ReadyPromptWindowButtonTest
, ClickIgnore
) {
279 EXPECT_CALL(*state_
, PermanentlyDeclineChromeFrame());
280 ASSERT_TRUE(ClickOnCaption(L
"Ignore"));
281 RunUntilCloseInfobar();
284 // TODO(erikwright): test WebBrowserAdapter
285 // TODO(erikwright): an integration test of ReadyMode::Configure with a mock