4 * Copyright 2010 Thomas Mullaly
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 * IUri testing framework goals:
25 * - invalid args (IUri, uri string)
26 * - Test parsing for components when no canonicalization occurs
27 * - Test parsing for components when canonicalization occurs.
31 #include <wine/test.h>
42 #define URI_STR_PROPERTY_COUNT Uri_PROPERTY_STRING_LAST+1
43 #define URI_DWORD_PROPERTY_COUNT (Uri_PROPERTY_DWORD_LAST - Uri_PROPERTY_DWORD_START)+1
45 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
47 static const WCHAR http_urlW[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q',
48 '.','o','r','g','/',0};
50 typedef struct _uri_create_flag_test {
53 } uri_create_flag_test;
55 static const uri_create_flag_test invalid_flag_tests[] = {
56 /* Set of invalid flag combinations to test for. */
57 {Uri_CREATE_DECODE_EXTRA_INFO | Uri_CREATE_NO_DECODE_EXTRA_INFO, E_INVALIDARG},
58 {Uri_CREATE_CANONICALIZE | Uri_CREATE_NO_CANONICALIZE, E_INVALIDARG},
59 {Uri_CREATE_CRACK_UNKNOWN_SCHEMES | Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES, E_INVALIDARG},
60 {Uri_CREATE_PRE_PROCESS_HTML_URI | Uri_CREATE_NO_PRE_PROCESS_HTML_URI, E_INVALIDARG},
61 {Uri_CREATE_IE_SETTINGS | Uri_CREATE_NO_IE_SETTINGS, E_INVALIDARG}
64 typedef struct _uri_str_property {
70 typedef struct _uri_dword_property {
76 typedef struct _uri_properties {
79 HRESULT create_expected;
82 uri_str_property str_props[URI_STR_PROPERTY_COUNT];
83 uri_dword_property dword_props[URI_DWORD_PROPERTY_COUNT];
86 static const uri_properties uri_tests[] = {
87 { "http://www.winehq.org/tests/../tests/../..", 0, S_OK, FALSE,
89 {"http://www.winehq.org/",S_OK,TRUE}, /* ABSOLUTE_URI */
90 {"www.winehq.org",S_OK,TRUE}, /* AUTHORITY */
91 {"http://www.winehq.org/",S_OK,TRUE}, /* DISPLAY_URI */
92 {"winehq.org",S_OK,TRUE}, /* DOMAIN */
93 {"",S_FALSE,TRUE}, /* EXTENSION */
94 {"",S_FALSE,TRUE}, /* FRAGMENT */
95 {"www.winehq.org",S_OK,TRUE}, /* HOST */
96 {"",S_FALSE,TRUE}, /* PASSWORD */
97 {"/",S_OK,TRUE}, /* PATH */
98 {"/",S_OK,TRUE}, /* PATH_AND_QUERY */
99 {"",S_FALSE,TRUE}, /* QUERY */
100 {"http://www.winehq.org/tests/../tests/../..",S_OK,TRUE}, /* RAW_URI */
101 {"http",S_OK,TRUE}, /* SCHEME_NAME */
102 {"",S_FALSE,TRUE}, /* USER_INFO */
103 {"",S_FALSE,TRUE} /* USER_NAME */
106 {Uri_HOST_DNS,S_OK,TRUE}, /* HOST_TYPE */
107 {80,S_OK,TRUE}, /* PORT */
108 {URL_SCHEME_HTTP,S_OK,TRUE}, /* SCHEME */
109 {URLZONE_INVALID,E_NOTIMPL,FALSE} /* ZONE */
112 { "http://winehq.org/tests/.././tests", 0, S_OK, FALSE,
114 {"http://winehq.org/tests",S_OK,TRUE},
115 {"winehq.org",S_OK,TRUE},
116 {"http://winehq.org/tests",S_OK,TRUE},
117 {"winehq.org",S_OK,TRUE},
120 {"winehq.org",S_OK,TRUE},
122 {"/tests",S_OK,TRUE},
123 {"/tests",S_OK,TRUE},
125 {"http://winehq.org/tests/.././tests",S_OK,TRUE},
131 {Uri_HOST_DNS,S_OK,TRUE},
133 {URL_SCHEME_HTTP,S_OK,TRUE},
134 {URLZONE_INVALID,E_NOTIMPL,FALSE}
137 { "HtTp://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, FALSE,
139 {"http://www.winehq.org/?query=x&return=y",S_OK,TRUE},
140 {"www.winehq.org",S_OK,TRUE},
141 {"http://www.winehq.org/?query=x&return=y",S_OK,TRUE},
142 {"winehq.org",S_OK,TRUE},
145 {"www.winehq.org",S_OK,TRUE},
148 {"/?query=x&return=y",S_OK,TRUE},
149 {"?query=x&return=y",S_OK,TRUE},
150 {"HtTp://www.winehq.org/tests/..?query=x&return=y",S_OK,TRUE},
156 {Uri_HOST_DNS,S_OK,TRUE},
158 {URL_SCHEME_HTTP,S_OK,TRUE},
159 {URLZONE_INVALID,E_NOTIMPL,FALSE},
162 { "hTTp://us%45r%3Ainfo@examp%4CE.com:80/path/a/b/./c/../%2E%2E/Forbidden'<|> Characters", 0, S_OK, FALSE,
164 {"http://usEr%3Ainfo@example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
165 {"usEr%3Ainfo@example.com",S_OK,TRUE},
166 {"http://example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
167 {"example.com",S_OK,TRUE},
170 {"example.com",S_OK,TRUE},
172 {"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
173 {"/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,TRUE},
175 {"hTTp://us%45r%3Ainfo@examp%4CE.com:80/path/a/b/./c/../%2E%2E/Forbidden'<|> Characters",S_OK,TRUE},
177 {"usEr%3Ainfo",S_OK,TRUE},
178 {"usEr%3Ainfo",S_OK,TRUE}
181 {Uri_HOST_DNS,S_OK,TRUE},
183 {URL_SCHEME_HTTP,S_OK,TRUE},
184 {URLZONE_INVALID,E_NOTIMPL,FALSE},
187 { "ftp://winepass:wine@ftp.winehq.org:9999/dir/foo bar.txt", 0, S_OK, FALSE,
189 {"ftp://winepass:wine@ftp.winehq.org:9999/dir/foo%20bar.txt",S_OK,TRUE},
190 {"winepass:wine@ftp.winehq.org:9999",S_OK,TRUE},
191 {"ftp://ftp.winehq.org:9999/dir/foo%20bar.txt",S_OK,TRUE},
192 {"winehq.org",S_OK,TRUE},
195 {"ftp.winehq.org",S_OK,TRUE},
197 {"/dir/foo%20bar.txt",S_OK,TRUE},
198 {"/dir/foo%20bar.txt",S_OK,TRUE},
200 {"ftp://winepass:wine@ftp.winehq.org:9999/dir/foo bar.txt",S_OK,TRUE},
202 {"winepass:wine",S_OK,TRUE},
203 {"winepass",S_OK,TRUE}
206 {Uri_HOST_DNS,S_OK,TRUE},
208 {URL_SCHEME_FTP,S_OK,TRUE},
209 {URLZONE_INVALID,E_NOTIMPL,FALSE}
212 { "file://c:\\tests\\../tests/foo%20bar.mp3", 0, S_OK, FALSE,
214 {"file:///c:/tests/foo%2520bar.mp3",S_OK,TRUE},
216 {"file:///c:/tests/foo%2520bar.mp3",S_OK,TRUE},
222 {"/c:/tests/foo%2520bar.mp3",S_OK,TRUE},
223 {"/c:/tests/foo%2520bar.mp3",S_OK,TRUE},
225 {"file://c:\\tests\\../tests/foo%20bar.mp3",S_OK,TRUE},
231 {Uri_HOST_UNKNOWN,S_OK,TRUE},
233 {URL_SCHEME_FILE,S_OK,TRUE},
234 {URLZONE_INVALID,E_NOTIMPL,FALSE}
237 { "FILE://localhost/test dir\\../tests/test%20file.README.txt", 0, S_OK, FALSE,
239 {"file:///tests/test%20file.README.txt",S_OK,TRUE},
241 {"file:///tests/test%20file.README.txt",S_OK,TRUE},
247 {"/tests/test%20file.README.txt",S_OK,TRUE},
248 {"/tests/test%20file.README.txt",S_OK,TRUE},
250 {"FILE://localhost/test dir\\../tests/test%20file.README.txt",S_OK,TRUE},
256 {Uri_HOST_UNKNOWN,S_OK,TRUE},
258 {URL_SCHEME_FILE,S_OK,TRUE},
259 {URLZONE_INVALID,E_NOTIMPL,FALSE}
262 { "urn:nothing:should:happen here", 0, S_OK, FALSE,
264 {"urn:nothing:should:happen here",S_OK,TRUE},
266 {"urn:nothing:should:happen here",S_OK,TRUE},
272 {"nothing:should:happen here",S_OK,TRUE},
273 {"nothing:should:happen here",S_OK,TRUE},
275 {"urn:nothing:should:happen here",S_OK,TRUE},
281 {Uri_HOST_UNKNOWN,S_OK,TRUE},
283 {URL_SCHEME_UNKNOWN,S_OK,TRUE},
284 {URLZONE_INVALID,E_NOTIMPL,FALSE}
289 static inline LPWSTR a2w(LPCSTR str) {
293 DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
294 ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
295 MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
301 static inline BOOL heap_free(void* mem) {
302 return HeapFree(GetProcessHeap(), 0, mem);
305 static inline DWORD strcmp_aw(LPCSTR strA, LPCWSTR strB) {
306 LPWSTR strAW = a2w(strA);
307 DWORD ret = lstrcmpW(strAW, strB);
313 * Simple tests to make sure the CreateUri function handles invalid flag combinations
316 static void test_CreateUri_InvalidFlags(void) {
319 for(i = 0; i < sizeof(invalid_flag_tests)/sizeof(invalid_flag_tests[0]); ++i) {
321 IUri *uri = (void*) 0xdeadbeef;
323 hr = pCreateUri(http_urlW, invalid_flag_tests[i].flags, 0, &uri);
325 ok(hr == invalid_flag_tests[i].expected, "Error: CreateUri returned 0x%08x, expected 0x%08x, flags=0x%08x\n",
326 hr, invalid_flag_tests[i].expected, invalid_flag_tests[i].flags);
328 todo_wine { ok(uri == NULL, "Error: expected the IUri to be NULL, but it was %p instead\n", uri); }
332 static void test_CreateUri_InvalidArgs(void) {
334 IUri *uri = (void*) 0xdeadbeef;
336 hr = pCreateUri(http_urlW, 0, 0, NULL);
337 ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
339 hr = pCreateUri(NULL, 0, 0, &uri);
340 ok(hr == E_INVALIDARG, "Error: CreateUri returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG);
341 ok(uri == NULL, "Error: Expected the IUri to be NULL, but it was %p instead\n", uri);
344 static void test_IUri_GetPropertyBSTR(void) {
347 for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
348 uri_properties test = uri_tests[i];
353 uriW = a2w(test.uri);
354 hr = pCreateUri(uriW, test.create_flags, 0, &uri);
355 if(test.create_todo) {
357 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
358 hr, test.create_expected, i);
361 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
362 hr, test.create_expected, i);
368 /* Checks all the string properties of the uri. */
369 for(j = Uri_PROPERTY_STRING_START; j <= Uri_PROPERTY_STRING_LAST; ++j) {
370 BSTR received = NULL;
371 uri_str_property prop = test.str_props[j];
373 hr = IUri_GetPropertyBSTR(uri, j, &received, 0);
376 ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
377 hr, prop.expected, i, j);
380 ok(!strcmp_aw(prop.value, received), "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
381 prop.value, wine_dbgstr_w(received), i, j);
384 ok(hr == prop.expected, "GetPropertyBSTR returned 0x%08x, expected 0x%08x. On uri_tests[%d].str_props[%d].\n",
385 hr, prop.expected, i, j);
386 ok(!strcmp_aw(prop.value, received), "Expected %s but got %s on uri_tests[%d].str_props[%d].\n",
387 prop.value, wine_dbgstr_w(received), i, j);
390 SysFreeString(received);
394 if(uri) IUri_Release(uri);
400 static void test_IUri_GetPropertyDWORD(void) {
405 hr = pCreateUri(http_urlW, 0, 0, &uri);
406 ok(hr == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hr, S_OK);
408 hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_DWORD_START, NULL, 0);
409 ok(hr == E_INVALIDARG, "Error: GetPropertyDWORD returned 0x%08x, expected 0x%08x.\n", hr, E_INVALIDARG);
411 if(uri) IUri_Release(uri);
413 for(i = 0; i < sizeof(uri_tests)/sizeof(uri_tests[0]); ++i) {
414 uri_properties test = uri_tests[i];
418 uriW = a2w(test.uri);
419 hr = pCreateUri(uriW, test.create_flags, 0, &uri);
420 if(test.create_todo) {
422 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
423 hr, test.create_expected, i);
426 ok(hr == test.create_expected, "Error: CreateUri returned 0x%08x, expected 0x%08x. Failed on uri_tests[%d].\n",
427 hr, test.create_expected, i);
433 /* Checks all the DWORD properties of the uri. */
434 for(j = 0; j < sizeof(test.dword_props)/sizeof(test.dword_props[0]); ++j) {
436 uri_dword_property prop = test.dword_props[j];
438 hr = IUri_GetPropertyDWORD(uri, j+Uri_PROPERTY_DWORD_START, &received, 0);
441 ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
442 hr, prop.expected, i, j);
445 ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
446 prop.value, received, i, j);
449 ok(hr == prop.expected, "GetPropertyDWORD returned 0x%08x, expected 0x%08x. On uri_tests[%d].dword_props[%d].\n",
450 hr, prop.expected, i, j);
451 ok(prop.value == received, "Expected %d but got %d on uri_tests[%d].dword_props[%d].\n",
452 prop.value, received, i, j);
457 if(uri) IUri_Release(uri);
466 hurlmon = GetModuleHandle("urlmon.dll");
467 pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
470 win_skip("CreateUri is not present, skipping tests.\n");
474 trace("test CreateUri invalid flags...\n");
475 test_CreateUri_InvalidFlags();
477 trace("test CreateUri invalid args...\n");
478 test_CreateUri_InvalidArgs();
480 trace("test IUri_GetPropertyBSTR...\n");
481 test_IUri_GetPropertyBSTR();
483 trace("test IUri_GetPropretyDWORD...\n");
484 test_IUri_GetPropertyDWORD();