1 /***
2  * Copyright (C) Microsoft. All rights reserved.
3  * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4  *
5  * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
6  *
7  * constructor_tests.cpp
8  *
9  * Tests for constructors of the uri class.
10  *
11  * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
12  ****/
13 
14 #include "stdafx.h"
15 
16 using namespace web;
17 using namespace utility;
18 
19 namespace tests
20 {
21 namespace functional
22 {
23 namespace uri_tests
24 {
SUITE(constructor_tests)25 SUITE(constructor_tests)
26 {
27     TEST(parsing_constructor_char)
28     {
29         uri u(uri::encode_uri(U("net.tcp://steve:@testname.com:81/bleh%?qstring#goo")));
30 
31         VERIFY_ARE_EQUAL(U("net.tcp"), u.scheme());
32         VERIFY_ARE_EQUAL(U("steve:"), u.user_info());
33         VERIFY_ARE_EQUAL(U("testname.com"), u.host());
34         VERIFY_ARE_EQUAL(81, u.port());
35         VERIFY_ARE_EQUAL(U("/bleh%25"), u.path());
36         VERIFY_ARE_EQUAL(U("qstring"), u.query());
37         VERIFY_ARE_EQUAL(U("goo"), u.fragment());
38     }
39 
40     TEST(parsing_constructor_encoded_string)
41     {
42         uri u(uri::encode_uri(U("net.tcp://testname.com:81/bleh%?qstring#goo")));
43 
44         VERIFY_ARE_EQUAL(U("net.tcp"), u.scheme());
45         VERIFY_ARE_EQUAL(U("testname.com"), u.host());
46         VERIFY_ARE_EQUAL(81, u.port());
47         VERIFY_ARE_EQUAL(U("/bleh%25"), u.path());
48         VERIFY_ARE_EQUAL(U("qstring"), u.query());
49         VERIFY_ARE_EQUAL(U("goo"), u.fragment());
50     }
51 
52     TEST(parsing_constructor_string_string)
53     {
54         uri u(uri::encode_uri(U("net.tcp://testname.com:81/bleh%?qstring#goo")));
55 
56         VERIFY_ARE_EQUAL(U("net.tcp"), u.scheme());
57         VERIFY_ARE_EQUAL(U("testname.com"), u.host());
58         VERIFY_ARE_EQUAL(81, u.port());
59         VERIFY_ARE_EQUAL(U("/bleh%25"), u.path());
60         VERIFY_ARE_EQUAL(U("qstring"), u.query());
61         VERIFY_ARE_EQUAL(U("goo"), u.fragment());
62     }
63 
64     TEST(empty_strings)
65     {
66         VERIFY_IS_TRUE(uri(U("")).is_empty());
67         VERIFY_IS_TRUE(uri(U("")).is_empty());
68         VERIFY_IS_TRUE(uri(uri::encode_uri(U(""))).is_empty());
69     }
70 
71     TEST(default_constructor) { VERIFY_IS_TRUE(uri().is_empty()); }
72 
73     TEST(relative_ref_string)
74     {
75         uri u(uri::encode_uri(U("first/second#boff")));
76 
77         VERIFY_ARE_EQUAL(U(""), u.scheme());
78         VERIFY_ARE_EQUAL(U(""), u.host());
79         VERIFY_ARE_EQUAL(0, u.port());
80         VERIFY_ARE_EQUAL(U("first/second"), u.path());
81         VERIFY_ARE_EQUAL(U(""), u.query());
82         VERIFY_ARE_EQUAL(U("boff"), u.fragment());
83     }
84 
85     TEST(absolute_ref_string)
86     {
87         uri u(uri::encode_uri(U("/first/second#boff")));
88 
89         VERIFY_ARE_EQUAL(U(""), u.scheme());
90         VERIFY_ARE_EQUAL(U(""), u.host());
91         VERIFY_ARE_EQUAL(0, u.port());
92         VERIFY_ARE_EQUAL(U("/first/second"), u.path());
93         VERIFY_ARE_EQUAL(U(""), u.query());
94         VERIFY_ARE_EQUAL(U("boff"), u.fragment());
95     }
96 
97     TEST(copy_constructor)
98     {
99         uri original(U("http://st:pass@localhost:456/path1?qstring#goo"));
100         uri new_uri(original);
101 
102         VERIFY_ARE_EQUAL(original, new_uri);
103     }
104 
105     TEST(move_constructor)
106     {
107         const utility::string_t uri_str(U("http://localhost:456/path1?qstring#goo"));
108         uri original(uri_str);
109         uri new_uri = std::move(original);
110 
111         VERIFY_ARE_EQUAL(uri_str, new_uri.to_string());
112         VERIFY_ARE_EQUAL(uri(uri_str), new_uri);
113     }
114 
115     TEST(assignment_operator)
116     {
117         uri original(U("http://localhost:456/path?qstring#goo"));
118         uri new_uri = original;
119 
120         VERIFY_ARE_EQUAL(original, new_uri);
121     }
122 
123     // Tests invalid URI being passed in constructor.
124     TEST(parsing_constructor_invalid)
125     {
126         VERIFY_THROWS(uri(U("123http://localhost:345/")), uri_exception);
127         VERIFY_THROWS(uri(U("h*ttp://localhost:345/")), uri_exception);
128         VERIFY_THROWS(uri(U("http://localhost:345/\"")), uri_exception);
129         VERIFY_THROWS(uri(U("http://localhost:345/path?\"")), uri_exception);
130         VERIFY_THROWS(uri(U("http://local\"host:345/")), uri_exception);
131     }
132 
133     // Tests a variety of different URIs using the examples in RFC 2732
134     TEST(RFC_2732_examples_string)
135     {
136         // The URI parser will make characters lower case
137         uri http1(U("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html"));
138         VERIFY_ARE_EQUAL(U("http"), http1.scheme());
139         VERIFY_ARE_EQUAL(U("[fedc:ba98:7654:3210:fedc:ba98:7654:3210]"), http1.host());
140         VERIFY_ARE_EQUAL(80, http1.port());
141         VERIFY_ARE_EQUAL(U("/index.html"), http1.path());
142         VERIFY_ARE_EQUAL(U(""), http1.query());
143 
144         uri http2(U("http://[1080:0:0:0:8:800:200C:417A]/index.html"));
145         VERIFY_ARE_EQUAL(U("http"), http2.scheme());
146         VERIFY_ARE_EQUAL(U("[1080:0:0:0:8:800:200c:417a]"), http2.host());
147         VERIFY_ARE_EQUAL(0, http2.port());
148         VERIFY_ARE_EQUAL(U("/index.html"), http2.path());
149         VERIFY_ARE_EQUAL(U(""), http2.query());
150 
151         uri http3(U("https://[3ffe:2a00:100:7031::1]"));
152         VERIFY_ARE_EQUAL(U("https"), http3.scheme());
153         VERIFY_ARE_EQUAL(U("[3ffe:2a00:100:7031::1]"), http3.host());
154         VERIFY_ARE_EQUAL(0, http3.port());
155         VERIFY_ARE_EQUAL(U("/"), http3.path());
156         VERIFY_ARE_EQUAL(U(""), http3.query());
157 
158         uri http4(U("http://[::192.9.5.5]/ipng"));
159         VERIFY_ARE_EQUAL(U("http"), http4.scheme());
160         VERIFY_ARE_EQUAL(U("[::192.9.5.5]"), http4.host());
161         VERIFY_ARE_EQUAL(0, http4.port());
162         VERIFY_ARE_EQUAL(U("/ipng"), http4.path());
163         VERIFY_ARE_EQUAL(U(""), http4.query());
164 
165         uri http5(U("http://[1080::8:800:200C:417A]/foo"));
166         VERIFY_ARE_EQUAL(U("http"), http5.scheme());
167         VERIFY_ARE_EQUAL(U("[1080::8:800:200c:417a]"), http5.host());
168         VERIFY_ARE_EQUAL(0, http5.port());
169         VERIFY_ARE_EQUAL(U("/foo"), http5.path());
170         VERIFY_ARE_EQUAL(U(""), http5.query());
171 
172         uri http6(U("http://[::FFFF:129.144.52.38]:80/index.html"));
173         VERIFY_ARE_EQUAL(U("http"), http6.scheme());
174         VERIFY_ARE_EQUAL(U("[::ffff:129.144.52.38]"), http6.host());
175         VERIFY_ARE_EQUAL(80, http6.port());
176         VERIFY_ARE_EQUAL(U("/index.html"), http6.path());
177         VERIFY_ARE_EQUAL(U(""), http6.query());
178 
179         uri http7(U("http://[2010:836B:4179::836B:4179]"));
180         VERIFY_ARE_EQUAL(U("http"), http7.scheme());
181         VERIFY_ARE_EQUAL(U("[2010:836b:4179::836b:4179]"), http7.host());
182         VERIFY_ARE_EQUAL(0, http7.port());
183         VERIFY_ARE_EQUAL(U("/"), http7.path());
184         VERIFY_ARE_EQUAL(U(""), http7.query());
185     }
186 
187     // Tests a variety of different URIs using the examples in RFC 3986.
188     TEST(RFC_3968_examples_string)
189     {
190         uri ftp(U("ftp://ftp.is.co.za/rfc/rfc1808.txt"));
191         VERIFY_ARE_EQUAL(U("ftp"), ftp.scheme());
192         VERIFY_ARE_EQUAL(U(""), ftp.user_info());
193         VERIFY_ARE_EQUAL(U("ftp.is.co.za"), ftp.host());
194         VERIFY_ARE_EQUAL(0, ftp.port());
195         VERIFY_ARE_EQUAL(U("/rfc/rfc1808.txt"), ftp.path());
196         VERIFY_ARE_EQUAL(U(""), ftp.query());
197         VERIFY_ARE_EQUAL(U(""), ftp.fragment());
198 
199         // TFS #371892
200         // uri ldap(U("ldap://[2001:db8::7]/?c=GB#objectClass?one"));
201         // VERIFY_ARE_EQUAL(U("ldap"), ldap.scheme());
202         // VERIFY_ARE_EQUAL(U(""), ldap.user_info());
203         // VERIFY_ARE_EQUAL(U("2001:db8::7"), ldap.host());
204         // VERIFY_ARE_EQUAL(0, ldap.port());
205         // VERIFY_ARE_EQUAL(U("/"), ldap.path());
206         // VERIFY_ARE_EQUAL(U("c=GB"), ldap.query());
207         // VERIFY_ARE_EQUAL(U("objectClass?one"), ldap.fragment());
208 
209         // We don't support anything scheme specific like in C# so
210         // these common ones don't have a great experience yet.
211         uri mailto(U("mailto:John.Doe@example.com"));
212         VERIFY_ARE_EQUAL(U("mailto"), mailto.scheme());
213         VERIFY_ARE_EQUAL(U(""), mailto.user_info());
214         VERIFY_ARE_EQUAL(U(""), mailto.host());
215         VERIFY_ARE_EQUAL(0, mailto.port());
216         VERIFY_ARE_EQUAL(U("John.Doe@example.com"), mailto.path());
217         VERIFY_ARE_EQUAL(U(""), mailto.query());
218         VERIFY_ARE_EQUAL(U(""), mailto.fragment());
219 
220         uri tel(U("tel:+1-816-555-1212"));
221         VERIFY_ARE_EQUAL(U("tel"), tel.scheme());
222         VERIFY_ARE_EQUAL(U(""), tel.user_info());
223         VERIFY_ARE_EQUAL(U(""), tel.host());
224         VERIFY_ARE_EQUAL(0, tel.port());
225         VERIFY_ARE_EQUAL(U("+1-816-555-1212"), tel.path());
226         VERIFY_ARE_EQUAL(U(""), tel.query());
227         VERIFY_ARE_EQUAL(U(""), tel.fragment());
228 
229         uri telnet(U("telnet://192.0.2.16:80/"));
230         VERIFY_ARE_EQUAL(U("telnet"), telnet.scheme());
231         VERIFY_ARE_EQUAL(U(""), telnet.user_info());
232         VERIFY_ARE_EQUAL(U("192.0.2.16"), telnet.host());
233         VERIFY_ARE_EQUAL(80, telnet.port());
234         VERIFY_ARE_EQUAL(U("/"), telnet.path());
235         VERIFY_ARE_EQUAL(U(""), telnet.query());
236         VERIFY_ARE_EQUAL(U(""), telnet.fragment());
237     }
238 
239     TEST(user_info_string)
240     {
241         uri ftp(U("ftp://johndoe:testname@ftp.is.co.za/rfc/rfc1808.txt"));
242         VERIFY_ARE_EQUAL(U("ftp"), ftp.scheme());
243         VERIFY_ARE_EQUAL(U("johndoe:testname"), ftp.user_info());
244         VERIFY_ARE_EQUAL(U("ftp.is.co.za"), ftp.host());
245         VERIFY_ARE_EQUAL(0, ftp.port());
246         VERIFY_ARE_EQUAL(U("/rfc/rfc1808.txt"), ftp.path());
247         VERIFY_ARE_EQUAL(U(""), ftp.query());
248         VERIFY_ARE_EQUAL(U(""), ftp.fragment());
249     }
250 
251     // Test query component can be separated with '&' or ';'.
252     TEST(query_seperated_with_semi_colon)
253     {
254         uri u(U("http://localhost/path1?key1=val1;key2=val2"));
255         VERIFY_ARE_EQUAL(U("key1=val1;key2=val2"), u.query());
256     }
257 
258 } // SUITE(constructor_tests)
259 
260 } // namespace uri_tests
261 } // namespace functional
262 } // namespace tests
263