platform/packages/framework/test/controller_test.dart

207 lines
5.9 KiB
Dart
Raw Normal View History

2016-06-27 00:20:42 +00:00
import 'dart:async';
import 'dart:convert';
2016-06-27 00:20:42 +00:00
import 'dart:io';
2018-08-20 03:06:29 +00:00
2021-05-14 10:34:09 +00:00
import 'package:angel3_container/mirrors.dart';
import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';
2016-06-27 00:20:42 +00:00
import 'package:http/http.dart' as http;
2021-05-14 10:34:09 +00:00
import 'package:angel3_mock_request/angel3_mock_request.dart';
2016-06-27 00:20:42 +00:00
import 'package:test/test.dart';
2018-08-20 03:06:29 +00:00
2016-06-27 00:20:42 +00:00
import 'common.dart';
2021-07-08 02:42:40 +00:00
@Expose('/todos', middleware: [foo])
2016-06-27 00:20:42 +00:00
class TodoController extends Controller {
2021-07-08 02:42:40 +00:00
List<Todo> todos = [Todo(text: 'Hello', over: 'world')];
2016-06-27 00:20:42 +00:00
2021-07-08 02:42:40 +00:00
@Expose('/:id', middleware: [bar])
2016-11-23 09:10:47 +00:00
Future<Todo> fetchTodo(
2016-11-28 00:49:27 +00:00
String id, RequestContext req, ResponseContext res) async {
2016-06-27 00:20:42 +00:00
expect(req, isNotNull);
expect(res, isNotNull);
2016-11-28 00:49:27 +00:00
return todos[int.parse(id)];
2016-06-27 00:20:42 +00:00
}
2021-07-08 02:42:40 +00:00
@Expose('/namedRoute/:foo', as: 'foo')
2016-11-23 09:10:47 +00:00
Future<String> someRandomRoute(
RequestContext req, ResponseContext res) async {
2016-06-27 00:20:42 +00:00
return "${req.params['foo']}!";
}
}
2019-10-12 14:56:24 +00:00
class NoExposeController extends Controller {
String getIndex() => 'Hey!';
int timesTwo(int n) => n * 2;
String repeatName(String name, int times) {
var b = StringBuffer();
2021-07-08 02:42:40 +00:00
for (var i = 0; i < times; i++) {
2019-10-12 14:56:24 +00:00
b.writeln(name);
}
return b.toString();
}
@Expose('/yellow', method: 'POST')
String someColor() => 'yellow';
@Expose.patch
int three() => 333;
@noExpose
String hideThis() => 'Should not be exposed';
}
2017-06-29 22:17:42 +00:00
@Expose('/named', as: 'foo')
class NamedController extends Controller {
2019-05-02 22:48:31 +00:00
@Expose('/optional/:arg?', allowNull: ['arg'])
2021-07-08 02:42:40 +00:00
int optional() => 2;
2017-06-29 22:17:42 +00:00
}
2018-11-11 01:07:09 +00:00
bool foo(RequestContext req, ResponseContext res) {
2021-07-08 02:42:40 +00:00
res.write('Hello, ');
2018-11-11 01:07:09 +00:00
return true;
}
2018-11-11 01:07:09 +00:00
bool bar(RequestContext req, ResponseContext res) {
2021-07-08 02:42:40 +00:00
res.write('world!');
2018-11-11 01:07:09 +00:00
return true;
}
2021-07-08 02:42:40 +00:00
void main() {
2021-04-03 05:50:52 +00:00
late Angel app;
2021-03-20 08:11:18 +00:00
late TodoController todoController;
late NoExposeController noExposeCtrl;
late HttpServer server;
2021-07-08 02:42:40 +00:00
var client = http.Client();
2021-03-20 08:11:18 +00:00
String? url;
2016-06-27 00:20:42 +00:00
setUp(() async {
2019-05-02 22:48:31 +00:00
app = Angel(reflector: MirrorsReflector());
2021-04-03 05:50:52 +00:00
app.get(
2021-07-08 02:42:40 +00:00
'/redirect',
(req, res) async =>
2021-07-08 02:42:40 +00:00
res.redirectToAction('TodoController@foo', {'foo': 'world'}));
2018-11-08 02:50:04 +00:00
// Register as a singleton, just for the purpose of this test
2021-04-03 05:50:52 +00:00
if (!app.container!.has<TodoController>()) {
app.container!.registerSingleton(todoController = TodoController());
2019-05-31 03:49:00 +00:00
}
2018-11-08 02:50:04 +00:00
// Using mountController<T>();
2021-04-03 05:50:52 +00:00
await app.mountController<TodoController>();
2016-06-27 00:20:42 +00:00
2021-04-03 05:50:52 +00:00
noExposeCtrl = await app.mountController<NoExposeController>();
2019-10-12 14:56:24 +00:00
// Place controller in group. The applyRoutes() call, however, is async.
// Until https://github.com/angel-dart/route/issues/28 is closed,
// this will need to be done by manually mounting the router.
var subRouter = Router<RequestHandler>();
2021-04-03 05:50:52 +00:00
await todoController.applyRoutes(subRouter, app.container!.reflector);
app.mount('/ctrl_group', subRouter);
2019-05-31 20:24:13 +00:00
2021-04-03 05:50:52 +00:00
print(app.controllers);
app.dumpTree();
2016-06-27 00:20:42 +00:00
2019-05-02 22:48:31 +00:00
server = await AngelHttp(app).startServer();
2016-11-24 07:12:53 +00:00
url = 'http://${server.address.address}:${server.port}';
});
2016-06-27 00:20:42 +00:00
tearDown(() async {
2016-11-23 09:10:47 +00:00
await server.close(force: true);
2016-11-24 07:12:53 +00:00
url = null;
});
2016-06-27 00:20:42 +00:00
2017-06-29 22:17:42 +00:00
test('basic', () {
expect(todoController.app, app);
2017-06-29 22:17:42 +00:00
});
test('create dynamic handler', () async {
2019-05-02 22:48:31 +00:00
var app = Angel(reflector: MirrorsReflector());
2017-09-22 14:03:23 +00:00
app.get(
'/foo',
2021-03-20 08:11:18 +00:00
ioc(({String? bar}) {
2017-09-22 14:03:23 +00:00
return 2;
}, optional: ['bar']));
2019-05-02 22:48:31 +00:00
var rq = MockHttpRequest('GET', Uri(path: 'foo'));
await AngelHttp(app).handleRequest(rq);
2019-09-29 05:38:22 +00:00
var body = await utf8.decoder.bind(rq.response).join();
2018-05-16 02:05:13 +00:00
expect(json.decode(body), 2);
2017-06-29 22:17:42 +00:00
});
test('optional name', () async {
2019-05-02 22:48:31 +00:00
var app = Angel(reflector: MirrorsReflector());
await app.configure(NamedController().configureServer);
expect(app.controllers['foo'], const IsInstanceOf<NamedController>());
2017-06-29 22:17:42 +00:00
});
2021-07-08 02:42:40 +00:00
test('middleware', () async {
var rgx = RegExp('^Hello, world!');
var response = await client.get(Uri.parse('$url/todos/0'));
2016-11-28 00:49:27 +00:00
print('Response: ${response.body}');
2016-06-27 00:20:42 +00:00
2017-11-18 17:42:31 +00:00
expect(rgx.firstMatch(response.body)?.start, equals(0));
2021-07-08 02:42:40 +00:00
var todo = json.decode(response.body.replaceAll(rgx, '')) as Map;
print('Todo: $todo');
expect(todo['text'], equals('Hello'));
expect(todo['over'], equals('world'));
});
2016-06-27 00:20:42 +00:00
2021-07-08 02:42:40 +00:00
test('controller in group', () async {
var rgx = RegExp('^Hello, world!');
var response = await client.get(Uri.parse('$url/ctrl_group/todos/0'));
2019-05-31 20:24:13 +00:00
print('Response: ${response.body}');
expect(rgx.firstMatch(response.body)?.start, equals(0));
2021-07-08 02:42:40 +00:00
var todo = json.decode(response.body.replaceAll(rgx, '')) as Map;
print('Todo: $todo');
expect(todo['text'], equals('Hello'));
expect(todo['over'], equals('world'));
2019-05-31 20:24:13 +00:00
});
2021-07-08 02:42:40 +00:00
test('named actions', () async {
var response = await client.get(Uri.parse('$url/redirect'));
2016-11-28 00:49:27 +00:00
print('Response: ${response.body}');
2021-07-08 02:42:40 +00:00
expect(response.body, equals('Hello, \"world!\"'));
2016-06-27 00:20:42 +00:00
});
2019-10-12 14:56:24 +00:00
group('optional expose', () {
test('removes suffixes from controller names', () {
2021-03-20 08:11:18 +00:00
expect(noExposeCtrl.mountPoint!.path, 'no_expose');
2019-10-12 14:56:24 +00:00
});
test('mounts correct routes', () {
print(noExposeCtrl.routeMappings.keys);
expect(noExposeCtrl.routeMappings.keys.toList(),
['getIndex', 'timesTwo', 'repeatName', 'someColor', 'three']);
});
test('mounts correct methods', () {
void expectMethod(String name, String method) {
2021-03-20 08:11:18 +00:00
expect(noExposeCtrl.routeMappings[name]!.method, method);
2019-10-12 14:56:24 +00:00
}
expectMethod('getIndex', 'GET');
expectMethod('timesTwo', 'GET');
expectMethod('repeatName', 'GET');
expectMethod('someColor', 'POST');
expectMethod('three', 'PATCH');
});
test('mounts correct paths', () {
void expectPath(String name, String path) {
2021-03-20 08:11:18 +00:00
expect(noExposeCtrl.routeMappings[name]!.path, path);
2019-10-12 14:56:24 +00:00
}
expectPath('getIndex', '/');
expectPath('timesTwo', '/times_two/int:n');
expectPath('repeatName', '/repeat_name/:name/int:times');
expectPath('someColor', '/yellow');
expectPath('three', '/three');
});
});
2016-06-27 00:20:42 +00:00
}