Fix Win8 metro startup crash from window switcher button
[chromium-blink-merge.git] / chrome_frame / test / com_message_event_unittest.cc
blobbd8a1ab70b5d99dc97a4b9e68228c1fe2f674c60
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/com_message_event.h"
7 #include <atlbase.h>
8 #include <atlcom.h>
10 #include "testing/gtest/include/gtest/gtest.h"
12 // To allow the unit test read-only access to check protected member variables.
13 class FriendlyComMessageEvent : public ComMessageEvent {
14 public:
15 inline IHTMLEventObj* basic_event() { return basic_event_; }
18 class ATL_NO_VTABLE MockDumbContainer :
19 public CComObjectRoot,
20 public IOleContainer {
21 public:
22 DECLARE_NOT_AGGREGATABLE(MockDumbContainer)
23 BEGIN_COM_MAP(MockDumbContainer)
24 COM_INTERFACE_ENTRY(IParseDisplayName)
25 COM_INTERFACE_ENTRY(IOleContainer)
26 END_COM_MAP()
28 STDMETHOD(ParseDisplayName)(IBindCtx*, LPOLESTR, ULONG*, IMoniker**) {
29 NOTREACHED();
30 return E_NOTIMPL;
32 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown**) {
33 NOTREACHED();
34 return E_NOTIMPL;
36 STDMETHOD(LockContainer)(BOOL) {
37 NOTREACHED();
38 return E_NOTIMPL;
42 TEST(ComMessageEvent, WithDumbContainer) {
43 CComObject<MockDumbContainer>* container_obj = NULL;
44 CComObject<MockDumbContainer>::CreateInstance(&container_obj);
45 base::win::ScopedComPtr<IOleContainer> container(container_obj);
46 EXPECT_FALSE(!container);
48 CComObject<FriendlyComMessageEvent>* event_obj = NULL;
49 CComObject<FriendlyComMessageEvent>::CreateInstance(&event_obj);
50 base::win::ScopedComPtr<IUnknown> event_ref(event_obj);
52 bool result = event_obj->Initialize(container, "hi", "http://www.foo.com/",
53 "message");
54 EXPECT_TRUE(result);
55 EXPECT_TRUE(!event_obj->basic_event());
58 // Mock object to mimic a "smart" container, e.g. IE, that will
59 // be able to return an IHTMLDocument2 and 4, and from which you
60 // can get an IHTMLEventObj implementation. Doubles as a mock
61 // IHTMLEventObj implementation.
62 class ATL_NO_VTABLE MockSmartContainer :
63 public CComObjectRoot,
64 public IOleContainer,
65 public IHTMLDocument2,
66 public IHTMLDocument4,
67 public IHTMLEventObj {
68 public:
69 DECLARE_NOT_AGGREGATABLE(MockSmartContainer)
70 BEGIN_COM_MAP(MockSmartContainer)
71 COM_INTERFACE_ENTRY_IID(IID_IDispatch, IHTMLEventObj)
72 COM_INTERFACE_ENTRY(IParseDisplayName)
73 COM_INTERFACE_ENTRY(IOleContainer)
74 COM_INTERFACE_ENTRY(IHTMLDocument)
75 COM_INTERFACE_ENTRY(IHTMLDocument2)
76 COM_INTERFACE_ENTRY(IHTMLDocument4)
77 COM_INTERFACE_ENTRY(IHTMLEventObj)
78 END_COM_MAP()
80 static const DISPID kDispId = 424242;
81 static const long kResultValue = 42;
83 // Only method we actually implement from IHTMLDocument4, to give
84 // out the mock IHTMLEventObj.
85 STDMETHOD(createEventObject)(VARIANT*, IHTMLEventObj** event_obj) {
86 return GetUnknown()->QueryInterface(event_obj);
89 // Dummy IDispatch implementation for unit testing, to validate
90 // passthrough semantics.
91 STDMETHOD(GetIDsOfNames)(REFIID iid, LPOLESTR* names, UINT num_names,
92 LCID lcid, DISPID* disp_ids) {
93 DCHECK(num_names == 1);
94 disp_ids[0] = kDispId;
95 return S_OK;
98 STDMETHOD(Invoke)(DISPID id, REFIID iid, LCID lcid, WORD flags,
99 DISPPARAMS* disp_params, VARIANT* var_result,
100 EXCEPINFO* excep_info, UINT* arg_error) {
101 var_result->vt = VT_I4;
102 var_result->lVal = kResultValue;
103 return S_OK;
107 // Do-nothing implementation of the rest of the interface methods.
108 // To make this less verbose, define a macro here and undefine it
109 // at the end of the list.
110 #define STDMETHODNOTIMP(method, parameters) \
111 STDMETHOD(method) parameters { \
112 NOTREACHED(); \
113 return E_NOTIMPL; \
116 // IDispatch
117 STDMETHODNOTIMP(GetTypeInfoCount, (UINT*));
118 STDMETHODNOTIMP(GetTypeInfo, (UINT, LCID, ITypeInfo**));
120 // IParseDisplayName
121 STDMETHODNOTIMP(ParseDisplayName, (IBindCtx*, LPOLESTR, ULONG*, IMoniker**));
122 // IOleContainer
123 STDMETHODNOTIMP(EnumObjects, (DWORD, IEnumUnknown**));
124 STDMETHODNOTIMP(LockContainer, (BOOL));
125 // IHTMLDocument
126 STDMETHODNOTIMP(get_Script, (IDispatch**));
127 // IHTMLDocument2
128 STDMETHODNOTIMP(get_all, (IHTMLElementCollection**));
129 STDMETHODNOTIMP(get_body, (IHTMLElement**));
130 STDMETHODNOTIMP(get_activeElement, (IHTMLElement**));
131 STDMETHODNOTIMP(get_images, (IHTMLElementCollection**));
132 STDMETHODNOTIMP(get_applets, (IHTMLElementCollection**));
133 STDMETHODNOTIMP(get_links, (IHTMLElementCollection**));
134 STDMETHODNOTIMP(get_forms, (IHTMLElementCollection**));
135 STDMETHODNOTIMP(get_anchors, (IHTMLElementCollection**));
136 STDMETHODNOTIMP(put_title, (BSTR));
137 STDMETHODNOTIMP(get_title, (BSTR*));
138 STDMETHODNOTIMP(get_scripts, (IHTMLElementCollection**));
139 STDMETHODNOTIMP(put_designMode, (BSTR));
140 STDMETHODNOTIMP(get_designMode, (BSTR*));
141 STDMETHODNOTIMP(get_selection, (IHTMLSelectionObject**));
142 STDMETHODNOTIMP(get_readyState, (BSTR*));
143 STDMETHODNOTIMP(get_frames, (IHTMLFramesCollection2**));
144 STDMETHODNOTIMP(get_embeds, (IHTMLElementCollection**));
145 STDMETHODNOTIMP(get_plugins, (IHTMLElementCollection**));
146 STDMETHODNOTIMP(put_alinkColor, (VARIANT));
147 STDMETHODNOTIMP(get_alinkColor, (VARIANT*));
148 STDMETHODNOTIMP(put_bgColor, (VARIANT));
149 STDMETHODNOTIMP(get_bgColor, (VARIANT*));
150 STDMETHODNOTIMP(put_fgColor, (VARIANT));
151 STDMETHODNOTIMP(get_fgColor, (VARIANT*));
152 STDMETHODNOTIMP(put_linkColor, (VARIANT));
153 STDMETHODNOTIMP(get_linkColor, (VARIANT*));
154 STDMETHODNOTIMP(put_vlinkColor, (VARIANT));
155 STDMETHODNOTIMP(get_vlinkColor, (VARIANT*));
156 STDMETHODNOTIMP(get_referrer, (BSTR*));
157 STDMETHODNOTIMP(get_location, (IHTMLLocation**));
158 STDMETHODNOTIMP(get_lastModified, (BSTR*));
159 STDMETHODNOTIMP(put_URL, (BSTR));
160 STDMETHODNOTIMP(get_URL, (BSTR*));
161 STDMETHODNOTIMP(put_domain, (BSTR));
162 STDMETHODNOTIMP(get_domain, (BSTR*));
163 STDMETHODNOTIMP(put_cookie, (BSTR));
164 STDMETHODNOTIMP(get_cookie, (BSTR*));
165 STDMETHODNOTIMP(put_expando, (VARIANT_BOOL));
166 STDMETHODNOTIMP(get_expando, (VARIANT_BOOL*));
167 STDMETHODNOTIMP(put_charset, (BSTR));
168 STDMETHODNOTIMP(get_charset, (BSTR*));
169 STDMETHODNOTIMP(put_defaultCharset, (BSTR));
170 STDMETHODNOTIMP(get_defaultCharset, (BSTR*));
171 STDMETHODNOTIMP(get_mimeType, (BSTR*));
172 STDMETHODNOTIMP(get_fileSize, (BSTR*));
173 STDMETHODNOTIMP(get_fileCreatedDate, (BSTR*));
174 STDMETHODNOTIMP(get_fileModifiedDate, (BSTR*));
175 STDMETHODNOTIMP(get_fileUpdatedDate, (BSTR*));
176 STDMETHODNOTIMP(get_security, (BSTR*));
177 STDMETHODNOTIMP(get_protocol, (BSTR*));
178 STDMETHODNOTIMP(get_nameProp, (BSTR*));
179 STDMETHODNOTIMP(write, (SAFEARRAY*));
180 STDMETHODNOTIMP(writeln, (SAFEARRAY*));
181 STDMETHODNOTIMP(open, (BSTR, VARIANT, VARIANT, VARIANT, IDispatch**));
182 STDMETHODNOTIMP(close, ());
183 STDMETHODNOTIMP(clear, ());
184 STDMETHODNOTIMP(queryCommandSupported, (BSTR, VARIANT_BOOL*));
185 STDMETHODNOTIMP(queryCommandEnabled, (BSTR, VARIANT_BOOL*));
186 STDMETHODNOTIMP(queryCommandState, (BSTR, VARIANT_BOOL*));
187 STDMETHODNOTIMP(queryCommandIndeterm, (BSTR, VARIANT_BOOL*));
188 STDMETHODNOTIMP(queryCommandText, (BSTR, BSTR*));
189 STDMETHODNOTIMP(queryCommandValue, (BSTR, VARIANT*));
190 STDMETHODNOTIMP(execCommand, (BSTR, VARIANT_BOOL, VARIANT, VARIANT_BOOL*));
191 STDMETHODNOTIMP(execCommandShowHelp, (BSTR, VARIANT_BOOL*));
192 STDMETHODNOTIMP(createElement, (BSTR, IHTMLElement**));
193 STDMETHODNOTIMP(put_onhelp, (VARIANT));
194 STDMETHODNOTIMP(get_onhelp, (VARIANT*));
195 STDMETHODNOTIMP(put_onclick, (VARIANT));
196 STDMETHODNOTIMP(get_onclick, (VARIANT*));
197 STDMETHODNOTIMP(put_ondblclick, (VARIANT));
198 STDMETHODNOTIMP(get_ondblclick, (VARIANT*));
199 STDMETHODNOTIMP(put_onkeyup, (VARIANT));
200 STDMETHODNOTIMP(get_onkeyup, (VARIANT*));
201 STDMETHODNOTIMP(put_onkeydown, (VARIANT));
202 STDMETHODNOTIMP(get_onkeydown, (VARIANT*));
203 STDMETHODNOTIMP(put_onkeypress, (VARIANT));
204 STDMETHODNOTIMP(get_onkeypress, (VARIANT*));
205 STDMETHODNOTIMP(put_onmouseup, (VARIANT));
206 STDMETHODNOTIMP(get_onmouseup, (VARIANT*));
207 STDMETHODNOTIMP(put_onmousedown, (VARIANT));
208 STDMETHODNOTIMP(get_onmousedown, (VARIANT*));
209 STDMETHODNOTIMP(put_onmousemove, (VARIANT));
210 STDMETHODNOTIMP(get_onmousemove, (VARIANT*));
211 STDMETHODNOTIMP(put_onmouseout, (VARIANT));
212 STDMETHODNOTIMP(get_onmouseout, (VARIANT*));
213 STDMETHODNOTIMP(put_onmouseover, (VARIANT));
214 STDMETHODNOTIMP(get_onmouseover, (VARIANT*));
215 STDMETHODNOTIMP(put_onreadystatechange, (VARIANT));
216 STDMETHODNOTIMP(get_onreadystatechange, (VARIANT*));
217 STDMETHODNOTIMP(put_onafterupdate, (VARIANT));
218 STDMETHODNOTIMP(get_onafterupdate, (VARIANT*));
219 STDMETHODNOTIMP(put_onrowexit, (VARIANT));
220 STDMETHODNOTIMP(get_onrowexit, (VARIANT*));
221 STDMETHODNOTIMP(put_onrowenter, (VARIANT));
222 STDMETHODNOTIMP(get_onrowenter, (VARIANT*));
223 STDMETHODNOTIMP(put_ondragstart, (VARIANT));
224 STDMETHODNOTIMP(get_ondragstart, (VARIANT*));
225 STDMETHODNOTIMP(put_onselectstart, (VARIANT));
226 STDMETHODNOTIMP(get_onselectstart, (VARIANT*));
227 STDMETHODNOTIMP(elementFromPoint, (long, long, IHTMLElement**));
228 STDMETHODNOTIMP(get_parentWindow, (IHTMLWindow2**));
229 STDMETHODNOTIMP(get_styleSheets, (IHTMLStyleSheetsCollection**));
230 STDMETHODNOTIMP(put_onbeforeupdate, (VARIANT));
231 STDMETHODNOTIMP(get_onbeforeupdate, (VARIANT*));
232 STDMETHODNOTIMP(put_onerrorupdate, (VARIANT));
233 STDMETHODNOTIMP(get_onerrorupdate, (VARIANT*));
234 STDMETHODNOTIMP(toString, (BSTR*));
235 STDMETHODNOTIMP(createStyleSheet, (BSTR, long, IHTMLStyleSheet**));
236 // IHTMLDocument4
237 STDMETHODNOTIMP(focus, ());
238 STDMETHODNOTIMP(hasFocus, (VARIANT_BOOL*));
239 STDMETHODNOTIMP(put_onselectionchange, (VARIANT));
240 STDMETHODNOTIMP(get_onselectionchange, (VARIANT*));
241 STDMETHODNOTIMP(get_namespaces, (IDispatch**));
242 STDMETHODNOTIMP(createDocumentFromUrl, (BSTR, BSTR, IHTMLDocument2**));
243 STDMETHODNOTIMP(put_media, (BSTR));
244 STDMETHODNOTIMP(get_media, (BSTR*));
245 STDMETHODNOTIMP(fireEvent, (BSTR, VARIANT*, VARIANT_BOOL*));
246 STDMETHODNOTIMP(createRenderStyle, (BSTR, IHTMLRenderStyle**));
247 STDMETHODNOTIMP(put_oncontrolselect, (VARIANT));
248 STDMETHODNOTIMP(get_oncontrolselect, (VARIANT*));
249 STDMETHODNOTIMP(get_URLUnencoded, (BSTR*));
250 // IHTMLEventObj
251 STDMETHODNOTIMP(get_srcElement, (IHTMLElement**))
252 STDMETHODNOTIMP(get_altKey, (VARIANT_BOOL*));
253 STDMETHODNOTIMP(get_ctrlKey, (VARIANT_BOOL*));
254 STDMETHODNOTIMP(get_shiftKey, (VARIANT_BOOL*));
255 STDMETHODNOTIMP(put_returnValue, (VARIANT));
256 STDMETHODNOTIMP(get_returnValue, (VARIANT*));
257 STDMETHODNOTIMP(put_cancelBubble, (VARIANT_BOOL));
258 STDMETHODNOTIMP(get_cancelBubble, (VARIANT_BOOL*));
259 STDMETHODNOTIMP(get_fromElement, (IHTMLElement**));
260 STDMETHODNOTIMP(get_toElement, (IHTMLElement**));
261 STDMETHODNOTIMP(put_keyCode, (long));
262 STDMETHODNOTIMP(get_keyCode, (long*));
263 STDMETHODNOTIMP(get_button, (long*));
264 STDMETHODNOTIMP(get_type, (BSTR*));
265 STDMETHODNOTIMP(get_qualifier, (BSTR*));
266 STDMETHODNOTIMP(get_reason, (long*));
267 STDMETHODNOTIMP(get_x, (long*));
268 STDMETHODNOTIMP(get_y, (long*));
269 STDMETHODNOTIMP(get_clientX, (long*));
270 STDMETHODNOTIMP(get_clientY, (long*));
271 STDMETHODNOTIMP(get_offsetX, (long*));
272 STDMETHODNOTIMP(get_offsetY, (long*));
273 STDMETHODNOTIMP(get_screenX, (long*));
274 STDMETHODNOTIMP(get_screenY, (long*));
275 STDMETHODNOTIMP(get_srcFilter, (IDispatch**));
276 #undef STDMETHODNOTIMP
279 TEST(ComMessageEvent, WithSmartContainer) {
280 CComObject<MockSmartContainer>* container_obj = NULL;
281 CComObject<MockSmartContainer>::CreateInstance(&container_obj);
282 base::win::ScopedComPtr<IOleContainer> container(container_obj);
283 EXPECT_FALSE(!container);
285 CComObject<FriendlyComMessageEvent>* event_obj = NULL;
286 CComObject<FriendlyComMessageEvent>::CreateInstance(&event_obj);
287 base::win::ScopedComPtr<IUnknown> event_ref(event_obj);
289 bool succeeded = event_obj->Initialize(container, "hi",
290 "http://www.foo.com/", "message");
291 EXPECT_TRUE(succeeded);
292 EXPECT_FALSE(!event_obj->basic_event());
294 // Name handled natively by CF's ComMessageEvent.
295 DISPID dispid = -1;
296 LPOLESTR name = L"data";
297 HRESULT hr = event_obj->GetIDsOfNames(IID_IDispatch, &name, 1,
298 LOCALE_USER_DEFAULT, &dispid);
299 EXPECT_HRESULT_SUCCEEDED(hr);
300 EXPECT_EQ(dispid, ComMessageEvent::DISPID_MESSAGE_EVENT_DATA);
302 // Name not handled by CF's ComMessageEvent.
303 dispid = -1;
304 name = L"nothandledatallbyanyone";
305 hr = event_obj->GetIDsOfNames(IID_IDispatch, &name, 1,
306 LOCALE_USER_DEFAULT, &dispid);
307 EXPECT_HRESULT_SUCCEEDED(hr);
308 EXPECT_EQ(dispid, MockSmartContainer::kDispId);
310 // Invoke function handled by ComMessageEvent.
311 CComDispatchDriver dispatcher(event_obj);
312 CComVariant result;
313 hr = dispatcher.GetProperty(ComMessageEvent::DISPID_MESSAGE_EVENT_DATA,
314 &result);
315 EXPECT_HRESULT_SUCCEEDED(hr);
316 EXPECT_EQ(result.vt, VT_BSTR);
317 EXPECT_EQ(wcscmp(result.bstrVal, L"hi"), 0);
319 // And now check passthrough.
320 result.Clear();
321 hr = dispatcher.GetProperty(MockSmartContainer::kDispId, &result);
322 EXPECT_HRESULT_SUCCEEDED(hr);
323 EXPECT_EQ(result.vt, VT_I4);
324 EXPECT_EQ(result.lVal, MockSmartContainer::kResultValue);