diff --git a/packages/dart_frog/lib/src/request.dart b/packages/dart_frog/lib/src/request.dart index 516a5e071..bd180da86 100644 --- a/packages/dart_frog/lib/src/request.dart +++ b/packages/dart_frog/lib/src/request.dart @@ -135,6 +135,12 @@ class Request { ); } + /// Returns the url parameters captured by the [Router]. + /// Returns an empty map if no parameters are captured. + /// + /// The returned map is unmodifiable. + Map get params => _request.params; + /// Returns a [Stream] representing the body. Stream> bytes() => _request.read(); diff --git a/packages/dart_frog/test/src/request_test.dart b/packages/dart_frog/test/src/request_test.dart index 564660fdc..9cb4016da 100644 --- a/packages/dart_frog/test/src/request_test.dart +++ b/packages/dart_frog/test/src/request_test.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:collection'; import 'dart:convert'; import 'dart:io'; @@ -79,6 +80,14 @@ ${HttpMethod.values.map((m) => m.value.toUpperCase()).join(', ')}.'''), expect(request.headers['foo'], equals(headers['foo'])); }); + test('has correct params (empty)', () { + final request = Request('GET', localhost); + expect( + request.params, + equals(UnmodifiableMapView(const {})), + ); + }); + test('body can be read multiple times (sync)', () { final body = json.encode({'test': 'body'}); final request = Request('GET', localhost, body: body); diff --git a/packages/dart_frog/test/src/router_test.dart b/packages/dart_frog/test/src/router_test.dart index c6c1eb467..9c159fa8f 100644 --- a/packages/dart_frog/test/src/router_test.dart +++ b/packages/dart_frog/test/src/router_test.dart @@ -16,6 +16,7 @@ @TestOn('vm') library; +import 'dart:collection'; import 'dart:convert'; import 'dart:io'; @@ -291,10 +292,90 @@ void main() { expect(response.body, equals('hello')); }); + test('request exposes captured params (empty)', () async { + final context = _MockRequestContext(); + final app = Router() + ..get('/hello', (RequestContext context) { + expect( + context.request.params, + equals(UnmodifiableMapView(const {})), + ); + return Response(body: 'hello world'); + }); + + server.mount((request) async { + when(() => context.request).thenReturn( + Request(request.method, request.requestedUri), + ); + final response = await app(context); + final body = await response.body(); + return shelf.Response(response.statusCode, body: body); + }); + + final response = await http.get(Uri.parse('${server.url}/hello')); + expect(response.statusCode, equals(HttpStatus.ok)); + expect(response.body, equals('hello world')); + }); + + test('request exposes captured params (single)', () async { + final context = _MockRequestContext(); + final app = Router() + ..get('/users//greet', (RequestContext context, String id) { + expect( + context.request.params, + equals(UnmodifiableMapView({'id': id})), + ); + return Response(body: 'hello $id'); + }); + + server.mount((request) async { + when(() => context.request).thenReturn( + Request(request.method, request.requestedUri), + ); + final response = await app(context); + final body = await response.body(); + return shelf.Response(response.statusCode, body: body); + }); + + final response = await http.get(Uri.parse('${server.url}/users/42/greet')); + expect(response.statusCode, equals(HttpStatus.ok)); + expect(response.body, equals('hello 42')); + }); + + test('request exposes captured params (multiple)', () async { + final context = _MockRequestContext(); + final app = Router() + ..get('/users//greet/', ( + RequestContext context, + String id, + String name, + ) { + expect( + context.request.params, + equals(UnmodifiableMapView({'id': id, 'name': name})), + ); + return Response(body: 'hello $name ($id)'); + }); + + server.mount((request) async { + when(() => context.request).thenReturn( + Request(request.method, request.requestedUri), + ); + final response = await app(context); + final body = await response.body(); + return shelf.Response(response.statusCode, body: body); + }); + + final response = + await http.get(Uri.parse('${server.url}/users/42/greet/felangel')); + expect(response.statusCode, equals(HttpStatus.ok)); + expect(response.body, equals('hello felangel (42)')); + }); + test('mount(Router)', () async { final context = _MockRequestContext(); final api = Router() - ..all('/user//info', (RequestContext request, String user) { + ..all('/user//info', (RequestContext context, String user) { return Response(body: 'Hello $user'); });