1 // Copyright (c) 2011 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.
5 #include "chrome_frame/external_tab.h"
7 // #include "base/synchronization/waitable_event.h"
10 #include "base/bind_helpers.h"
11 #include "base/location.h"
12 #include "base/threading/thread.h"
13 #include "chrome/common/automation_messages.h"
14 #include "chrome_frame/navigation_constraints.h"
15 #include "chrome_frame/test/chrome_frame_test_utils.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gmock_mutant.h"
20 using testing::StrictMock
;
22 using testing::Invoke
;
23 using testing::InvokeWithoutArgs
;
24 using testing::CreateFunctor
;
25 using testing::Return
;
28 using chrome_frame_test::TimedMsgLoop
;
30 struct MockUIDelegate
: public UIDelegate
{
31 MOCK_METHOD2(OnNavigationStateChanged
, void(int flags
,
32 const NavigationInfo
& nav_info
));
33 MOCK_METHOD1(OnUpdateTargetUrl
, void(const std::wstring
& new_target_url
));
34 MOCK_METHOD1(OnLoad
, void(const GURL
& url
));
35 MOCK_METHOD1(OnMoveWindow
, void(const gfx::Rect
& pos
));
36 MOCK_METHOD3(OnMessageFromChromeFrame
, void(const std::string
& message
,
37 const std::string
& origin
, const std::string
& target
));
38 MOCK_METHOD3(OnHandleContextMenu
, void(const ContextMenuModel
& menu_model
,
39 int align_flags
, const MiniContextMenuParams
& params
));
40 MOCK_METHOD1(OnHandleAccelerator
, void(const MSG
& accel_message
));
41 MOCK_METHOD1(OnTabbedOut
, void(bool reverse
));
42 MOCK_METHOD1(OnGoToHistoryOffset
, void(int offset
));
43 MOCK_METHOD3(OnOpenURL
, void(const GURL
& url_to_open
, const GURL
& referrer
,
44 int open_disposition
));
47 struct MockProxy
: public ChromeProxy
{
48 MOCK_METHOD1(RemoveBrowsingData
, void(int remove_mask
));
49 MOCK_METHOD1(SetProxyConfig
, void(const std::string
& json_encoded_settings
));
51 MOCK_METHOD2(CreateTab
, void(ChromeProxyDelegate
* delegate
,
52 const ExternalTabSettings
& settings
));
53 MOCK_METHOD3(ConnectTab
, void(ChromeProxyDelegate
* delegate
, HWND hwnd
,
55 MOCK_METHOD1(BlockTab
, void(uint64 cookie
));
57 MOCK_METHOD4(Tab_PostMessage
, void(int tab
, const std::string
& message
,
58 const std::string
& origin
, const std::string
& target
));
59 MOCK_METHOD1(Tab_Reload
, void(int tab
));
60 MOCK_METHOD1(Tab_Stop
, void(int tab
));
61 MOCK_METHOD1(Tab_SaveAs
, void(int tab
));
62 MOCK_METHOD1(Tab_Print
, void(int tab
));
63 MOCK_METHOD1(Tab_Cut
, void(int tab
));
64 MOCK_METHOD1(Tab_Copy
, void(int tab
));
65 MOCK_METHOD1(Tab_Paste
, void(int tab
));
66 MOCK_METHOD1(Tab_SelectAll
, void(int tab
));
67 MOCK_METHOD5(Tab_Find
, void(int tab
, const string16
& search_string
,
68 FindInPageDirection forward
, FindInPageCase match_case
, bool find_next
));
69 MOCK_METHOD2(Tab_MenuCommand
, void(int tab
, int selected_command
));
71 MOCK_METHOD2(Tab_Zoom
, void(int tab
, content::PageZoom zoom_level
));
72 MOCK_METHOD2(Tab_FontSize
, void(int tab
, AutomationPageFontSize font_size
));
73 MOCK_METHOD3(Tab_SetInitialFocus
, void(int tab
, bool reverse
,
74 bool restore_focus_to_view
));
75 MOCK_METHOD1(Tab_SetParentWindow
, void(int tab
));
76 MOCK_METHOD1(Tab_Resize
, void(int tab
));
77 MOCK_METHOD2(Tab_ProcessAccelerator
, void(int tab
, const MSG
& msg
));
80 MOCK_METHOD1(Tab_OnHostMoved
, void(int tab
));
81 MOCK_METHOD1(Tab_RunUnloadHandlers
, void(int tab
));
82 MOCK_METHOD3(Tab_Navigate
, void(int tab
, const GURL
& url
,
83 const GURL
& referrer
));
84 MOCK_METHOD2(Tab_OverrideEncoding
, void(int tab
, const char* encoding
));
86 MOCK_METHOD1(Init
, void(const ProxyParams
& params
));
87 MOCK_METHOD1(AddDelegate
, int(ChromeProxyDelegate
* delegate
));
88 MOCK_METHOD1(RemoveDelegate
, int(ChromeProxyDelegate
* delegate
));
91 struct MockFactory
: public ChromeProxyFactory
{
92 MOCK_METHOD0(CreateProxy
, ChromeProxy
*());
96 // This class just calls methods of ChromeProxyDelegate but in background thread
97 struct AsyncEventCreator
{
99 explicit AsyncEventCreator(ChromeProxyDelegate
* delegate
)
100 : delegate_(delegate
), ipc_thread_("ipc") {
101 base::Thread::Options
options(MessageLoop::TYPE_IO
, 0);
102 ipc_thread_
.StartWithOptions(options
);
103 ipc_loop_
= ipc_thread_
.message_loop();
106 void Fire_Connected(ChromeProxy
* proxy
, base::TimeDelta delay
) {
107 ipc_loop_
->PostDelayedTask(
109 base::Bind(&ChromeProxyDelegate::Connected
, base::Unretained(delegate_
),
111 delay
.InMilliseconds());
114 void Fire_PeerLost(ChromeProxy
* proxy
,
115 ChromeProxyDelegate::DisconnectReason reason
, base::TimeDelta delay
) {
116 ipc_loop_
->PostDelayedTask(
118 base::Bind(&ChromeProxyDelegate::PeerLost
, base::Unretained(delegate_
),
120 delay
.InMilliseconds());
123 void Fire_Disconnected(base::TimeDelta delay
) {
124 ipc_loop_
->PostDelayedTask(
126 base::Bind(&ChromeProxyDelegate::Disconnected
,
127 base::Unretained(delegate_
)),
128 delay
.InMilliseconds());
131 void Fire_CompletedCreateTab(bool success
, HWND chrome_wnd
, HWND tab_window
,
132 int tab_handle
, int session_id
,
133 base::TimeDelta delay
) {
134 ipc_loop_
->PostDelayedTask(
136 base::Bind(&ChromeProxyDelegate::Completed_CreateTab
,
137 base::Unretained(delegate_
), success
, chrome_wnd
, tab_window
,
138 tab_handle
, session_id
),
139 delay
.InMilliseconds());
143 ChromeProxyDelegate
* delegate_
;
144 base::Thread ipc_thread_
;
145 MessageLoop
* ipc_loop_
;
148 // We may want the same test with 'real' proxy and mock 'proxy traits'.
149 TEST(ExternalTabProxy
, CancelledCreateTab
) {
150 MockUIDelegate ui_delegate
;
151 StrictMock
<MockFactory
> factory
;
152 scoped_ptr
<ExternalTabProxy
> tab(new ExternalTabProxy());
153 AsyncEventCreator
async_events(tab
.get());
154 StrictMock
<MockProxy
>* proxy
= new StrictMock
<MockProxy
>();
156 tab
->set_proxy_factory(&factory
);
158 EXPECT_CALL(factory
, CreateProxy()).WillOnce(Return(proxy
));
159 EXPECT_CALL(*proxy
, Init(_
));
160 EXPECT_CALL(*proxy
, AddDelegate(tab
.get())).WillOnce(DoAll(InvokeWithoutArgs(
161 CreateFunctor(&async_events
, &AsyncEventCreator::Fire_Connected
,
162 proxy
, base::TimeDelta::FromMilliseconds(30))),
165 EXPECT_CALL(*proxy
, CreateTab(tab
.get(), _
))
166 .WillOnce(QUIT_LOOP(loop
));
168 EXPECT_CALL(*proxy
, RemoveDelegate(_
)).WillOnce(DoAll(
169 InvokeWithoutArgs(CreateFunctor(&async_events
,
170 &AsyncEventCreator::Fire_CompletedCreateTab
, false, HWND(0), HWND(0),
171 0, 0, base::TimeDelta::FromMilliseconds(0))),
172 InvokeWithoutArgs(CreateFunctor(&async_events
,
173 &AsyncEventCreator::Fire_Disconnected
,
174 base::TimeDelta::FromMilliseconds(0))),
177 CreateTabParams tab_params
;
178 tab_params
.is_incognito
= true;
179 tab_params
.is_widget_mode
= false;
180 tab_params
.url
= GURL("http://Xanadu.org");
182 tab
->CreateTab(tab_params
, &ui_delegate
);
184 EXPECT_FALSE(loop
.WasTimedOut());