mshtml: Add IHTMLXMLHttpRequest:open() method implementation.
[wine.git] / dlls / mshtml / tests / xmlhttprequest.c
blob240f6d30c02e239e7c9293f41e50d39eefe16b6c
1 /*
2 * Copyright 2015 Zhenbo Li
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include <wine/test.h>
22 #include <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "ole2.h"
27 #include "mshtml.h"
29 static BSTR a2bstr(const char *str)
31 BSTR ret;
32 int len;
34 len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
35 ret = SysAllocStringLen(NULL, len);
36 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
38 return ret;
41 static int strcmp_wa(LPCWSTR strw, const char *stra)
43 CHAR buf[512];
44 WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
45 return lstrcmpA(stra, buf);
48 #define DEFINE_EXPECT(func) \
49 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
51 #define SET_EXPECT(func) \
52 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
54 #define CHECK_EXPECT2(func) \
55 do { \
56 trace(#func "\n"); \
57 ok(expect_ ##func, "unexpected call " #func "\n"); \
58 called_ ## func = TRUE; \
59 }while(0)
61 #define CHECK_EXPECT(func) \
62 do { \
63 CHECK_EXPECT2(func); \
64 expect_ ## func = FALSE; \
65 }while(0)
67 #define CHECK_CALLED(func) \
68 do { \
69 ok(called_ ## func, "expected " #func "\n"); \
70 expect_ ## func = called_ ## func = FALSE; \
71 }while(0)
73 static IHTMLXMLHttpRequest *xhr = NULL;
75 DEFINE_EXPECT(xmlhttprequest_onreadystatechange_opened);
76 DEFINE_EXPECT(xmlhttprequest_onreadystatechange_headers_received);
77 DEFINE_EXPECT(xmlhttprequest_onreadystatechange_loading);
78 DEFINE_EXPECT(xmlhttprequest_onreadystatechange_done);
80 #define test_disp(u,id) _test_disp(__LINE__,u,id)
81 static void _test_disp(unsigned line, IUnknown *unk, const IID *diid)
83 IDispatchEx *dispex;
84 ITypeInfo *typeinfo;
85 UINT ticnt;
86 HRESULT hres;
88 hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
89 ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
90 if(FAILED(hres))
91 return;
93 ticnt = 0xdeadbeef;
94 hres = IDispatchEx_GetTypeInfoCount(dispex, &ticnt);
95 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfoCount failed: %08x\n", hres);
96 ok_(__FILE__,line) (ticnt == 1, "ticnt=%u\n", ticnt);
98 hres = IDispatchEx_GetTypeInfo(dispex, 0, 0, &typeinfo);
99 ok_(__FILE__,line) (hres == S_OK, "GetTypeInfo failed: %08x\n", hres);
101 if(SUCCEEDED(hres)) {
102 TYPEATTR *type_attr;
104 hres = ITypeInfo_GetTypeAttr(typeinfo, &type_attr);
105 ok_(__FILE__,line) (hres == S_OK, "GetTypeAttr failed: %08x\n", hres);
106 ok_(__FILE__,line) (IsEqualGUID(&type_attr->guid, diid), "unexpected guid %s\n",
107 wine_dbgstr_guid(&type_attr->guid));
109 ITypeInfo_ReleaseTypeAttr(typeinfo, type_attr);
110 ITypeInfo_Release(typeinfo);
113 IDispatchEx_Release(dispex);
116 #define test_event_args(a,b,c,d,e,f,g) _test_event_args(__LINE__,a,b,c,d,e,f,g)
117 static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD wFlags, DISPPARAMS *pdp,
118 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
120 ok_(__FILE__,line) (id == DISPID_VALUE, "id = %d\n", id);
121 ok_(__FILE__,line) (wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
122 ok_(__FILE__,line) (pdp != NULL, "pdp == NULL\n");
123 ok_(__FILE__,line) (pdp->cArgs == 1, "pdp->cArgs = %d\n", pdp->cArgs);
124 ok_(__FILE__,line) (pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
125 ok_(__FILE__,line) (pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n",
126 pdp->rgdispidNamedArgs[0]);
127 ok_(__FILE__,line) (V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
128 ok_(__FILE__,line) (pvarRes != NULL, "pvarRes == NULL\n");
129 ok_(__FILE__,line) (pei != NULL, "pei == NULL");
130 ok_(__FILE__,line) (!pspCaller, "pspCaller != NULL\n");
132 if(dispiid)
133 _test_disp(line, (IUnknown*)V_DISPATCH(pdp->rgvarg), dispiid);
136 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
138 *ppv = NULL;
140 if(IsEqualGUID(riid, &IID_IUnknown)
141 || IsEqualGUID(riid, &IID_IDispatch)
142 || IsEqualGUID(riid, &IID_IDispatchEx))
143 *ppv = iface;
144 else {
145 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
146 return E_NOINTERFACE;
149 return S_OK;
152 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
154 return 2;
157 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
159 return 1;
162 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
164 ok(0, "unexpected call\n");
165 return E_NOTIMPL;
168 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
169 LCID lcid, ITypeInfo **ppTInfo)
171 ok(0, "unexpected call\n");
172 return E_NOTIMPL;
175 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
176 LPOLESTR *rgszNames, UINT cNames,
177 LCID lcid, DISPID *rgDispId)
179 ok(0, "unexpected call\n");
180 return E_NOTIMPL;
183 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
184 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
185 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
187 ok(0, "unexpected call\n");
188 return E_NOTIMPL;
191 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
193 ok(0, "unexpected call\n");
194 return E_NOTIMPL;
197 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
199 ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
200 return E_NOTIMPL;
203 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
205 ok(0, "unexpected call\n");
206 return E_NOTIMPL;
209 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
211 ok(0, "unexpected call\n");
212 return E_NOTIMPL;
215 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
217 ok(0, "unexpected call\n");
218 return E_NOTIMPL;
221 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
223 ok(0, "unexpected call\n");
224 return E_NOTIMPL;
227 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
229 ok(0, "unexpected call\n");
230 return E_NOTIMPL;
233 static HRESULT WINAPI xmlhttprequest_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
234 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
236 LONG val;
237 HRESULT hres;
239 test_event_args(&DIID_DispHTMLXMLHttpRequest, id, wFlags, pdp, pvarRes, pei, pspCaller);
241 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
242 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
244 switch(val) {
245 case 1:
246 CHECK_EXPECT(xmlhttprequest_onreadystatechange_opened);
247 break;
248 case 2:
249 CHECK_EXPECT(xmlhttprequest_onreadystatechange_headers_received);
250 break;
251 case 3:
252 CHECK_EXPECT(xmlhttprequest_onreadystatechange_loading);
253 break;
254 case 4:
255 CHECK_EXPECT(xmlhttprequest_onreadystatechange_done);
256 break;
257 default:
258 ok(0, "unexpected readyState: %d\n", val);
260 return S_OK;
263 static IDispatchExVtbl xmlhttprequest_onreadystatechangeFuncVtbl = {
264 DispatchEx_QueryInterface,
265 DispatchEx_AddRef,
266 DispatchEx_Release,
267 DispatchEx_GetTypeInfoCount,
268 DispatchEx_GetTypeInfo,
269 DispatchEx_GetIDsOfNames,
270 DispatchEx_Invoke,
271 DispatchEx_GetDispID,
272 xmlhttprequest_onreadystatechange,
273 DispatchEx_DeleteMemberByName,
274 DispatchEx_DeleteMemberByDispID,
275 DispatchEx_GetMemberProperties,
276 DispatchEx_GetMemberName,
277 DispatchEx_GetNextDispID,
278 DispatchEx_GetNameSpaceParent
280 static IDispatchEx xmlhttprequest_onreadystatechange_obj = { &xmlhttprequest_onreadystatechangeFuncVtbl };
282 static void pump_msgs(BOOL *b)
284 MSG msg;
286 if(b) {
287 while(!*b && GetMessageW(&msg, NULL, 0, 0)) {
288 TranslateMessage(&msg);
289 DispatchMessageW(&msg);
291 }else {
292 while(PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
293 TranslateMessage(&msg);
294 DispatchMessageW(&msg);
299 static const char EXPECT_RESPONSE_TEXT[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<a>TEST</a>\n";
301 static void create_xmlhttprequest(IHTMLDocument2 *doc)
303 IHTMLWindow2 *window;
304 IHTMLWindow5 *window5;
305 VARIANT var;
306 IHTMLXMLHttpRequestFactory *factory;
307 HRESULT hres;
309 hres = IHTMLDocument2_get_parentWindow(doc, &window);
310 ok(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
311 ok(window != NULL, "window == NULL\n");
313 hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow5, (void**)&window5);
314 IHTMLWindow2_Release(window);
315 if(FAILED(hres)) {
316 win_skip("IHTMLWindow5 not supported\n");
317 return;
320 hres = IHTMLWindow5_get_XMLHttpRequest(window5, &var);
321 IHTMLWindow5_Release(window5);
322 ok(hres == S_OK, "get_XMLHttpRequest failed: %08x\n", hres);
323 ok(V_VT(&var) == VT_DISPATCH, "V_VT(&var) is %08x, expected VT_DISPATCH\n", V_VT(&var));
325 hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IHTMLXMLHttpRequestFactory, (void**)&factory);
326 VariantClear(&var);
327 ok(hres == S_OK, "QueryInterface(IID_IHTMLXMLHttpRequestFactory) failed: %08x\n", hres);
328 ok(factory != NULL, "factory == NULL\n");
330 hres = IHTMLXMLHttpRequestFactory_create(factory, &xhr);
331 IHTMLXMLHttpRequestFactory_Release(factory);
332 ok(hres == S_OK, "create failed: %08x\n", hres);
333 ok(xhr != NULL, "xhr == NULL\n");
336 static void test_sync_xhr(IHTMLDocument2 *doc, const char *xml_url)
338 VARIANT vbool, vempty, var;
339 BSTR method, url;
340 BSTR text;
341 LONG val;
342 HRESULT hres;
344 create_xmlhttprequest(doc);
345 if(!xhr)
346 return;
348 V_VT(&var) = VT_EMPTY;
349 hres = IHTMLXMLHttpRequest_get_onreadystatechange(xhr, &var);
350 ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
351 ok(V_VT(&var) == VT_NULL, "V_VT(onreadystatechange) = %d\n", V_VT(&var));
353 V_VT(&var) = VT_DISPATCH;
354 V_DISPATCH(&var) = (IDispatch*)&xmlhttprequest_onreadystatechange_obj;
355 hres = IHTMLXMLHttpRequest_put_onreadystatechange(xhr, var);
356 ok(hres == S_OK, "put_onreadystatechange failed: %08x\n", hres);
358 V_VT(&var) = VT_EMPTY;
359 hres = IHTMLXMLHttpRequest_get_onreadystatechange(xhr, &var);
360 ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
361 ok(V_VT(&var) == VT_DISPATCH, "V_VT(onreadystatechange) = %d\n", V_VT(&var));
362 ok(V_DISPATCH(&var) == (IDispatch*)&xmlhttprequest_onreadystatechange_obj, "unexpected onreadystatechange value\n");
364 hres = IHTMLXMLHttpRequest_get_readyState(xhr, NULL);
365 todo_wine ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres);
367 val = 0xdeadbeef;
368 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
369 todo_wine ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
370 todo_wine ok(val == 0, "Expect UNSENT, got %d\n", val);
372 hres = IHTMLXMLHttpRequest_get_status(xhr, NULL);
373 todo_wine ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres);
375 val = 0xdeadbeef;
376 hres = IHTMLXMLHttpRequest_get_status(xhr, &val);
377 todo_wine ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
378 todo_wine ok(val == 0, "Expect 0, got %d\n", val);
380 hres = IHTMLXMLHttpRequest_get_statusText(xhr, NULL);
381 todo_wine ok(hres == E_POINTER, "Expect E_POINTER, got %08x\n", hres);
383 hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text);
384 todo_wine ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
385 todo_wine ok(text == NULL, "Expect NULL, got %p\n", text);
387 method = a2bstr("GET");
388 url = a2bstr(xml_url);
389 V_VT(&vbool) = VT_BOOL;
390 V_BOOL(&vbool) = VARIANT_FALSE;
391 V_VT(&vempty) = VT_EMPTY;
393 SET_EXPECT(xmlhttprequest_onreadystatechange_opened);
394 hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty);
395 todo_wine ok(hres == S_OK, "open failed: %08x\n", hres); /* Gecko 30+ only supports async */
396 todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened);
398 SysFreeString(method);
399 SysFreeString(url);
401 if(FAILED(hres)) {
402 IHTMLXMLHttpRequest_Release(xhr);
403 xhr = NULL;
404 return;
407 val = 0xdeadbeef;
408 hres = IHTMLXMLHttpRequest_get_status(xhr, &val);
409 ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
410 ok(val == 0, "Expect 0, got %d\n", val);
412 hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text);
413 ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
414 ok(text == NULL, "Expect NULL, got %p\n", text);
416 val = 0xdeadbeef;
417 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
418 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
419 ok(val == 1, "Expect OPENED, got %d\n", val);
421 SET_EXPECT(xmlhttprequest_onreadystatechange_opened);
422 SET_EXPECT(xmlhttprequest_onreadystatechange_headers_received);
423 SET_EXPECT(xmlhttprequest_onreadystatechange_loading);
424 SET_EXPECT(xmlhttprequest_onreadystatechange_done);
425 hres = IHTMLXMLHttpRequest_send(xhr, vempty);
426 ok(hres == S_OK, "send failed: %08x\n", hres);
427 CHECK_CALLED(xmlhttprequest_onreadystatechange_opened);
428 CHECK_CALLED(xmlhttprequest_onreadystatechange_headers_received);
429 CHECK_CALLED(xmlhttprequest_onreadystatechange_loading);
430 CHECK_CALLED(xmlhttprequest_onreadystatechange_done);
432 val = 0xdeadbeef;
433 hres = IHTMLXMLHttpRequest_get_status(xhr, &val);
434 ok(hres == S_OK, "get_status failed: %08x\n", hres);
435 ok(val == 200, "Expect 200, got %d\n", val);
437 hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text);
438 ok(hres == S_OK, "get_statusText failed: %08x\n", hres);
439 ok(text != NULL, "text == NULL\n");
440 ok(!strcmp_wa(text, "OK"),
441 "Expected \"OK\", got %s\n", wine_dbgstr_w(text));
442 SysFreeString(text);
444 val = 0xdeadbeef;
445 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
446 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
447 ok(val == 4, "Expect DONE, got %d\n", val);
449 hres = IHTMLXMLHttpRequest_get_responseText(xhr, &text);
450 ok(hres == S_OK, "get_responseText failed: %08x\n", hres);
451 ok(text != NULL, "test == NULL\n");
452 ok(!strcmp_wa(text, EXPECT_RESPONSE_TEXT), "expect %s, got %s\n",
453 EXPECT_RESPONSE_TEXT, wine_dbgstr_w(text));
454 SysFreeString(text);
456 IHTMLXMLHttpRequest_Release(xhr);
457 xhr = NULL;
460 static void test_async_xhr(IHTMLDocument2 *doc, const char *xml_url)
462 VARIANT vbool, vempty, var;
463 BSTR method, url;
464 BSTR text;
465 LONG val;
466 HRESULT hres;
468 create_xmlhttprequest(doc);
469 if(!xhr)
470 return;
472 V_VT(&var) = VT_DISPATCH;
473 V_DISPATCH(&var) = (IDispatch*)&xmlhttprequest_onreadystatechange_obj;
474 hres = IHTMLXMLHttpRequest_put_onreadystatechange(xhr, var);
475 ok(hres == S_OK, "put_onreadystatechange failed: %08x\n", hres);
477 V_VT(&var) = VT_EMPTY;
478 hres = IHTMLXMLHttpRequest_get_onreadystatechange(xhr, &var);
479 ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
480 ok(V_VT(&var) == VT_DISPATCH, "V_VT(onreadystatechange) = %d\n", V_VT(&var));
481 ok(V_DISPATCH(&var) == (IDispatch*)&xmlhttprequest_onreadystatechange_obj, "unexpected onreadystatechange value\n");
483 val = 0xdeadbeef;
484 hres = IHTMLXMLHttpRequest_get_status(xhr, &val);
485 todo_wine ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
486 todo_wine ok(val == 0, "Expect 0, got %d\n", val);
488 text = (BSTR)0xdeadbeef;
489 hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text);
490 todo_wine ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
491 todo_wine ok(text == NULL, "Expect NULL, got %p\n", text);
493 val = 0xdeadbeef;
494 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
495 todo_wine ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
496 todo_wine ok(val == 0, "Expect UNSENT, got %d\n", val);
498 method = a2bstr("GET");
499 url = a2bstr(xml_url);
500 V_VT(&vbool) = VT_BOOL;
501 V_BOOL(&vbool) = VARIANT_TRUE;
502 V_VT(&vempty) = VT_EMPTY;
504 SET_EXPECT(xmlhttprequest_onreadystatechange_opened);
505 hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty);
506 ok(hres == S_OK, "open failed: %08x\n", hres);
507 todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened);
509 SysFreeString(method);
510 SysFreeString(url);
512 if(FAILED(hres)) {
513 IHTMLXMLHttpRequest_Release(xhr);
514 xhr = NULL;
515 return;
518 val = 0xdeadbeef;
519 hres = IHTMLXMLHttpRequest_get_status(xhr, &val);
520 todo_wine ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
521 todo_wine ok(val == 0, "Expect 0, got %d\n", val);
523 hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text);
524 todo_wine ok(hres == E_FAIL, "Expect E_FAIL, got: %08x\n", hres);
525 todo_wine ok(text == NULL, "Expect NULL, got %p\n", text);
527 val = 0xdeadbeef;
528 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
529 todo_wine ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
530 todo_wine ok(val == 1, "Expect OPENED, got %d\n", val);
532 SET_EXPECT(xmlhttprequest_onreadystatechange_opened);
533 SET_EXPECT(xmlhttprequest_onreadystatechange_headers_received);
534 SET_EXPECT(xmlhttprequest_onreadystatechange_loading);
535 SET_EXPECT(xmlhttprequest_onreadystatechange_done);
536 hres = IHTMLXMLHttpRequest_send(xhr, vempty);
538 todo_wine ok(hres == S_OK, "send failed: %08x\n", hres);
539 if(SUCCEEDED(hres))
540 pump_msgs(&called_xmlhttprequest_onreadystatechange_done);
541 todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened);
542 todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_headers_received);
543 todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_loading);
544 todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_done);
546 if(FAILED(hres)) {
547 IHTMLXMLHttpRequest_Release(xhr);
548 xhr = NULL;
549 return;
552 val = 0xdeadbeef;
553 hres = IHTMLXMLHttpRequest_get_status(xhr, &val);
554 ok(hres == S_OK, "get_status failed: %08x\n", hres);
555 todo_wine ok(val == 200, "Expect 200, got %d\n", val);
557 hres = IHTMLXMLHttpRequest_get_statusText(xhr, &text);
558 ok(hres == S_OK, "get_statusText failed: %08x\n", hres);
559 todo_wine ok(text != NULL, "text == NULL\n");
560 todo_wine ok(!strcmp_wa(text, "OK"),
561 "Expected \"OK\", got %s\n", wine_dbgstr_w(text));
562 SysFreeString(text);
564 val = 0xdeadbeef;
565 hres = IHTMLXMLHttpRequest_get_readyState(xhr, &val);
566 ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
567 ok(val == 4, "Expect DONE, got %d\n", val);
569 hres = IHTMLXMLHttpRequest_get_responseText(xhr, &text);
570 ok(hres == S_OK, "get_responseText failed: %08x\n", hres);
571 ok(text != NULL, "test == NULL\n");
572 ok(!strcmp_wa(text, EXPECT_RESPONSE_TEXT), "expect %s, got %s\n",
573 EXPECT_RESPONSE_TEXT, wine_dbgstr_w(text));
574 SysFreeString(text);
576 IHTMLXMLHttpRequest_Release(xhr);
577 xhr = NULL;
580 static IHTMLDocument2 *create_doc_from_url(const char *start_url)
582 BSTR url;
583 IBindCtx *bc;
584 IMoniker *url_mon;
585 IPersistMoniker *persist_mon;
586 IHTMLDocument2 *doc;
587 HRESULT hres;
589 hres = CreateBindCtx(0, &bc);
590 ok(hres == S_OK, "CreateBindCtx failed: 0x%08x\n", hres);
592 url = a2bstr(start_url);
593 hres = CreateURLMoniker(NULL, url, &url_mon);
594 ok(hres == S_OK, "CreateURLMoniker failed: 0x%08x\n", hres);
596 hres = CoCreateInstance(&CLSID_HTMLDocument, NULL,
597 CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, &IID_IHTMLDocument2,
598 (void**)&doc);
599 ok(hres == S_OK, "CoCreateInstance failed: 0x%08x\n", hres);
601 hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker,
602 (void**)&persist_mon);
603 ok(hres == S_OK, "IHTMLDocument2_QueryInterface failed: 0x%08x\n", hres);
605 hres = IPersistMoniker_Load(persist_mon, FALSE, url_mon, bc,
606 STGM_SHARE_EXCLUSIVE | STGM_READWRITE);
607 ok(hres == S_OK, "IPersistMoniker_Load failed: 0x%08x\n", hres);
609 IPersistMoniker_Release(persist_mon);
610 IMoniker_Release(url_mon);
611 IBindCtx_Release(bc);
612 SysFreeString(url);
614 return doc;
617 START_TEST(xmlhttprequest)
619 IHTMLDocument2 *doc;
620 static const char start_url[] = "http://test.winehq.org/tests/hello.html";
621 static const char xml_url[] = "http://test.winehq.org/tests/xmltest.xml";
623 CoInitialize(NULL);
625 doc = create_doc_from_url(start_url);
626 if(doc) {
627 test_sync_xhr(doc, xml_url);
628 test_async_xhr(doc, xml_url);
629 IHTMLDocument2_Release(doc);
632 CoUninitialize();