| 1 | // Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | import net.urllib |
| 5 | |
| 6 | fn test_str() { |
| 7 | url := urllib.parse('https://en.wikipedia.org/wiki/Brazil_(1985_film)') or { |
| 8 | panic('unable to parse URL') |
| 9 | } |
| 10 | assert url.str() == 'https://en.wikipedia.org/wiki/Brazil_(1985_film)' |
| 11 | } |
| 12 | |
| 13 | fn test_escape_unescape() { |
| 14 | mut original := 'те ст: т\\%' |
| 15 | mut escaped := urllib.query_escape(original) |
| 16 | assert escaped == '%D1%82%D0%B5+%D1%81%D1%82%3A+%D1%82%5C%25' |
| 17 | mut unescaped := urllib.query_unescape(escaped)! |
| 18 | assert unescaped == original |
| 19 | |
| 20 | original = 'Hellö Wörld@vlang' |
| 21 | escaped = urllib.query_escape(original) |
| 22 | assert escaped == 'Hell%C3%B6+W%C3%B6rld%40vlang' |
| 23 | unescaped = urllib.query_unescape(escaped)! |
| 24 | assert unescaped == original |
| 25 | } |
| 26 | |
| 27 | fn test_parse_query() { |
| 28 | q1 := urllib.parse_query('format=%22%25l%3A+%25c+%25t%22')! |
| 29 | q2 := urllib.parse_query('format="%l:+%c+%t"')! |
| 30 | // dump(q1) |
| 31 | // dump(q2) |
| 32 | assert q1.get('format')? == '"%l: %c %t"' |
| 33 | assert q2.get('format')? == '"%l: %c %t"' |
| 34 | } |
| 35 | |
| 36 | fn test_parse_query_orders() { |
| 37 | query_one := |
| 38 | urllib.parse_query('https://someapi.com/endpoint?gamma=zalibaba&tau=1&alpha=alibaba&signature=alibaba123')! |
| 39 | qvalues := query_one.values() |
| 40 | assert qvalues == ['zalibaba', '1', 'alibaba', 'alibaba123'] |
| 41 | } |
| 42 | |
| 43 | fn test_parse_missing_host() { |
| 44 | // issue #10311 |
| 45 | url := urllib.parse('http:///')! |
| 46 | assert url.str() == 'http://///' |
| 47 | } |
| 48 | |
| 49 | // testing the case where the key as a null value |
| 50 | // e.g ?key= |
| 51 | fn test_parse_none_value() { |
| 52 | query_one := urllib.parse_query('gamma=zalibaba&tau=1&alpha=alibaba&signature=')! |
| 53 | qvalues := query_one.values() |
| 54 | qvalues_map := query_one.to_map() |
| 55 | assert qvalues == ['zalibaba', '1', 'alibaba'] |
| 56 | assert qvalues_map == { |
| 57 | 'gamma': ['zalibaba'] |
| 58 | 'tau': ['1'] |
| 59 | 'alpha': ['alibaba'] |
| 60 | 'signature': [''] |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | // testing the case where the query as empity value |
| 65 | // e.g https://www.vlang.dev?alibaba |
| 66 | fn test_parse_empty_query_one() { |
| 67 | query_str := 'alibaba' |
| 68 | query_one := urllib.parse_query(query_str)! |
| 69 | qvalues := query_one.values() |
| 70 | qvalues_map := query_one.to_map() |
| 71 | query_encode := query_one.encode() |
| 72 | assert qvalues == [] |
| 73 | assert qvalues_map == { |
| 74 | 'alibaba': [''] |
| 75 | } |
| 76 | assert query_str == query_encode |
| 77 | } |
| 78 | |
| 79 | // testing the case where the query as empty value |
| 80 | // e.g https://www.vlang.dev? |
| 81 | fn test_parse_empty_query_two() { |
| 82 | query_str := '' |
| 83 | query_one := urllib.parse_query(query_str)! |
| 84 | qvalues := query_one.values() |
| 85 | qvalues_map := query_one.to_map() |
| 86 | query_encode := query_one.encode() |
| 87 | assert qvalues == [] |
| 88 | assert qvalues_map == {} |
| 89 | assert query_str == query_encode |
| 90 | } |
| 91 | |
| 92 | fn test_parse() { |
| 93 | urls := [ |
| 94 | 'jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true', |
| 95 | 'ftp://ftp.is.co.za/rfc/rfc1808.txt', |
| 96 | 'http://www.ietf.org/rfc/rfc2396.txt#header1', |
| 97 | 'ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two', |
| 98 | 'mailto:[email protected]', |
| 99 | 'news:comp.infosystems.www.servers.unix', |
| 100 | 'tel:+1-816-555-1212', |
| 101 | 'telnet://192.0.2.16:80/', |
| 102 | 'urn:oasis:names:specification:docbook:dtd:xml:4.1.2', |
| 103 | 'foo://example.com:8042/over/there?name=ferret#nose', |
| 104 | 'ftp://2001:0db8:85a3:0000:0000:8a2e:0370:7334/path/file.txt', |
| 105 | 'ws://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:4000', |
| 106 | '/2000k/hls/mixed.m3u8', |
| 107 | '2000k/hls/mixed.m3u8', |
| 108 | './2000k:hls/mixed.m3u8', |
| 109 | ] |
| 110 | for url in urls { |
| 111 | urllib.parse(url)! |
| 112 | } |
| 113 | |
| 114 | test_url := 'https://joe:[email protected]:8080/som/url?param1=test1¶m2=test2&foo=bar#testfragment' |
| 115 | u := urllib.parse(test_url)! |
| 116 | if user := u.user { |
| 117 | assert u.scheme == 'https' && u.hostname() == 'www.mydomain.com' && u.port() == '8080' |
| 118 | && u.path == '/som/url' && u.fragment == 'testfragment' && user.username == 'joe' |
| 119 | && user.password == 'pass' |
| 120 | } |
| 121 | |
| 122 | v := |
| 123 | urllib.parse('https://vip.ffzy-online4.com/20230205/6094_d2720761/index.m3u8')!.resolve_reference(urllib.parse('2000k/hls/mixed.m3u8')!)! |
| 124 | assert v.str() == 'https://vip.ffzy-online4.com/20230205/6094_d2720761/2000k/hls/mixed.m3u8' |
| 125 | } |
| 126 | |
| 127 | fn test_parse_authority() { |
| 128 | test_urls := { |
| 129 | 'ftp://[email protected]/': ['webmaster', ''] |
| 130 | 'http://j@ne:[email protected]': ['j@ne', 'password'] |
| 131 | 'http://jane:p@[email protected]/p@th?q=@go': ['jane', 'p@ssword'] |
| 132 | } |
| 133 | |
| 134 | for url, expected in test_urls { |
| 135 | u := urllib.parse(url)! |
| 136 | if user := u.user { |
| 137 | assert user.username == expected[0] |
| 138 | assert user.password == expected[1] |
| 139 | } |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | fn test_parse_slashes() { |
| 144 | assert urllib.parse('/')!.str() == '/' |
| 145 | assert urllib.parse('//')!.str() == '//' |
| 146 | assert urllib.parse('///')!.str() == '///' |
| 147 | } |
| 148 | |