OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome_frame/com_message_event.h" | |
6 | |
7 #include <atlbase.h> | |
8 #include <atlcom.h> | |
9 | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
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_; } | |
16 }; | |
17 | |
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() | |
27 | |
28 STDMETHOD(ParseDisplayName)(IBindCtx*, LPOLESTR, ULONG*, IMoniker**) { | |
29 NOTREACHED(); | |
30 return E_NOTIMPL; | |
31 } | |
32 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown**) { | |
33 NOTREACHED(); | |
34 return E_NOTIMPL; | |
35 } | |
36 STDMETHOD(LockContainer)(BOOL) { | |
37 NOTREACHED(); | |
38 return E_NOTIMPL; | |
39 } | |
40 }; | |
41 | |
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); | |
47 | |
48 CComObject<FriendlyComMessageEvent>* event_obj = NULL; | |
49 CComObject<FriendlyComMessageEvent>::CreateInstance(&event_obj); | |
50 base::win::ScopedComPtr<IUnknown> event_ref(event_obj); | |
51 | |
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()); | |
56 } | |
57 | |
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() | |
79 | |
80 static const DISPID kDispId = 424242; | |
81 static const long kResultValue = 42; | |
82 | |
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); | |
87 } | |
88 | |
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; | |
96 } | |
97 | |
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; | |
104 } | |
105 | |
106 | |
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; \ | |
114 } | |
115 | |
116 // IDispatch | |
117 STDMETHODNOTIMP(GetTypeInfoCount, (UINT*)); | |
118 STDMETHODNOTIMP(GetTypeInfo, (UINT, LCID, ITypeInfo**)); | |
119 | |
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 | |
277 }; | |
278 | |
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); | |
284 | |
285 CComObject<FriendlyComMessageEvent>* event_obj = NULL; | |
286 CComObject<FriendlyComMessageEvent>::CreateInstance(&event_obj); | |
287 base::win::ScopedComPtr<IUnknown> event_ref(event_obj); | |
288 | |
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()); | |
293 | |
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); | |
301 | |
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); | |
309 | |
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); | |
318 | |
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); | |
325 } | |
OLD | NEW |