- add sources.
[platform/framework/web/crosswalk.git] / src / chrome_frame / test / com_message_event_unittest.cc
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 }