diff --git a/.idea/runConfigurations/Simple_Tests.xml b/.idea/runConfigurations/Simple_Tests.xml new file mode 100644 index 00000000..9f906dc1 --- /dev/null +++ b/.idea/runConfigurations/Simple_Tests.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..de2210c9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1 @@ +language: dart \ No newline at end of file diff --git a/README.md b/README.md index 96d77d61..40e65277 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ # angel_test Testing utility library for the Angel framework. -# Todo -- `ServiceSuite` - -etc. +See the tests for examples. \ No newline at end of file diff --git a/lib/src/client.dart b/lib/src/client.dart index 5dfa49ba..5f270461 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1,18 +1,65 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'package:angel_client/io.dart' as client; -import 'package:angel_framework/angel_framework.dart' as server; +import 'package:angel_framework/angel_framework.dart'; +import 'package:uuid/uuid.dart'; + +final Uuid _uuid = new Uuid(); + +Future connectTo(Angel app, + {Map initialSession, bool saveSession: true}) async { + TestClient client; + var path = '/${_uuid.v1()}/${_uuid.v1()}/${_uuid.v1()}'; + + if (saveSession) { + app + ..get(path, (RequestContext req, res) async { + client._session = req.session; + + if (initialSession != null) { + req.session.addAll(initialSession); + } + }) + ..post(path, (RequestContext req, res) async { + client._session = req.session..addAll(req.body); + }) + ..patch(path, (RequestContext req, res) async { + req.body['keys'].forEach(req.session.remove); + client._session = req.session; + }); + } -Future connectTo(server.Angel app) async { final server = await app.startServer(); - return new _TestClient( - server, 'http://${server.address.address}:${server.port}'); + final url = 'http://${server.address.address}:${server.port}'; + client = new TestClient(server, url); + + if (saveSession) { + await client.client.get('$url$path'); + client._sessionPath = path; + } + + return client; } -class _TestClient extends client.Rest { +/// Interacts with an Angel server. +class TestClient extends client.Rest { final HttpServer server; + HttpSession _session; + String _sessionPath; - _TestClient(this.server, String path) : super(path); + /// Returns a pointer to the current session. + HttpSession get session => _session; + + TestClient(this.server, String path) : super(path); + + /// Adds data to the [session]. + Future addToSession(Map data) => post(_sessionPath, body: data); + + /// Removes data from the [session]. + Future removeFromSession(List keys) => patch(_sessionPath, + body: JSON.encode({'keys': keys}), + headers: {HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType}); @override Future close() async { diff --git a/lib/src/matchers.dart b/lib/src/matchers.dart index fbf7cb9a..837d1b74 100644 --- a/lib/src/matchers.dart +++ b/lib/src/matchers.dart @@ -3,4 +3,38 @@ import 'package:http/http.dart' as http; import 'package:matcher/matcher.dart'; /// Expects a given response, when parsed as JSON, -/// to equal a desired value. \ No newline at end of file +/// to equal a desired value. +Matcher isJson(value) => new _IsJson(value); + +/// Expects a response to have the given status code. +Matcher hasStatus(int status) => new _HasStatus(status); + +class _IsJson extends Matcher { + var value; + + _IsJson(this.value); + + @override + Description describe(Description description) { + return description.add(' should equal the desired JSON response: $value'); + } + + @override + bool matches(http.Response item, Map matchState) => + equals(value).matches(JSON.decode(item.body), matchState); +} + +class _HasStatus extends Matcher { + int status; + + _HasStatus(this.status); + + @override + Description describe(Description description) { + return description.add(' should have statuc code $status'); + } + + @override + bool matches(http.Response item, Map matchState) => + equals(status).matches(item.statusCode, matchState); +} diff --git a/pubspec.yaml b/pubspec.yaml index ae8e556d..8c9ad4ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,6 +8,7 @@ dependencies: angel_framework: "^1.0.0-dev" http: "^0.11.3+9" matcher: "^0.12.0+2" + uuid: "^0.5.3" dev_dependencies: test: "^0.12.17+2" environment: diff --git a/test/simple_test.dart b/test/simple_test.dart index 46bc63bd..e02020b2 100644 --- a/test/simple_test.dart +++ b/test/simple_test.dart @@ -1,17 +1,60 @@ import 'package:angel_framework/angel_framework.dart' as server; -import 'package:angel_client/angel_client.dart' as client; import 'package:angel_test/angel_test.dart'; import 'package:test/test.dart'; main() { server.Angel app; - client.Angel clientApp; + TestClient testClient; setUp(() async { - app.get('/hello', 'Hello'); + app = new server.Angel() + ..get('/hello', 'Hello') + ..post('/hello', (req, res) async { + return {'bar': req.body['foo']}; + }); - clientApp = await connectTo(app); + testClient = await connectTo(app); }); - tearDown(clientApp.close); -} \ No newline at end of file + tearDown(() async { + await testClient.close(); + app = null; + }); + + group('isJson+hasStatus', () { + test('get', () async { + final response = await testClient.get('/hello'); + expect(response, isJson('Hello')); + }); + + test('post', () async { + final response = await testClient.post('/hello', body: {'foo': 'baz'}); + expect(response, allOf(hasStatus(200), isJson({'bar': 'baz'}))); + }); + }); + + group('session', () { + test('initial session', () async { + final TestClient client = + await connectTo(app, initialSession: {'foo': 'bar'}); + expect(client.session['foo'], equals('bar')); + }); + + test('add to session', () async { + final TestClient client = await connectTo(app); + await client.addToSession({'michael': 'jackson'}); + expect(client.session['michael'], equals('jackson')); + }); + + test('remove from session', () async { + final TestClient client = await connectTo(app, initialSession: {'angel': 'framework'}); + await client.removeFromSession(['angel']); + expect(client.session.containsKey('angel'), isFalse); + }); + + test('disable session', () async { + final client = await connectTo(app, saveSession: false); + expect(client.session, isNull); + }); + }); +}