2018-07-09 15:02:00 +00:00
|
|
|
import 'dart:io';
|
2018-08-19 15:33:25 +00:00
|
|
|
import 'package:angel_container/mirrors.dart';
|
2016-04-18 03:27:23 +00:00
|
|
|
import 'package:angel_framework/angel_framework.dart';
|
2018-08-20 03:06:29 +00:00
|
|
|
import 'dart:convert';
|
2016-04-18 03:27:23 +00:00
|
|
|
import 'package:http/http.dart' as http;
|
2018-07-09 15:02:00 +00:00
|
|
|
import 'package:io/ansi.dart';
|
|
|
|
import 'package:logging/logging.dart';
|
2016-04-18 03:27:23 +00:00
|
|
|
import 'package:test/test.dart';
|
2018-07-09 14:28:32 +00:00
|
|
|
import 'common.dart';
|
2016-04-18 03:27:23 +00:00
|
|
|
|
2016-05-02 22:28:14 +00:00
|
|
|
@Middleware(const ['interceptor'])
|
|
|
|
testMiddlewareMetadata(RequestContext req, ResponseContext res) async {
|
|
|
|
return "This should not be shown.";
|
|
|
|
}
|
|
|
|
|
2016-06-23 19:09:49 +00:00
|
|
|
@Middleware(const ['intercept_service'])
|
2016-06-23 19:05:55 +00:00
|
|
|
class QueryService extends Service {
|
|
|
|
@override
|
2016-06-23 19:09:49 +00:00
|
|
|
@Middleware(const ['interceptor'])
|
2017-08-03 16:40:21 +00:00
|
|
|
read(id, [Map params]) async => params;
|
2016-06-23 19:05:55 +00:00
|
|
|
}
|
|
|
|
|
2016-04-18 03:27:23 +00:00
|
|
|
main() {
|
2016-11-28 00:49:27 +00:00
|
|
|
Angel app;
|
2016-09-15 19:53:01 +00:00
|
|
|
Angel nested;
|
|
|
|
Angel todos;
|
|
|
|
String url;
|
|
|
|
http.Client client;
|
|
|
|
|
|
|
|
setUp(() async {
|
2018-08-20 02:40:11 +00:00
|
|
|
app = new Angel(reflector: MirrorsReflector());
|
|
|
|
nested = new Angel(reflector: MirrorsReflector());
|
|
|
|
todos = new Angel(reflector: MirrorsReflector());
|
2016-10-22 20:41:36 +00:00
|
|
|
|
2017-04-01 01:00:24 +00:00
|
|
|
[app, nested, todos].forEach((Angel app) {
|
2018-07-09 15:02:00 +00:00
|
|
|
app.logger = new Logger('routing_test')
|
|
|
|
..onRecord.listen((rec) {
|
|
|
|
if (rec.error != null) {
|
|
|
|
stdout
|
|
|
|
..writeln(cyan.wrap(rec.toString()))
|
|
|
|
..writeln(cyan.wrap(rec.error.toString()))
|
|
|
|
..writeln(cyan.wrap(rec.stackTrace.toString()));
|
|
|
|
}
|
|
|
|
});
|
2017-04-01 01:00:24 +00:00
|
|
|
});
|
|
|
|
|
2017-10-04 14:09:12 +00:00
|
|
|
app.requestMiddleware
|
|
|
|
..['interceptor'] = (req, res) async {
|
2016-10-22 20:41:36 +00:00
|
|
|
res.write('Middleware');
|
|
|
|
return false;
|
2017-10-04 14:09:12 +00:00
|
|
|
}
|
|
|
|
..['intercept_service'] = (RequestContext req, res) async {
|
2016-11-23 09:10:47 +00:00
|
|
|
res.write("Service with ");
|
2016-10-22 20:41:36 +00:00
|
|
|
return true;
|
2017-10-04 14:09:12 +00:00
|
|
|
};
|
2016-04-18 03:27:23 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
todos.get('/action/:action', (req, res) => res.json(req.params));
|
2016-10-22 20:41:36 +00:00
|
|
|
|
|
|
|
Route ted;
|
|
|
|
|
|
|
|
ted = nested.post('/ted/:route', (RequestContext req, res) {
|
|
|
|
print('Params: ${req.params}');
|
2017-11-28 18:14:50 +00:00
|
|
|
print('Path: ${ted.path}, uri: ${req.path}');
|
|
|
|
print('matcher: ${ted.parser}');
|
2016-10-22 20:41:36 +00:00
|
|
|
return req.params;
|
|
|
|
});
|
|
|
|
|
2016-11-28 00:49:27 +00:00
|
|
|
app.use('/nes', nested);
|
|
|
|
app.get('/meta', testMiddlewareMetadata);
|
|
|
|
app.get('/intercepted', 'This should not be shown',
|
2016-09-15 19:53:01 +00:00
|
|
|
middleware: ['interceptor']);
|
2016-11-28 00:49:27 +00:00
|
|
|
app.get('/hello', 'world');
|
|
|
|
app.get('/name/:first/last/:last', (req, res) => req.params);
|
2018-08-20 03:51:09 +00:00
|
|
|
app.post('/lambda', (RequestContext req, res) => req.parseBody());
|
2016-11-28 00:49:27 +00:00
|
|
|
app.use('/todos/:id', todos);
|
|
|
|
app
|
2016-09-15 19:53:01 +00:00
|
|
|
.get('/greet/:name',
|
2016-10-22 20:41:36 +00:00
|
|
|
(RequestContext req, res) async => "Hello ${req.params['name']}")
|
2017-11-28 18:14:50 +00:00
|
|
|
.name = 'Named routes';
|
2016-11-28 00:49:27 +00:00
|
|
|
app.get('/named', (req, ResponseContext res) async {
|
2016-09-15 19:53:01 +00:00
|
|
|
res.redirectTo('Named routes', {'name': 'tests'});
|
2016-04-18 03:27:23 +00:00
|
|
|
});
|
2016-11-28 00:49:27 +00:00
|
|
|
app.get('/log', (RequestContext req, res) async {
|
2016-09-15 19:53:01 +00:00
|
|
|
print("Query: ${req.query}");
|
|
|
|
return "Logged";
|
2016-04-18 03:27:23 +00:00
|
|
|
});
|
2016-10-22 20:41:36 +00:00
|
|
|
|
2017-10-04 14:09:12 +00:00
|
|
|
app.get('/method', () => 'Only GET');
|
|
|
|
app.post('/method', () => 'Only POST');
|
|
|
|
|
2016-11-28 00:49:27 +00:00
|
|
|
app.use('/query', new QueryService());
|
2017-10-04 14:09:12 +00:00
|
|
|
|
2017-10-10 16:55:42 +00:00
|
|
|
RequestMiddleware write(String message) {
|
|
|
|
return (req, res) async {
|
|
|
|
res.write(message);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-11-28 18:14:50 +00:00
|
|
|
app
|
|
|
|
.chain(write('a'))
|
|
|
|
.chain([write('b'), write('c')]).get('/chained', () => false);
|
2017-10-10 16:55:42 +00:00
|
|
|
|
2017-10-04 14:09:12 +00:00
|
|
|
app.use('MJ');
|
2016-04-18 03:27:23 +00:00
|
|
|
|
2016-11-28 00:49:27 +00:00
|
|
|
app.dumpTree(header: "DUMPING ROUTES:", showMatchers: true);
|
2016-04-18 03:27:23 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
client = new http.Client();
|
2018-06-23 03:59:41 +00:00
|
|
|
var server = await new AngelHttp(app).startServer('127.0.0.1', 0);
|
2018-02-07 05:36:24 +00:00
|
|
|
url = "http://${server.address.host}:${server.port}";
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
2016-04-18 03:27:23 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
tearDown(() async {
|
2018-02-07 04:34:08 +00:00
|
|
|
await app.close();
|
2016-11-28 00:49:27 +00:00
|
|
|
app = null;
|
2016-09-15 19:53:01 +00:00
|
|
|
nested = null;
|
|
|
|
todos = null;
|
|
|
|
client.close();
|
|
|
|
client = null;
|
|
|
|
url = null;
|
|
|
|
});
|
2016-04-21 20:37:02 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Can match basic url', () async {
|
|
|
|
var response = await client.get("$url/hello");
|
|
|
|
expect(response.body, equals('"world"'));
|
|
|
|
});
|
2016-04-21 20:37:02 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Can match url with multiple parameters', () async {
|
|
|
|
var response = await client.get('$url/name/HELLO/last/WORLD');
|
2016-11-28 00:49:27 +00:00
|
|
|
print('Response: ${response.body}');
|
2018-06-08 07:06:26 +00:00
|
|
|
var json_ = json.decode(response.body);
|
2018-07-09 14:28:32 +00:00
|
|
|
expect(json_, const IsInstanceOf<Map>());
|
2018-06-08 07:06:26 +00:00
|
|
|
expect(json_['first'], equals('HELLO'));
|
|
|
|
expect(json_['last'], equals('WORLD'));
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
2016-05-02 22:28:14 +00:00
|
|
|
|
2017-10-10 16:55:42 +00:00
|
|
|
test('Chained routes', () async {
|
|
|
|
var response = await client.get("$url/chained");
|
|
|
|
expect(response.body, equals('abc'));
|
|
|
|
});
|
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Can nest another Angel instance', () async {
|
|
|
|
var response = await client.post('$url/nes/ted/foo');
|
2018-06-08 07:06:26 +00:00
|
|
|
var json_ = json.decode(response.body);
|
|
|
|
expect(json_['route'], equals('foo'));
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
Angel.secure, fallback routes, 404, app.addRoute, app.all, services are a go (just missing params, i.e. $sort?), now have service.app, app.before, app.after, angel.configure now uses futures, errors are implemented
2016-04-29 00:01:58 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Can parse parameters from a nested Angel instance', () async {
|
|
|
|
var response = await client.get('$url/todos/1337/action/test');
|
2018-06-08 07:06:26 +00:00
|
|
|
var json_ = json.decode(response.body);
|
|
|
|
print('JSON: $json_');
|
|
|
|
expect(json_['id'], equals('1337'));
|
|
|
|
expect(json_['action'], equals('test'));
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
2016-05-02 22:28:14 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Can add and use named middleware', () async {
|
|
|
|
var response = await client.get('$url/intercepted');
|
|
|
|
expect(response.body, equals('Middleware'));
|
|
|
|
});
|
2016-05-02 22:28:14 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Middleware via metadata', () async {
|
|
|
|
// Metadata
|
|
|
|
var response = await client.get('$url/meta');
|
|
|
|
expect(response.body, equals('Middleware'));
|
|
|
|
});
|
2016-06-23 19:05:55 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Can serialize function result as JSON', () async {
|
2018-07-09 14:54:50 +00:00
|
|
|
Map headers = <String, String>{'Content-Type': 'application/json'};
|
2018-06-08 07:06:26 +00:00
|
|
|
String postData = json.encode({'it': 'works'});
|
2018-06-23 03:59:41 +00:00
|
|
|
var response = await client.post("$url/lambda",
|
2018-06-27 18:40:43 +00:00
|
|
|
headers: headers as Map<String, String>, body: postData);
|
2018-06-08 07:06:26 +00:00
|
|
|
print('Response: ${response.body}');
|
|
|
|
expect(json.decode(response.body)['it'], equals('works'));
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
2016-06-23 19:05:55 +00:00
|
|
|
|
2016-09-15 19:53:01 +00:00
|
|
|
test('Fallback routes', () async {
|
|
|
|
var response = await client.get('$url/my_favorite_artist');
|
|
|
|
expect(response.body, equals('"MJ"'));
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Can name routes', () {
|
2017-11-28 18:14:50 +00:00
|
|
|
Route foo = app.get('/framework/:id', [])..name = 'frm';
|
2016-10-22 20:41:36 +00:00
|
|
|
print('Foo: $foo');
|
2016-09-15 19:53:01 +00:00
|
|
|
String uri = foo.makeUri({'id': 'angel'});
|
|
|
|
print(uri);
|
2016-10-22 20:41:36 +00:00
|
|
|
expect(uri, equals('framework/angel'));
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('Redirect to named routes', () async {
|
|
|
|
var response = await client.get('$url/named');
|
|
|
|
print(response.body);
|
2018-06-08 07:06:26 +00:00
|
|
|
expect(json.decode(response.body), equals('Hello tests'));
|
2016-09-15 19:53:01 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('Match routes, even with query params', () async {
|
|
|
|
var response =
|
2016-10-22 20:41:36 +00:00
|
|
|
await client.get("$url/log?foo=bar&bar=baz&baz.foo=bar&baz.bar=foo");
|
2016-09-15 19:53:01 +00:00
|
|
|
print(response.body);
|
2018-06-08 07:06:26 +00:00
|
|
|
expect(json.decode(response.body), equals('Logged'));
|
2016-09-15 19:53:01 +00:00
|
|
|
|
|
|
|
response = await client.get("$url/query/foo?bar=baz");
|
|
|
|
print(response.body);
|
2016-11-23 09:10:47 +00:00
|
|
|
expect(response.body, equals("Service with Middleware"));
|
2016-04-18 03:27:23 +00:00
|
|
|
});
|
2017-10-04 14:09:12 +00:00
|
|
|
|
|
|
|
test('only match route with matching method', () async {
|
|
|
|
var response = await client.get("$url/method");
|
|
|
|
print(response.body);
|
|
|
|
expect(response.body, '"Only GET"');
|
|
|
|
|
|
|
|
response = await client.post("$url/method");
|
|
|
|
print(response.body);
|
|
|
|
expect(response.body, '"Only POST"');
|
|
|
|
|
|
|
|
response = await client.patch("$url/method");
|
|
|
|
print(response.body);
|
|
|
|
expect(response.body, '"MJ"');
|
|
|
|
});
|
2016-06-23 19:05:55 +00:00
|
|
|
}
|