From 5f5c00352ceb4d5f60f2e864997853fd38c8fef1 Mon Sep 17 00:00:00 2001 From: thosakwe Date: Sun, 12 Feb 2017 20:38:24 -0500 Subject: [PATCH] Broken --- .idea/angel_mongo.iml | 18 ++++ .idea/modules.xml | 8 ++ README.md | 6 +- lib/angel_mongo.dart | 1 - lib/model.dart | 3 +- lib/mongo_service.dart | 40 ++++---- lib/mongo_service_typed.dart | 154 +++++++------------------------ lib/mongo_service_typed.old.dart | 145 +++++++++++++++++++++++++++++ lib/services.dart | 53 ++++++++--- pubspec.yaml | 2 +- test/generic_test.dart | 39 ++++---- test/typed_test.dart | 65 +++++++------ 12 files changed, 331 insertions(+), 203 deletions(-) create mode 100644 .idea/angel_mongo.iml create mode 100644 .idea/modules.xml create mode 100644 lib/mongo_service_typed.old.dart diff --git a/.idea/angel_mongo.iml b/.idea/angel_mongo.iml new file mode 100644 index 00000000..a928d34a --- /dev/null +++ b/.idea/angel_mongo.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..571c4566 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index d771798a..3fc5f217 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,7 @@ You can query these services as follows: /path/to/service?foo=bar -The above will query the database to find records where 'foo' equals 'bar'. Thanks to body_parser, this -also works with numbers, and even Maps. - - /path/to/service?$sort=createdAt - /path/to/service?$sort.createdAt=1 +The above will query the database to find records where 'foo' equals 'bar'. The former will sort result in ascending order of creation, and so will the latter. diff --git a/lib/angel_mongo.dart b/lib/angel_mongo.dart index 654e4b6d..91f85241 100644 --- a/lib/angel_mongo.dart +++ b/lib/angel_mongo.dart @@ -1,4 +1,3 @@ library angel_mongo; -export 'model.dart'; export 'services.dart'; \ No newline at end of file diff --git a/lib/model.dart b/lib/model.dart index cf2d5152..84c81e6a 100644 --- a/lib/model.dart +++ b/lib/model.dart @@ -1,6 +1,7 @@ library angel_mongo.model; -/// A data type that can be serialized to MongoDB. +/// Use the `Model` class defined in `package:angel_framework/common.dart` instead. +@deprecated class Model { /// This instance's ID. String id; diff --git a/lib/mongo_service.dart b/lib/mongo_service.dart index fb9f4520..c836cf40 100644 --- a/lib/mongo_service.dart +++ b/lib/mongo_service.dart @@ -3,23 +3,26 @@ part of angel_mongo.services; /// Manipulates data from MongoDB as Maps. class MongoService extends Service { DbCollection collection; - bool debug; + final bool debug; MongoService(DbCollection this.collection, {this.debug: true}) : super(); _jsonify(Map doc, [Map params]) { Map result = {}; + for (var key in doc.keys) { - if (doc[key] is ObjectId) { - result[key] = doc[key].toHexString(); - } else - result[key] = doc[key]; + var value = doc[key]; + if (value is ObjectId) { + result[key] = value.toHexString(); + } else if (value is! RequestContext && value is! ResponseContext) { + result[key] = value; + } } return _transformId(result); } - void log(e, st, msg) { + void printDebug(e, st, msg) { if (debug) { stderr.writeln('$msg ERROR: $e'); stderr.writeln(st); @@ -34,7 +37,7 @@ class MongoService extends Service { } @override - Future create(Map data, [Map params]) async { + Future create(data, [Map params]) async { Map item = (data is Map) ? data : god.serializeObject(data); item = _removeSensitive(item); @@ -43,7 +46,7 @@ class MongoService extends Service { await collection.insert(item); return await _lastItem(collection, _jsonify, params); } catch (e, st) { - log(e, st, 'CREATE'); + printDebug(e, st, 'CREATE'); throw new AngelHttpException(e, stackTrace: st); } } @@ -54,7 +57,7 @@ class MongoService extends Service { Map found = await collection.findOne(where.id(_id).and(_makeQuery(params))); if (found == null) { - throw new AngelHttpException.NotFound( + throw new AngelHttpException.notFound( message: 'No record found for ID ${_id.toHexString()}'); } @@ -62,9 +65,12 @@ class MongoService extends Service { } @override - Future modify(id, Map data, [Map params]) async { - Map target = await read(id, params); - Map result = mergeMap([target, _removeSensitive(data)]); + Future modify(id, data, [Map params]) async { + var target = await read(id, params); + Map result = mergeMap([ + target is Map ? target : god.serializeObject(target), + _removeSensitive(data) + ]); result['updatedAt'] = new DateTime.now(); try { @@ -73,17 +79,17 @@ class MongoService extends Service { result['id'] = id; return result; } catch (e, st) { - log(e, st, 'MODIFY'); + printDebug(e, st, 'MODIFY'); throw new AngelHttpException(e, stackTrace: st); } } @override Future update(id, data, [Map params]) async { - Map target = await read(id, params); + var target = await read(id, params); Map result = _removeSensitive(data); result['_id'] = _makeId(id); - result['createdAt'] = target['createdAt']; + result['createdAt'] = target is Map ? ['createdAt'] : target.createdAt; result['updatedAt'] = new DateTime.now(); try { @@ -92,7 +98,7 @@ class MongoService extends Service { result['id'] = id; return result; } catch (e, st) { - log(e, st, 'UPDATE'); + printDebug(e, st, 'UPDATE'); throw new AngelHttpException(e, stackTrace: st); } } @@ -105,7 +111,7 @@ class MongoService extends Service { await collection.remove(where.id(_makeId(id)).and(_makeQuery(params))); return result; } catch (e, st) { - log(e, st, 'REMOVE'); + printDebug(e, st, 'REMOVE'); throw new AngelHttpException(e, stackTrace: st); } } diff --git a/lib/mongo_service_typed.dart b/lib/mongo_service_typed.dart index bb1e7812..09b232fe 100644 --- a/lib/mongo_service_typed.dart +++ b/lib/mongo_service_typed.dart @@ -1,145 +1,61 @@ part of angel_mongo.services; -/// Manipulates data from MongoDB by serializing BSON from and deserializing BSON to a target class. -class MongoTypedService extends Service { - DbCollection collection; - bool debug; - - MongoTypedService(DbCollection this.collection, {this.debug: true}) : super() { +class MongoTypedService extends MongoService { + MongoTypedService(DbCollection collection, {bool debug}) + : super(collection, debug: debug == true) { if (!reflectType(T).isAssignableTo(reflectType(Model))) throw new Exception( - "If you specify a type for MongoService, it must be dynamic, Map, or extend from Model."); + "If you specify a type for MongoService, it must extend Model."); } - _jsonify(Map doc, [Map params]) { - Map result = {}; - for (var key in doc.keys) { - if (doc[key] is ObjectId) { - result[key] = doc[key].toHexString(); - } else - result[key] = doc[key]; - } + _deserialize(x) { + if (x == dynamic || x == Object || x is T) + return x; + else if (x is Map) { + Map data = x.keys.fold({}, (map, key) { + var value = x[key]; - result = _transformId(result); + if ((key == 'createdAt' || key == 'updatedAt') && value is String) { + return map..[key] = '44'; // DateTime.parse(value).toIso8601String(); + } else + return map..[key] = value; + }); - // Clients will always receive JSON. - if ((params != null && params['provider'] != null)) { - return result; - } else { - // However, when we run server-side, we should return a T, not a Map. - Model typedResult = god.deserializeDatum(result, outputType: T); - typedResult.createdAt = result['createdAt']; - typedResult.updatedAt = result['updatedAt']; - return typedResult; - } + print('x: $x\ndata: $data'); + return god.deserializeDatum(data, outputType: T); + } else + return x; } - void log(e, st, msg) { - if (debug) { - stderr.writeln('$msg ERROR: $e'); - stderr.writeln(st); - } + _serialize(x) { + if (x is Model) + return god.serializeObject(x); + else + return x; } @override Future index([Map params]) async { - return await (await collection.find(_makeQuery(params))) - .map((x) => _jsonify(x, params)) - .toList(); + var result = await super.index(params); + return result.map(_deserialize).toList(); } @override - Future create(data, [Map params]) async { - Map item; - - try { - Model target = - (data is T) ? data : god.deserializeDatum(data, outputType: T); - item = god.serializeObject(target); - item = _removeSensitive(item); - - item['createdAt'] = new DateTime.now(); - await collection.insert(item); - return await _lastItem(collection, _jsonify, params); - } catch (e, st) { - log(e, st, 'CREATE'); - throw new AngelHttpException.BadRequest(); - } - } + Future create(data, [Map params]) => + super.create(_serialize(data), params).then(_deserialize); @override - Future read(id, [Map params]) async { - ObjectId _id = _makeId(id); - - Map found = await collection.findOne(where.id(_id).and(_makeQuery(params))); - - if (found == null) { - throw new AngelHttpException.NotFound( - message: 'No record found for ID ${_id.toHexString()}'); - } - - return _jsonify(found, params); - } + Future read(id, [Map params]) => super.read(id, params).then(_deserialize); @override - Future modify(id, Map data, [Map params]) async { - ObjectId _id = _makeId(id); - try { - Map result = - await collection.findOne(where.id(_id).and(_makeQuery(params))); - - if (result == null) { - throw new AngelHttpException.NotFound( - message: 'No record found for ID ${_id.toHexString()}'); - } - - result = mergeMap([result, _removeSensitive(data)]); - result['_id'] = _id; - result['updatedAt'] = new DateTime.now(); - - await collection.update(where.id(_id), result); - return await read(_id, params); - } catch (e, st) { - log(e, st, 'MODIFY'); - throw new AngelHttpException(e, stackTrace: st); - } - } + Future modify(id, data, [Map params]) => + super.modify(id, _serialize(data), params).then(_deserialize); @override - Future update(id, _data, [Map params]) async { - try { - Model data = - (_data is T) ? _data : god.deserializeDatum(_data, outputType: T); - ObjectId _id = _makeId(id); - Map rawData = _removeSensitive(god.serializeObject(data)); - rawData['_id'] = _id; - rawData['createdAt'] = data.createdAt; - rawData['updatedAt'] = new DateTime.now(); - - await collection.update(where.id(_id).and(_makeQuery(params)), rawData); - var result = _jsonify(rawData, params); - - if (result is T) { - result.createdAt = data.createdAt; - result.updatedAt = rawData['updatedAt']; - } - return result; - } catch (e, st) { - log(e, st, 'UPDATE'); - throw new AngelHttpException(e, stackTrace: st); - } - } + Future update(id, data, [Map params]) => + super.update(id, _serialize(data), params).then(_deserialize); @override - Future remove(id, [Map params]) async { - var result = await read(id, params); - - try { - await collection.remove(where.id(_makeId(id)).and(_makeQuery(params))); - return result; - } catch (e, st) { - log(e, st, 'REMOVE'); - throw new AngelHttpException(e, stackTrace: st); - } - } + Future remove(id, [Map params]) => + super.remove(id, params).then(_deserialize); } diff --git a/lib/mongo_service_typed.old.dart b/lib/mongo_service_typed.old.dart new file mode 100644 index 00000000..45cb155d --- /dev/null +++ b/lib/mongo_service_typed.old.dart @@ -0,0 +1,145 @@ +part of angel_mongo.services; + +/// Manipulates data from MongoDB by serializing BSON from and deserializing BSON to a target class. +class MongoTypedService extends Service { + DbCollection collection; + bool debug; + + MongoTypedService(DbCollection this.collection, {this.debug: true}) : super() { + if (!reflectType(T).isAssignableTo(reflectType(Model))) + throw new Exception( + "If you specify a type for MongoService, it must be dynamic, Map, or extend from Model."); + } + + _jsonify(Map doc, [Map params]) { + Map result = {}; + for (var key in doc.keys) { + if (doc[key] is ObjectId) { + result[key] = doc[key].toHexString(); + } else + result[key] = doc[key]; + } + + result = _transformId(result); + + // Clients will always receive JSON. + if ((params != null && params['provider'] != null)) { + return result; + } else { + // However, when we run server-side, we should return a T, not a Map. + Model typedResult = god.deserializeDatum(result, outputType: T); + typedResult.createdAt = result['createdAt']; + typedResult.updatedAt = result['updatedAt']; + return typedResult; + } + } + + void log(e, st, msg) { + if (debug) { + stderr.writeln('$msg ERROR: $e'); + stderr.writeln(st); + } + } + + @override + Future index([Map params]) async { + return await (await collection.find(_makeQuery(params))) + .map((x) => _jsonify(x, params)) + .toList(); + } + + @override + Future create(data, [Map params]) async { + Map item; + + try { + Model target = + (data is T) ? data : god.deserializeDatum(data, outputType: T); + item = god.serializeObject(target); + item = _removeSensitive(item); + + item['createdAt'] = new DateTime.now(); + await collection.insert(item); + return await _lastItem(collection, _jsonify, params); + } catch (e, st) { + log(e, st, 'CREATE'); + throw new AngelHttpException.badRequest(); + } + } + + @override + Future read(id, [Map params]) async { + ObjectId _id = _makeId(id); + + Map found = await collection.findOne(where.id(_id).and(_makeQuery(params))); + + if (found == null) { + throw new AngelHttpException.notFound( + message: 'No record found for ID ${_id.toHexString()}'); + } + + return _jsonify(found, params); + } + + @override + Future modify(id, Map data, [Map params]) async { + ObjectId _id = _makeId(id); + try { + Map result = + await collection.findOne(where.id(_id).and(_makeQuery(params))); + + if (result == null) { + throw new AngelHttpException.notFound( + message: 'No record found for ID ${_id.toHexString()}'); + } + + result = mergeMap([result, _removeSensitive(data)]); + result['_id'] = _id; + result['updatedAt'] = new DateTime.now(); + + await collection.update(where.id(_id), result); + return await read(_id, params); + } catch (e, st) { + log(e, st, 'MODIFY'); + throw new AngelHttpException(e, stackTrace: st); + } + } + + @override + Future update(id, _data, [Map params]) async { + try { + Model data = + (_data is T) ? _data : god.deserializeDatum(_data, outputType: T); + ObjectId _id = _makeId(id); + Map rawData = _removeSensitive(god.serializeObject(data)); + rawData['_id'] = _id; + rawData['createdAt'] = data.createdAt; + rawData['updatedAt'] = new DateTime.now(); + + await collection.update(where.id(_id).and(_makeQuery(params)), rawData); + var result = _jsonify(rawData, params); + + if (result is T) { + result.createdAt = data.createdAt; + result.updatedAt = rawData['updatedAt']; + } + return result; + } catch (e, st) { + log(e, st, 'UPDATE'); + throw new AngelHttpException(e, stackTrace: st); + } + } + + @override + Future remove(id, [Map params]) async { + var result = await read(id, params); + + try { + await collection.remove(where.id(_makeId(id)).and(_makeQuery(params))); + return result; + } catch (e, st) { + log(e, st, 'REMOVE'); + throw new AngelHttpException(e, stackTrace: st); + } + } +} diff --git a/lib/services.dart b/lib/services.dart index fb70688f..9c163224 100644 --- a/lib/services.dart +++ b/lib/services.dart @@ -4,10 +4,10 @@ import 'dart:async'; import 'dart:io'; import 'dart:mirrors'; import 'package:angel_framework/angel_framework.dart'; +import 'package:angel_framework/common.dart' show Model; import 'package:json_god/json_god.dart' as god; import 'package:merge_map/merge_map.dart'; import 'package:mongo_dart/mongo_dart.dart'; -import 'model.dart'; part 'mongo_service.dart'; @@ -15,15 +15,17 @@ part 'mongo_service_typed.dart'; Map _transformId(Map doc) { Map result = mergeMap([doc]); - result['id'] = doc['_id']; + result + ..['id'] = doc['_id'] + ..remove('_id'); - return result..remove('_id'); + return result; } _lastItem(DbCollection collection, Function _jsonify, [Map params]) async { return (await (await collection - .find(where.sortBy('\$natural', descending: true))) - .toList()) + .find(where.sortBy('\$natural', descending: true))) + .toList()) .map((x) => _jsonify(x, params)) .first; } @@ -32,25 +34,27 @@ ObjectId _makeId(id) { try { return (id is ObjectId) ? id : new ObjectId.fromHexString(id.toString()); } catch (e) { - throw new AngelHttpException.BadRequest(); + throw new AngelHttpException.badRequest(); } } +const List _SENSITIVE = const ['id', '_id', 'createdAt', 'updatedAt']; + Map _removeSensitive(Map data) { - return data - ..remove('id') - ..remove('_id') - ..remove('createdAt') - ..remove('updatedAt'); + return data.keys + .where((k) => !_SENSITIVE.contains(k)) + .fold({}, (map, key) => map..[key] = data[key]); } +const List _NO_QUERY = const ['__requestctx', '__responsectx']; + SelectorBuilder _makeQuery([Map params_]) { Map params = params_ ?? {}; params = params..remove('provider'); SelectorBuilder result = where.exists('_id'); // You can pass a SelectorBuilder as 'query'; - if (params['query'] != null && params['query'] is SelectorBuilder) { + if (params['query'] is SelectorBuilder) { return params['query']; } @@ -73,10 +77,31 @@ SelectorBuilder _makeQuery([Map params_]) { // by that, ascending result = result.sortBy(params[key]); } - } else if (key is String) { - result = result.and(where.eq(key, params[key])); + } else if (key == 'query') { + Map query = params[key]; + query.forEach((key, v) { + var value = v is Map ? _filterNoQuery(v) : v; + + if (!_NO_QUERY.contains(key) && + value is! RequestContext && + value is! ResponseContext) { + result = result.and(where.eq(key, value)); + } + }); } } return result; } + +Map _filterNoQuery(Map data) { + return data.keys.fold({}, (map, key) { + var value = data[key]; + + if (_NO_QUERY.contains(key) || + value is RequestContext || + value is ResponseContext) return map; + if (key is! Map) return map..[key] = value; + return map..[key] = _filterNoQuery(value); + }); +} diff --git a/pubspec.yaml b/pubspec.yaml index cb2b19a2..aa15a840 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_mongo -version: 1.0.0-dev+6 +version: 1.0.0 description: MongoDB-enabled services for the Angel framework. author: Tobe O homepage: https://github.com/angel-dart/angel_mongo diff --git a/test/generic_test.dart b/test/generic_test.dart index 539926e3..56e99df6 100644 --- a/test/generic_test.dart +++ b/test/generic_test.dart @@ -36,7 +36,7 @@ main() { Db db = new Db('mongodb://localhost:27017/angel_mongo'); DbCollection testData; String url; - HookedService Greetings; + HookedService greetingService; setUp(() async { client = new http.Client(); @@ -45,13 +45,18 @@ main() { // Delete anything before we start await testData.remove(); - var service = new MongoService(testData); - Greetings = new HookedService(service); - wireHooked(Greetings); + var service = new MongoService(testData, debug: true); + greetingService = new HookedService(service); + wireHooked(greetingService); - app.use('/api', Greetings); - HttpServer server = - await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0); + app.use('/api', greetingService); + + app.fatalErrorStream.listen((AngelFatalError e) { + print('Fatal error: ${e.error}'); + print(e.stack); + }); + + var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0); url = "http://${server.address.host}:${server.port}"; }); @@ -62,7 +67,7 @@ main() { await app.httpServer.close(force: true); client = null; url = null; - Greetings = null; + greetingService = null; }); test('insert items', () async { @@ -125,17 +130,17 @@ main() { body: god.serialize(testGreeting), headers: headers); Map created = god.deserialize(response.body); - int lastCount = (await Greetings.index()).length; + int lastCount = (await greetingService.index()).length; await client.delete("$url/api/${created['id']}"); - expect((await Greetings.index()).length, equals(lastCount - 1)); + expect((await greetingService.index()).length, equals(lastCount - 1)); }); test('\$sort and query parameters', () async { // Search by where.eq - Map world = await Greetings.create({"to": "world"}); - Map Mom = await Greetings.create({"to": "Mom"}); - Map Updated = await Greetings.create({"to": "Updated"}); + Map world = await greetingService.create({"to": "world"}); + await greetingService.create({"to": "Mom"}); + await greetingService.create({"to": "Updated"}); var response = await client.get("$url/api?to=world"); print(response.body); @@ -147,14 +152,14 @@ main() { expect(queried[0]["createdAt"], equals(world["createdAt"].toIso8601String())); - response = await client.get("$url/api?\$sort.createdAt=-1"); + /*response = await client.get("$url/api?\$sort.createdAt=-1"); print(response.body); queried = god.deserialize(response.body); expect(queried[0]["id"], equals(Updated["id"])); expect(queried[1]["id"], equals(Mom["id"])); - expect(queried[2]["id"], equals(world["id"])); - - queried = await Greetings.index({ + expect(queried[2]["id"], equals(world["id"]));*/ + + queried = await greetingService.index({ "\$query": {"_id": where.id(new ObjectId.fromHexString(world["id"]))} }); print(queried); diff --git a/test/typed_test.dart b/test/typed_test.dart index f9948e66..656c7e3b 100644 --- a/test/typed_test.dart +++ b/test/typed_test.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:angel_framework/angel_framework.dart'; +import 'package:angel_framework/common.dart' show Model; import 'package:angel_mongo/angel_mongo.dart'; import 'package:http/http.dart' as http; import 'package:json_god/json_god.dart' as god; @@ -9,7 +10,8 @@ import 'package:test/test.dart'; class Greeting extends Model { String to; - Greeting({String this.to}); + Greeting({String id, this.to, DateTime createdAt, DateTime updatedAt}) + : super(id: id, createdAt: createdAt, updatedAt: updatedAt); } final headers = { @@ -39,7 +41,7 @@ main() { Db db = new Db('mongodb://localhost:27017/angel_mongo'); DbCollection testData; String url; - Service Greetings; + Service greetingService; setUp(() async { client = new http.Client(); @@ -49,10 +51,16 @@ main() { await testData.remove(); var service = new MongoTypedService(testData); - Greetings = new HookedService(service); - wireHooked(Greetings); + greetingService = new HookedService(service); + wireHooked(greetingService); + + app.use('/api', greetingService); + + app.fatalErrorStream.listen((AngelFatalError e) { + print('Fatal error: ${e.error}'); + print(e.stack); + }); - app.use('/api', Greetings); HttpServer server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0); url = "http://${server.address.host}:${server.port}"; @@ -65,7 +73,7 @@ main() { await app.httpServer.close(force: true); client = null; url = null; - Greetings = null; + greetingService = null; }); test('insert items', () async { @@ -79,7 +87,7 @@ main() { expect(greetings.length, equals(1)); Greeting greeting = new Greeting(to: "Mom"); - await Greetings.create(greeting); + await greetingService.create(greeting); greetings = await (await testData.find()).toList(); expect(greetings.length, equals(2)); }); @@ -93,14 +101,15 @@ main() { response = await client.get("$url/api/${created['id']}"); expect(response.statusCode, equals(HttpStatus.OK)); Map read = god.deserialize(response.body); + print('Read: $read'); expect(read['id'], equals(created['id'])); expect(read['to'], equals('world')); - expect(read['createdAt'], isNot(null)); + expect(read['createdAt'], isNotNull); - Greeting greeting = await Greetings.read(created['id']); + Greeting greeting = await greetingService.read(created['id']); expect(greeting.id, equals(created['id'])); expect(greeting.to, equals('world')); - expect(greeting.createdAt, isNot(null)); + expect(greeting.createdAt, isNotNull); }); test('modify item', () async { @@ -115,10 +124,10 @@ main() { expect(response.statusCode, equals(HttpStatus.OK)); expect(modified['id'], equals(created['id'])); expect(modified['to'], equals('Mom')); - expect(modified['updatedAt'], isNot(null)); + expect(modified['updatedAt'], isNotNull); - await Greetings.modify(created['id'], {"to": "Batman"}); - Greeting greeting = await Greetings.read(created['id']); + await greetingService.modify(created['id'], {"to": "Batman"}); + Greeting greeting = await greetingService.read(created['id']); expect(greeting.to, equals("Batman")); }); @@ -134,7 +143,7 @@ main() { expect(response.statusCode, equals(HttpStatus.OK)); expect(modified['id'], equals(created['id'])); expect(modified['to'], equals('Updated')); - expect(modified['updatedAt'], isNot(null)); + expect(modified['updatedAt'], isNotNull); }); test('remove item', () async { @@ -142,26 +151,26 @@ main() { body: god.serialize(testGreeting), headers: headers); Map created = god.deserialize(response.body); - int lastCount = (await Greetings.index()).length; + int lastCount = (await greetingService.index()).length; await client.delete("$url/api/${created['id']}"); - expect((await Greetings.index()).length, equals(lastCount - 1)); + expect((await greetingService.index()).length, equals(lastCount - 1)); Greeting bernie = - await Greetings.create(new Greeting(to: "Bernie Sanders")); - lastCount = (await Greetings.index()).length; + await greetingService.create(new Greeting(to: "Bernie Sanders")); + lastCount = (await greetingService.index()).length; print('b'); - await Greetings.remove(bernie.id); - expect((await Greetings.index()).length, equals(lastCount - 1)); + await greetingService.remove(bernie.id); + expect((await greetingService.index()).length, equals(lastCount - 1)); print('c'); }); - test('\$sort and query parameters', () async { + test('query parameters', () async { // Search by where.eq - Greeting world = await Greetings.create(new Greeting(to: "world")); - Greeting Mom = await Greetings.create(new Greeting(to: "Mom")); - Greeting Updated = await Greetings.create(new Greeting(to: "Updated")); + Greeting world = await greetingService.create(new Greeting(to: "world")); + await greetingService.create(new Greeting(to: "Mom")); + await greetingService.create(new Greeting(to: "Updated")); var response = await client.get("$url/api?to=world"); print(response.body); @@ -171,16 +180,16 @@ main() { expect(queried[0]["id"], equals(world.id)); expect(queried[0]["to"], equals(world.to)); expect( - queried[0]["createdAt"], equals(world.createdAt.toIso8601String())); + queried[0]["createdAt"], equals(world.createdAt?.toIso8601String())); - response = await client.get("$url/api?\$sort.createdAt=-1"); + /*response = await client.get("$url/api?\$sort.createdAt=-1"); print(response.body); queried = god.deserialize(response.body); expect(queried[0]["id"], equals(Updated.id)); expect(queried[1]["id"], equals(Mom.id)); - expect(queried[2]["id"], equals(world.id)); + expect(queried[2]["id"], equals(world.id));*/ - queried = await Greetings.index({ + queried = await greetingService.index({ "\$query": {"_id": where.id(new ObjectId.fromHexString(world.id))} }); print(queried.map(god.serialize).toList());