OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library shelf.request_test; | 5 library shelf.request_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 | 9 |
10 import 'package:shelf/shelf.dart'; | 10 import 'package:shelf/shelf.dart'; |
(...skipping 11 matching lines...) Expand all Loading... |
22 test('protocolVersion defaults to "1.1"', () { | 22 test('protocolVersion defaults to "1.1"', () { |
23 var request = new Request('GET', LOCALHOST_URI); | 23 var request = new Request('GET', LOCALHOST_URI); |
24 expect(request.protocolVersion, '1.1'); | 24 expect(request.protocolVersion, '1.1'); |
25 }); | 25 }); |
26 | 26 |
27 test('provide non-default protocolVersion', () { | 27 test('provide non-default protocolVersion', () { |
28 var request = new Request('GET', LOCALHOST_URI, protocolVersion: '1.0'); | 28 var request = new Request('GET', LOCALHOST_URI, protocolVersion: '1.0'); |
29 expect(request.protocolVersion, '1.0'); | 29 expect(request.protocolVersion, '1.0'); |
30 }); | 30 }); |
31 | 31 |
32 test('requestedUri must be absolute', () { | 32 group("url", () { |
33 expect(() => new Request('GET', Uri.parse('/path')), throwsArgumentError); | 33 test("defaults to the requestedUri's relativized path and query", () { |
| 34 var request = |
| 35 new Request('GET', Uri.parse("http://localhost/foo/bar?q=1")); |
| 36 expect(request.url, equals(Uri.parse("foo/bar?q=1"))); |
| 37 }); |
| 38 |
| 39 test("is inferred from handlerPath if possible", () { |
| 40 var request = new Request( |
| 41 'GET', Uri.parse("http://localhost/foo/bar?q=1"), |
| 42 handlerPath: '/foo/'); |
| 43 expect(request.url, equals(Uri.parse("bar?q=1"))); |
| 44 }); |
| 45 |
| 46 test("uses the given value if passed", () { |
| 47 var request = new Request( |
| 48 'GET', Uri.parse("http://localhost/foo/bar?q=1"), |
| 49 url: Uri.parse("bar?q=1")); |
| 50 expect(request.url, equals(Uri.parse("bar?q=1"))); |
| 51 }); |
34 }); | 52 }); |
35 | 53 |
36 test('if uri is null, scriptName must be null', () { | 54 group("handlerPath", () { |
37 expect(() => new Request('GET', Uri.parse('/path'), | 55 test("defaults to '/'", () { |
38 scriptName: '/script/name'), throwsArgumentError); | 56 var request = new Request('GET', Uri.parse("http://localhost/foo/bar")); |
| 57 expect(request.handlerPath, equals('/')); |
| 58 }); |
| 59 |
| 60 test("is inferred from url if possible", () { |
| 61 var request = new Request( |
| 62 'GET', Uri.parse("http://localhost/foo/bar?q=1"), |
| 63 url: Uri.parse("bar?q=1")); |
| 64 expect(request.handlerPath, equals("/foo/")); |
| 65 }); |
| 66 |
| 67 test("uses the given value if passed", () { |
| 68 var request = new Request( |
| 69 'GET', Uri.parse("http://localhost/foo/bar?q=1"), |
| 70 handlerPath: '/foo/'); |
| 71 expect(request.handlerPath, equals("/foo/")); |
| 72 }); |
| 73 |
| 74 test("adds a trailing slash to the given value if necessary", () { |
| 75 var request = new Request( |
| 76 'GET', Uri.parse("http://localhost/foo/bar?q=1"), |
| 77 handlerPath: '/foo'); |
| 78 expect(request.handlerPath, equals("/foo/")); |
| 79 expect(request.url, equals(Uri.parse("bar?q=1"))); |
| 80 }); |
39 }); | 81 }); |
40 | 82 |
41 test('if scriptName is null, uri must be null', () { | 83 group("errors", () { |
42 var relativeUri = new Uri(path: '/cool/beans.html'); | 84 group('requestedUri', () { |
43 expect(() => new Request('GET', Uri.parse('/path'), url: relativeUri), | 85 test('must be absolute', () { |
44 throwsArgumentError); | 86 expect(() => new Request('GET', Uri.parse('/path')), |
45 }); | 87 throwsArgumentError); |
| 88 }); |
46 | 89 |
47 test('uri must be relative', () { | 90 test('may not have a fragment', () { |
48 var relativeUri = Uri.parse('http://localhost/test'); | 91 expect(() { |
| 92 new Request('GET', Uri.parse('http://localhost/#fragment')); |
| 93 }, throwsArgumentError); |
| 94 }); |
| 95 }); |
49 | 96 |
50 expect(() => new Request('GET', LOCALHOST_URI, | 97 group('url', () { |
51 url: relativeUri, scriptName: '/news'), throwsArgumentError); | 98 test('must be relative', () { |
| 99 expect(() { |
| 100 new Request('GET', Uri.parse('http://localhost/test'), |
| 101 url: Uri.parse('http://localhost/test')); |
| 102 }, throwsArgumentError); |
| 103 }); |
52 | 104 |
53 // NOTE: explicitly testing fragments due to Issue 18053 | 105 test('may not be root-relative', () { |
54 relativeUri = Uri.parse('http://localhost/test#fragment'); | 106 expect(() { |
| 107 new Request('GET', Uri.parse('http://localhost/test'), |
| 108 url: Uri.parse('/test')); |
| 109 }, throwsArgumentError); |
| 110 }); |
55 | 111 |
56 expect(() => new Request('GET', LOCALHOST_URI, | 112 test('may not have a fragment', () { |
57 url: relativeUri, scriptName: '/news'), throwsArgumentError); | 113 expect(() { |
58 }); | 114 new Request('GET', Uri.parse('http://localhost/test'), |
| 115 url: Uri.parse('test#fragment')); |
| 116 }, throwsArgumentError); |
| 117 }); |
59 | 118 |
60 test('uri and scriptName', () { | 119 test('must be a suffix of requestedUri', () { |
61 var pathInfo = '/pages/page.html?utm_source=ABC123'; | 120 expect(() { |
62 var scriptName = '/assets/static'; | 121 new Request('GET', Uri.parse('http://localhost/dir/test'), |
63 var fullUrl = 'http://localhost/other_path/other_resource.asp'; | 122 url: Uri.parse('dir')); |
64 var request = new Request('GET', Uri.parse(fullUrl), | 123 }, throwsArgumentError); |
65 url: Uri.parse(pathInfo), scriptName: scriptName); | 124 }); |
66 | 125 |
67 expect(request.scriptName, scriptName); | 126 test('must have the same query parameters as requestedUri', () { |
68 expect(request.url.path, '/pages/page.html'); | 127 expect(() { |
69 expect(request.url.query, 'utm_source=ABC123'); | 128 new Request('GET', Uri.parse('http://localhost/test?q=1&r=2'), |
70 }); | 129 url: Uri.parse('test?q=2&r=1')); |
| 130 }, throwsArgumentError); |
71 | 131 |
72 test('minimal uri', () { | 132 // Order matters for query parameters. |
73 var pathInfo = '/'; | 133 expect(() { |
74 var scriptName = '/assets/static'; | 134 new Request('GET', Uri.parse('http://localhost/test?q=1&r=2'), |
75 var fullUrl = 'http://localhost$scriptName$pathInfo'; | 135 url: Uri.parse('test?r=2&q=1')); |
76 var request = new Request('GET', Uri.parse(fullUrl), | 136 }, throwsArgumentError); |
77 url: Uri.parse(pathInfo), scriptName: scriptName); | 137 }); |
| 138 }); |
78 | 139 |
79 expect(request.scriptName, scriptName); | 140 group('handlerPath', () { |
80 expect(request.url.path, '/'); | 141 test('must be a prefix of requestedUri', () { |
81 expect(request.url.query, ''); | 142 expect(() { |
82 }); | 143 new Request('GET', Uri.parse('http://localhost/dir/test'), |
| 144 handlerPath: '/test'); |
| 145 }, throwsArgumentError); |
| 146 }); |
83 | 147 |
84 test('invalid url', () { | 148 test('must start with "/"', () { |
85 var testUrl = 'page'; | 149 expect(() { |
86 var scriptName = '/assets/static'; | 150 new Request('GET', Uri.parse('http://localhost/test'), |
87 var fullUrl = 'http://localhost$scriptName$testUrl'; | 151 handlerPath: 'test'); |
| 152 }, throwsArgumentError); |
| 153 }); |
| 154 }); |
88 | 155 |
89 expect(() => new Request('GET', Uri.parse(fullUrl), | 156 group('handlerPath + url must', () { |
90 url: Uri.parse(testUrl), scriptName: scriptName), | 157 test('be requestedUrl path', () { |
91 throwsArgumentError); | 158 expect(() { |
92 }); | 159 new Request('GET', Uri.parse('http://localhost/foo/bar/baz'), |
| 160 handlerPath: '/foo/', url: Uri.parse('baz')); |
| 161 }, throwsArgumentError); |
| 162 }); |
93 | 163 |
94 test('scriptName with no leading slash', () { | 164 test('be on a path boundary', () { |
95 var pathInfo = '/page'; | 165 expect(() { |
96 var scriptName = 'assets/static'; | 166 new Request('GET', Uri.parse('http://localhost/foo/bar/baz'), |
97 var fullUrl = 'http://localhost/assets/static/pages'; | 167 handlerPath: '/foo/ba', url: Uri.parse('r/baz')); |
98 | 168 }, throwsArgumentError); |
99 expect(() => new Request('GET', Uri.parse(fullUrl), | 169 }); |
100 url: Uri.parse(pathInfo), scriptName: scriptName), | 170 }); |
101 throwsArgumentError); | |
102 | |
103 pathInfo = '/assets/static/page'; | |
104 scriptName = '/'; | |
105 fullUrl = 'http://localhost/assets/static/pages'; | |
106 | |
107 expect(() => new Request('GET', Uri.parse(fullUrl), | |
108 url: Uri.parse(pathInfo), scriptName: scriptName), | |
109 throwsArgumentError); | |
110 }); | |
111 | |
112 test('scriptName that is only a slash', () { | |
113 var pathInfo = '/assets/static/page'; | |
114 var scriptName = '/'; | |
115 var fullUrl = 'http://localhost/assets/static/pages'; | |
116 | |
117 expect(() => new Request('GET', Uri.parse(fullUrl), | |
118 url: Uri.parse(pathInfo), scriptName: scriptName), | |
119 throwsArgumentError); | |
120 }); | 171 }); |
121 }); | 172 }); |
122 | 173 |
123 group("ifModifiedSince", () { | 174 group("ifModifiedSince", () { |
124 test("is null without an If-Modified-Since header", () { | 175 test("is null without an If-Modified-Since header", () { |
125 var request = _request(); | 176 var request = _request(); |
126 expect(request.ifModifiedSince, isNull); | 177 expect(request.ifModifiedSince, isNull); |
127 }); | 178 }); |
128 | 179 |
129 test("comes from the Last-Modified header", () { | 180 test("comes from the Last-Modified header", () { |
130 var request = _request( | 181 var request = _request( |
131 headers: {'if-modified-since': 'Sun, 06 Nov 1994 08:49:37 GMT'}); | 182 headers: {'if-modified-since': 'Sun, 06 Nov 1994 08:49:37 GMT'}); |
132 expect(request.ifModifiedSince, | 183 expect(request.ifModifiedSince, |
133 equals(DateTime.parse("1994-11-06 08:49:37z"))); | 184 equals(DateTime.parse("1994-11-06 08:49:37z"))); |
134 }); | 185 }); |
135 }); | 186 }); |
136 | 187 |
137 group('change', () { | 188 group('change', () { |
138 test('with no arguments returns instance with equal values', () { | 189 test('with no arguments returns instance with equal values', () { |
139 var controller = new StreamController(); | 190 var controller = new StreamController(); |
140 | 191 |
141 var uri = Uri.parse('https://test.example.com/static/file.html'); | 192 var uri = Uri.parse('https://test.example.com/static/file.html'); |
142 | 193 |
143 var request = new Request('GET', uri, | 194 var request = new Request('GET', uri, |
144 protocolVersion: '2.0', | 195 protocolVersion: '2.0', |
145 headers: {'header1': 'header value 1'}, | 196 headers: {'header1': 'header value 1'}, |
146 url: Uri.parse('/file.html'), | 197 url: Uri.parse('file.html'), |
147 scriptName: '/static', | 198 handlerPath: '/static/', |
148 body: controller.stream, | 199 body: controller.stream, |
149 context: {'context1': 'context value 1'}); | 200 context: {'context1': 'context value 1'}); |
150 | 201 |
151 var copy = request.change(); | 202 var copy = request.change(); |
152 | 203 |
153 expect(copy.method, request.method); | 204 expect(copy.method, request.method); |
154 expect(copy.requestedUri, request.requestedUri); | 205 expect(copy.requestedUri, request.requestedUri); |
155 expect(copy.protocolVersion, request.protocolVersion); | 206 expect(copy.protocolVersion, request.protocolVersion); |
156 expect(copy.headers, same(request.headers)); | 207 expect(copy.headers, same(request.headers)); |
157 expect(copy.url, request.url); | 208 expect(copy.url, request.url); |
158 expect(copy.scriptName, request.scriptName); | 209 expect(copy.handlerPath, request.handlerPath); |
159 expect(copy.context, same(request.context)); | 210 expect(copy.context, same(request.context)); |
160 expect(copy.readAsString(), completion('hello, world')); | 211 expect(copy.readAsString(), completion('hello, world')); |
161 | 212 |
162 controller.add(HELLO_BYTES); | 213 controller.add(HELLO_BYTES); |
163 return new Future(() { | 214 return new Future(() { |
164 controller | 215 controller |
165 ..add(WORLD_BYTES) | 216 ..add(WORLD_BYTES) |
166 ..close(); | 217 ..close(); |
167 }); | 218 }); |
168 }); | 219 }); |
169 | 220 |
170 group('with just scriptName', () { | 221 group('with path', () { |
171 test('updates url if scriptName matches existing url', () { | 222 test('updates handlerPath and url', () { |
172 var uri = Uri.parse('https://test.example.com/static/file.html'); | 223 var uri = Uri.parse('https://test.example.com/static/dir/file.html'); |
173 var request = new Request('GET', uri); | 224 var request = new Request('GET', uri, |
174 var copy = request.change(scriptName: '/static'); | 225 handlerPath: '/static/', url: Uri.parse('dir/file.html')); |
| 226 var copy = request.change(path: 'dir'); |
175 | 227 |
176 expect(copy.scriptName, '/static'); | 228 expect(copy.handlerPath, '/static/dir/'); |
177 expect(copy.url, Uri.parse('/file.html')); | 229 expect(copy.url, Uri.parse('file.html')); |
178 }); | 230 }); |
179 | 231 |
180 test('throws if striptName does not match existing url', () { | 232 test('allows a trailing slash', () { |
181 var uri = Uri.parse('https://test.example.com/static/file.html'); | 233 var uri = Uri.parse('https://test.example.com/static/dir/file.html'); |
182 var request = new Request('GET', uri); | 234 var request = new Request('GET', uri, |
| 235 handlerPath: '/static/', url: Uri.parse('dir/file.html')); |
| 236 var copy = request.change(path: 'dir/'); |
183 | 237 |
184 expect(() => request.change(scriptName: '/nope'), throwsArgumentError); | 238 expect(copy.handlerPath, '/static/dir/'); |
| 239 expect(copy.url, Uri.parse('file.html')); |
185 }); | 240 }); |
186 }); | |
187 | 241 |
188 test('url', () { | 242 test('throws if path does not match existing uri', () { |
189 var uri = Uri.parse('https://test.example.com/static/file.html'); | 243 var uri = Uri.parse('https://test.example.com/static/dir/file.html'); |
190 var request = new Request('GET', uri); | 244 var request = new Request('GET', uri, |
191 var copy = request.change(url: Uri.parse('/other_path/file.html')); | 245 handlerPath: '/static/', url: Uri.parse('dir/file.html')); |
192 | 246 |
193 expect(copy.scriptName, ''); | 247 expect(() => request.change(path: 'wrong'), throwsArgumentError); |
194 expect(copy.url, Uri.parse('/other_path/file.html')); | 248 }); |
195 }); | |
196 | 249 |
197 test('scriptName and url', () { | 250 test("throws if path isn't a path boundary", () { |
198 var uri = Uri.parse('https://test.example.com/static/file.html'); | 251 var uri = Uri.parse('https://test.example.com/static/dir/file.html'); |
199 var request = new Request('GET', uri); | 252 var request = new Request('GET', uri, |
200 var copy = request.change( | 253 handlerPath: '/static/', url: Uri.parse('dir/file.html')); |
201 scriptName: '/dynamic', url: Uri.parse('/other_path/file.html')); | |
202 | 254 |
203 expect(copy.scriptName, '/dynamic'); | 255 expect(() => request.change(path: 'di'), throwsArgumentError); |
204 expect(copy.url, Uri.parse('/other_path/file.html')); | 256 }); |
205 }); | 257 }); |
206 }); | 258 }); |
207 } | 259 } |
OLD | NEW |