Body parsing tests; allow setting body ONCE
This commit is contained in:
parent
28f020f1e9
commit
efbb09169a
3 changed files with 125 additions and 0 deletions
|
@ -3,6 +3,7 @@
|
|||
* Add `AngelEnvironment` class.
|
||||
* Add `Angel.environment`.
|
||||
* Deprecated `app.isProduction` in favor of `app.environment.isProduction`.
|
||||
* Allow setting of `bodyAsObject`, `bodyAsMap`, or `bodyAsList` **exactly once**.
|
||||
|
||||
# 2.0.0-alpha.24
|
||||
* Add `AngelEnv` class to `core`.
|
||||
|
|
|
@ -113,6 +113,11 @@ abstract class RequestContext<RawRequest> {
|
|||
return _bodyFields;
|
||||
}
|
||||
|
||||
/// This setter allows you to explicitly set the request body **exactly once**.
|
||||
///
|
||||
/// Use this if the format of the body is not natively parsed by Angel.
|
||||
set bodyAsMap(Map<String, dynamic> value) => bodyAsObject = value;
|
||||
|
||||
/// Returns a *mutable* [List] parsed from the request [body].
|
||||
///
|
||||
/// Note that [parseBody] must be called first.
|
||||
|
@ -126,6 +131,11 @@ abstract class RequestContext<RawRequest> {
|
|||
return _bodyList;
|
||||
}
|
||||
|
||||
/// This setter allows you to explicitly set the request body **exactly once**.
|
||||
///
|
||||
/// Use this if the format of the body is not natively parsed by Angel.
|
||||
set bodyAsList(List value) => bodyAsObject = value;
|
||||
|
||||
/// Returns the parsed request body, whatever it may be (typically a [Map] or [List]).
|
||||
///
|
||||
/// Note that [parseBody] must be called first.
|
||||
|
@ -137,6 +147,21 @@ abstract class RequestContext<RawRequest> {
|
|||
return _bodyObject;
|
||||
}
|
||||
|
||||
/// This setter allows you to explicitly set the request body **exactly once**.
|
||||
///
|
||||
/// Use this if the format of the body is not natively parsed by Angel.
|
||||
set bodyAsObject(value) {
|
||||
if (_bodyObject != null) {
|
||||
throw StateError(
|
||||
'The request body has already been parsed/set, and cannot be overwritten.');
|
||||
} else {
|
||||
if (value is List) _bodyList = value;
|
||||
if (value is Map<String, dynamic>) _bodyFields = value;
|
||||
_bodyObject = value;
|
||||
_hasParsedBody = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a *mutable* map of the files parsed from the request [body].
|
||||
///
|
||||
/// Note that [parseBody] must be called first.
|
||||
|
|
99
test/body_test.dart
Normal file
99
test/body_test.dart
Normal file
|
@ -0,0 +1,99 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_framework/http.dart';
|
||||
import 'package:mock_request/mock_request.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
var app = Angel();
|
||||
var http = AngelHttp(app);
|
||||
|
||||
Future<RequestContext> request(
|
||||
{bool asJson: true,
|
||||
bool parse: true,
|
||||
Map<String, dynamic> bodyFields,
|
||||
List bodyList}) async {
|
||||
var rq = MockHttpRequest('POST', Uri(path: '/'));
|
||||
|
||||
if (bodyFields != null) {
|
||||
if (asJson) {
|
||||
rq
|
||||
..headers.contentType = ContentType('application', 'json')
|
||||
..write(json.encode(bodyFields));
|
||||
} else {
|
||||
var b = StringBuffer();
|
||||
var i = 0;
|
||||
for (var entry in bodyFields.entries) {
|
||||
if (i++ > 0) b.write('&');
|
||||
b.write(entry.key);
|
||||
b.write('=');
|
||||
b.write(Uri.encodeComponent(entry.value.toString()));
|
||||
}
|
||||
|
||||
rq
|
||||
..headers.contentType =
|
||||
ContentType('application', 'x-www-form-urlencoded')
|
||||
..write(json.encode(b.toString()));
|
||||
}
|
||||
} else if (bodyList != null) {
|
||||
rq
|
||||
..headers.contentType = ContentType('application', 'json')
|
||||
..write(json.encode(bodyList));
|
||||
}
|
||||
|
||||
await rq.close();
|
||||
var req = await http.createRequestContext(rq, rq.response);
|
||||
if (parse) await req.parseBody();
|
||||
return req;
|
||||
}
|
||||
|
||||
test('parses json maps', () async {
|
||||
var req = await request(bodyFields: {'hello': 'world'});
|
||||
expect(req.bodyAsObject, TypeMatcher<Map<String, dynamic>>());
|
||||
expect(req.bodyAsMap, {'hello': 'world'});
|
||||
});
|
||||
|
||||
test('parses json lists', () async {
|
||||
var req = await request(bodyList: ['foo', 'bar']);
|
||||
expect(req.bodyAsObject, TypeMatcher<List>());
|
||||
expect(req.bodyAsList, ['foo', 'bar']);
|
||||
});
|
||||
|
||||
test('throws when body has not been parsed', () async {
|
||||
var req = await request(parse: false);
|
||||
expect(() => req.bodyAsObject, throwsStateError);
|
||||
expect(() => req.bodyAsMap, throwsStateError);
|
||||
expect(() => req.bodyAsList, throwsStateError);
|
||||
});
|
||||
|
||||
test('can set body object exactly once', () async {
|
||||
var req = await request(parse: false);
|
||||
req.bodyAsObject = 23;
|
||||
expect(req.bodyAsObject, 23);
|
||||
expect(() => req.bodyAsObject = {45.6: '34'}, throwsStateError);
|
||||
});
|
||||
|
||||
test('can set body map exactly once', () async {
|
||||
var req = await request(parse: false);
|
||||
req.bodyAsMap = {'hey': 'yes'};
|
||||
expect(req.bodyAsMap, {'hey': 'yes'});
|
||||
expect(() => req.bodyAsMap = {'hm': 'ok'}, throwsStateError);
|
||||
});
|
||||
|
||||
test('can set body list exactly once', () async {
|
||||
var req = await request(parse: false);
|
||||
req.bodyAsList = [
|
||||
{'hey': 'yes'}
|
||||
];
|
||||
expect(req.bodyAsList, [
|
||||
{'hey': 'yes'}
|
||||
]);
|
||||
expect(
|
||||
() => req.bodyAsList = [
|
||||
{'hm': 'ok'}
|
||||
],
|
||||
throwsStateError);
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue