| 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 |