From a5a930bbe91f49859e0bf17a85499e9e63cde011 Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Mon, 29 Aug 2022 15:42:04 +0200 Subject: [PATCH 01/11] test basic waiting for refactor from api --- lib/api/firebase_document.dart | 5 ++- lib/api/idocument.dart | 2 +- lib/model/client.dart | 9 +++-- lib/model/dietitian.dart | 8 ++--- lib/model/meal.dart | 4 +-- pubspec.lock | 21 +++++++++++ pubspec.yaml | 1 + test/aftercare_test.dart | 47 ++++++++++++++++++++++++ test/client_test.dart | 65 ++++++++++++++++++++++++++++++++++ test/dietitian_test.dart | 47 ++++++++++++++++++++++++ test/meal_test.dart | 47 ++++++++++++++++++++++++ test/message_test.dart | 47 ++++++++++++++++++++++++ 12 files changed, 292 insertions(+), 11 deletions(-) create mode 100644 test/aftercare_test.dart create mode 100644 test/client_test.dart create mode 100644 test/dietitian_test.dart create mode 100644 test/meal_test.dart create mode 100644 test/message_test.dart diff --git a/lib/api/firebase_document.dart b/lib/api/firebase_document.dart index cb3bc4b..c5dea36 100644 --- a/lib/api/firebase_document.dart +++ b/lib/api/firebase_document.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:pdg_app/api/idocument.dart'; import 'package:pdg_app/model/document.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_storage/firebase_storage.dart'; class FirebaseDocument implements IDocument { FirebaseDocument._(); @@ -10,9 +11,11 @@ class FirebaseDocument implements IDocument { factory FirebaseDocument() => _instance; CollectionReference documents = FirebaseFirestore.instance.collection('document'); + final storage = FirebaseStorage.instance; @override - void createDocument(Document document) { + void createDocument(Document document, String fileName) { + final file = storage.ref().child(fileName); documents .add(document.toJson()) .then((value) => log("Document Added")) diff --git a/lib/api/idocument.dart b/lib/api/idocument.dart index 75262a8..3e07964 100644 --- a/lib/api/idocument.dart +++ b/lib/api/idocument.dart @@ -1,7 +1,7 @@ import 'package:pdg_app/model/document.dart'; abstract class IDocument { - void createDocument(Document document); + void createDocument(Document document, String fileName); Future readDocument(String documentId); void updateDocument(Document document); void deleteDocument(String documentId); diff --git a/lib/model/client.dart b/lib/model/client.dart index 8312d68..1a7d036 100644 --- a/lib/model/client.dart +++ b/lib/model/client.dart @@ -1,4 +1,5 @@ class Client { + String? uid; String? firstName; String? lastName; String? birthDate; @@ -6,7 +7,8 @@ class Client { String? insurance; Client( - {this.firstName, + {this.uid, + this.firstName, this.lastName, this.birthDate, this.insurance, @@ -14,6 +16,7 @@ class Client { factory Client.fromJson(Map client) { return Client( + uid: client['uid'], firstName: client['firstName'], lastName: client['lastName'], birthDate: client['birthDate'], @@ -24,6 +27,7 @@ class Client { Map toJson() { return { + 'uid': uid, 'firstName': firstName, 'lastName': lastName, 'birthDate': birthDate, @@ -34,7 +38,6 @@ class Client { @override String toString() { - return 'Client{$firstName $lastName $birthDate $insurance $phoneNumber}'; + return 'Client{$uid $firstName $lastName $birthDate $insurance $phoneNumber}'; } - } diff --git a/lib/model/dietitian.dart b/lib/model/dietitian.dart index 5d63c02..f2d4367 100644 --- a/lib/model/dietitian.dart +++ b/lib/model/dietitian.dart @@ -1,5 +1,5 @@ class Dietitian { - String? id; + String? uid; String? firstName; String? lastName; List? clientList; @@ -7,7 +7,7 @@ class Dietitian { String? avs; Dietitian( - {this.id, + {this.uid, this.firstName, this.lastName, this.clientList, @@ -16,7 +16,7 @@ class Dietitian { factory Dietitian.fromJson(Map dietitian) { return Dietitian( - id: dietitian['id'], + uid: dietitian['id'], firstName: dietitian['firstName'], lastName: dietitian['lastName'], clientList: dietitian['clientList'], @@ -27,7 +27,7 @@ class Dietitian { Map toJson() { return { - 'id': id, + 'id': uid, 'firstName': firstName, 'lastName': lastName, 'clientList': clientList, diff --git a/lib/model/meal.dart b/lib/model/meal.dart index 7bcb75e..54fafa7 100644 --- a/lib/model/meal.dart +++ b/lib/model/meal.dart @@ -3,8 +3,8 @@ class Meal { DateTime? endTime; String? lastName; List? photo; - String? hunger; - String? satiety; + int? hunger; + int? satiety; String? setting; String? comment; diff --git a/pubspec.lock b/pubspec.lock index 199b6f3..6b89889 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -232,6 +232,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + fake_cloud_firestore: + dependency: "direct dev" + description: + name: fake_cloud_firestore + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" file: dependency: transitive description: @@ -597,6 +604,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.27.5" shelf: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 761392c..abc238c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,6 +56,7 @@ dev_dependencies: widgetbook: ^2.4.1 auto_route_generator: ^5.0.1 build_runner: + fake_cloud_firestore: ^1.3.1 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/test/aftercare_test.dart b/test/aftercare_test.dart new file mode 100644 index 0000000..6d271de --- /dev/null +++ b/test/aftercare_test.dart @@ -0,0 +1,47 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pdg_app/api/iaftercare.dart'; +import 'package:pdg_app/api/firebase_aftercare.dart'; +import 'package:pdg_app/firebase_options.dart'; +import 'package:pdg_app/model/aftercare.dart'; + +final db = FakeFirebaseFirestore(); +Aftercare a1 = Aftercare(bmi: 12, weight: 14.0); + + +void populateMockAftercare(Aftercare c) async { + await db.collection('aftercare').add(c.toJson()); +} + +void main() { + late final IAftercare aftercareApi; + + setUp(() async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + populateMockAftercare(a1); + aftercareApi = FirebaseAftercare(); + }); + + test("Create Aftercare", () { + aftercareApi.createAftercare(a1); + expect(a1, a1); + }); + + test("Read Aftercare", () { + aftercareApi.readAftercare('fd'); + expect(a1, a1); + }); + + test("Update aftercare", () { + aftercareApi.updateAftercare(a1); + expect(a1, a1); + }); + + test("Delete aftercare", () { + aftercareApi.deleteAftercare(''); + expect(a1, a1); + }); +} diff --git a/test/client_test.dart b/test/client_test.dart new file mode 100644 index 0000000..92f5fdc --- /dev/null +++ b/test/client_test.dart @@ -0,0 +1,65 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pdg_app/api/iclient.dart'; +import 'package:pdg_app/api/firebase_client.dart'; +import 'package:pdg_app/firebase_options.dart'; +import 'package:pdg_app/model/client.dart'; + +final db = FakeFirebaseFirestore(); +Client c1 = Client( + uid: '1', + firstName: 'Olivier', + lastName: 'D\'Ancona', + phoneNumber: '0780001223'); +Client c2 = Client( + uid: '2', + firstName: 'Chloé', + lastName: 'Fontaine', + phoneNumber: '0780002334'); +Client c3 = Client( + uid: '3', firstName: 'Luca', lastName: 'Coduri', phoneNumber: '0780003445'); +Client c4 = Client( + uid: '4', + firstName: 'Nelson', + lastName: 'Jeanrenaud', + phoneNumber: '0786834556'); + +void populateMockClient(Client c) async { + await db.collection('client').add(c.toJson()); +} + +void main() { + late final IClient clientApi; + + setUp(() async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + populateMockClient(c1); + populateMockClient(c2); + populateMockClient(c3); + populateMockClient(c4); + clientApi = FirebaseClient(); + }); + + test("Create Client", () { + clientApi.createClient(c1); + expect(c1, c1); + }); + + test("Read Client", () { + clientApi.readClient(c1.uid!); + expect(c1, c1); + }); + + test("Update client", () { + clientApi.updateClient(c2); + expect(c1, c1); + }); + + test("Delete client", () { + clientApi.deleteClient(c1.uid!); + expect(c1, c1); + }); +} diff --git a/test/dietitian_test.dart b/test/dietitian_test.dart new file mode 100644 index 0000000..2bdd9d8 --- /dev/null +++ b/test/dietitian_test.dart @@ -0,0 +1,47 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pdg_app/api/idietitian.dart'; +import 'package:pdg_app/api/firebase_dietitian.dart'; +import 'package:pdg_app/firebase_options.dart'; +import 'package:pdg_app/model/dietitian.dart'; + +final db = FakeFirebaseFirestore(); + Dietitian d1 = Dietitian(firstName: 'Claire', lastName: 'Emery', uid: '1'); + + +void populateMockDietitian(Dietitian c) async { + await db.collection('dietitian').add(c.toJson()); +} + +void main() { + late final IDietitian dietitianApi; + + setUp(() async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + populateMockDietitian(d1); + dietitianApi = FirebaseDietitian(); + }); + + test("Create Dietitian", () { + dietitianApi.createDietitian(d1); + expect(d1, d1); + }); + + test("Read Dietitian", () { + dietitianApi.readDietitian(d1.uid!); + expect(d1, d1); + }); + + test("Update dietitian", () { + dietitianApi.updateDietitian(d1); + expect(d1, d1); + }); + + test("Delete dietitian", () { + dietitianApi.deleteDietitian(d1.uid!); + expect(d1, d1); + }); +} diff --git a/test/meal_test.dart b/test/meal_test.dart new file mode 100644 index 0000000..1ecdd52 --- /dev/null +++ b/test/meal_test.dart @@ -0,0 +1,47 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pdg_app/api/imeal.dart'; +import 'package:pdg_app/api/firebase_meal.dart'; +import 'package:pdg_app/firebase_options.dart'; +import 'package:pdg_app/model/meal.dart'; + +final db = FakeFirebaseFirestore(); +Meal m1 = Meal(hunger: 4, satiety: 5, comment: 'no comment'); + + +void populateMockMeal(Meal c) async { + await db.collection('meal').add(c.toJson()); +} + +void main() { + late final IMeal mealApi; + + setUp(() async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + populateMockMeal(m1); + mealApi = FirebaseMeal(); + }); + + test("Create Meal", () { + mealApi.createMeal(m1); + expect(m1, m1); + }); + + test("Read Meal", () { + mealApi.readMeal('fd'); + expect(m1, m1); + }); + + test("Update meal", () { + mealApi.updateMeal(m1); + expect(m1, m1); + }); + + test("Delete meal", () { + mealApi.deleteMeal(''); + expect(m1, m1); + }); +} diff --git a/test/message_test.dart b/test/message_test.dart new file mode 100644 index 0000000..a26778c --- /dev/null +++ b/test/message_test.dart @@ -0,0 +1,47 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pdg_app/api/imessage.dart'; +import 'package:pdg_app/api/firebase_message.dart'; +import 'package:pdg_app/firebase_options.dart'; +import 'package:pdg_app/model/message.dart'; + +final db = FakeFirebaseFirestore(); +Message msg1 = + Message(content: 'Bonjour', fromId: 'alice', toId: 'bob', id: ''); + +void populateMockMessage(Message c) async { + await db.collection('message').add(c.toJson()); +} + +void main() { + late final IMessage messageApi; + + setUp(() async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + populateMockMessage(msg1); + messageApi = FirebaseMessage(); + }); + + test("Create Message", () { + messageApi.createMessage(msg1); + expect(msg1, msg1); + }); + + test("Read Message", () { + messageApi.readMessage('fd'); + expect(msg1, msg1); + }); + + test("Update message", () { + messageApi.updateMessage(msg1); + expect(msg1, msg1); + }); + + test("Delete message", () { + messageApi.deleteMessage(''); + expect(msg1, msg1); + }); +} From 2091d441af78c3a61dcb39c9ec317ff029263b93 Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Mon, 29 Aug 2022 15:46:37 +0200 Subject: [PATCH 02/11] fix --- lib/api/firebase_document.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/firebase_document.dart b/lib/api/firebase_document.dart index c5dea36..e70f183 100644 --- a/lib/api/firebase_document.dart +++ b/lib/api/firebase_document.dart @@ -15,7 +15,7 @@ class FirebaseDocument implements IDocument { @override void createDocument(Document document, String fileName) { - final file = storage.ref().child(fileName); + //final file = storage.ref().child(fileName); documents .add(document.toJson()) .then((value) => log("Document Added")) From c3c963ea5c74ac3c2d2c9634941480b1d47a0363 Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Mon, 29 Aug 2022 16:22:14 +0200 Subject: [PATCH 03/11] step next --- lib/api/firebase_api.dart | 10 ++++++++++ lib/api/firebase_client.dart | 4 +--- 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 lib/api/firebase_api.dart diff --git a/lib/api/firebase_api.dart b/lib/api/firebase_api.dart new file mode 100644 index 0000000..b1f8768 --- /dev/null +++ b/lib/api/firebase_api.dart @@ -0,0 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +class FirebaseAPI { + final FirebaseFirestore firestore; + final CollectionReference collectionReference; + + FirebaseAPI(FirebaseFirestore db, String collectionName) + : firestore = db, + collectionReference = db.collection(collectionName); +} diff --git a/lib/api/firebase_client.dart b/lib/api/firebase_client.dart index a93e297..b2b7928 100644 --- a/lib/api/firebase_client.dart +++ b/lib/api/firebase_client.dart @@ -1,13 +1,11 @@ import 'dart:developer'; import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:pdg_app/api/firebase_api.dart'; import 'package:pdg_app/api/iclient.dart'; import 'package:pdg_app/model/client.dart'; -import 'firebase_document.dart'; - class FirebaseClient extends FirebaseAPI implements IClient { - FirebaseClient(FirebaseFirestore db) : super(db, 'client'); @override From 0725de45af82034010fd786b83b82e8092ffcffa Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 09:07:48 +0200 Subject: [PATCH 04/11] in progress --- lib/api/firebase_aftercare.dart | 4 +- lib/api/firebase_client.dart | 26 +++++++++---- lib/api/firebase_dietitian.dart | 4 +- lib/api/firebase_document.dart | 4 +- lib/api/firebase_meal.dart | 4 +- lib/api/firebase_message.dart | 4 +- lib/model/aftercare.dart | 2 +- lib/model/client.dart | 46 +++++++++++++--------- lib/model/dietitian.dart | 2 +- lib/model/document.dart | 2 +- lib/model/imodel.dart | 2 +- lib/model/meal.dart | 2 +- lib/model/message.dart | 2 +- test/aftercare_test.dart | 6 +-- test/client_test.dart | 68 +++++++++++++++++---------------- test/default_test.dart | 14 ------- test/dietitian_test.dart | 7 +--- test/meal_test.dart | 7 +--- test/message_test.dart | 7 +--- 19 files changed, 100 insertions(+), 113 deletions(-) delete mode 100644 test/default_test.dart diff --git a/lib/api/firebase_aftercare.dart b/lib/api/firebase_aftercare.dart index 6e577ba..bfe14d0 100644 --- a/lib/api/firebase_aftercare.dart +++ b/lib/api/firebase_aftercare.dart @@ -15,7 +15,7 @@ class FirebaseAftercare implements IAftercare { @override void createAftercare(Aftercare aftercare) { aftercares - .add(aftercare.toJson()) + .add(aftercare.toFirestore()) .then((value) => log("Aftercare Added")) .catchError((error) { log("Failed to add aftercare: $error"); @@ -43,7 +43,7 @@ class FirebaseAftercare implements IAftercare { updateAftercare(Aftercare aftercare) { aftercares .doc('FAKE') - .update(aftercare.toJson()) + .update(aftercare.toFirestore()) .then((value) => log("Aftercare Updated")) .catchError((error) { log("Failed to update aftercare: $error"); diff --git a/lib/api/firebase_client.dart b/lib/api/firebase_client.dart index b2b7928..79b7712 100644 --- a/lib/api/firebase_client.dart +++ b/lib/api/firebase_client.dart @@ -11,7 +11,11 @@ class FirebaseClient extends FirebaseAPI implements IClient { @override void createClient(Client client) { collectionReference - .add(client.toJson()) + .withConverter( + fromFirestore: Client.fromFirestore, + toFirestore: (Client client, options) => client.toFirestore()) + .doc(client.uid) + .set(client) .then((value) => log("Client Added")) .catchError((error) { log("Failed to add client: $error"); @@ -21,20 +25,26 @@ class FirebaseClient extends FirebaseAPI implements IClient { @override Future readClient(String clientId) async { - final docRef = collectionReference.doc(clientId); - final doc = await docRef.get(); - if (!doc.exists) { + final docRef = collectionReference.doc(clientId).withConverter( + fromFirestore: Client.fromFirestore, + toFirestore: (Client city, _) => city.toFirestore(), + ); + + final docSnapshot = await docRef.get(); + final client = docSnapshot.data(); + if (client == null) { + log("Doc does not exist"); throw Error(); + } else { + return client; } - final data = doc.data() as Map; - return Client.fromJson(data); } @override void updateClient(Client client) { collectionReference - .doc('FAKE') - .update(client.toJson()) + .doc(client.uid) + .update(client.toFirestore()) .then((value) => log("Client Updated")) .catchError((error) { log("Failed to update client: $error"); diff --git a/lib/api/firebase_dietitian.dart b/lib/api/firebase_dietitian.dart index ccaa3a5..03a19c1 100644 --- a/lib/api/firebase_dietitian.dart +++ b/lib/api/firebase_dietitian.dart @@ -15,7 +15,7 @@ class FirebaseDietitian implements IDietitian { @override void createDietitian(Dietitian dietitian) { dietitians - .add(dietitian.toJson()) + .add(dietitian.toFirestore()) .then((value) => log("Dietitian Added")) .catchError((error) { log("Failed to add dietitian: $error"); @@ -38,7 +38,7 @@ class FirebaseDietitian implements IDietitian { void updateDietitian(Dietitian dietitian) { dietitians .doc('FAKE') - .update(dietitian.toJson()) + .update(dietitian.toFirestore()) .then((value) => log("Dietitian Updated")) .catchError((error) { log("Failed to update dietitian: $error"); diff --git a/lib/api/firebase_document.dart b/lib/api/firebase_document.dart index e70f183..cc19ea4 100644 --- a/lib/api/firebase_document.dart +++ b/lib/api/firebase_document.dart @@ -17,7 +17,7 @@ class FirebaseDocument implements IDocument { void createDocument(Document document, String fileName) { //final file = storage.ref().child(fileName); documents - .add(document.toJson()) + .add(document.toFirestore()) .then((value) => log("Document Added")) .catchError((error) { log("Failed to add document: $error"); @@ -45,7 +45,7 @@ class FirebaseDocument implements IDocument { updateDocument(Document document) { documents .doc('FAKE') - .update(document.toJson()) + .update(document.toFirestore()) .then((value) => log("Document Updated")) .catchError((error) { log("Failed to update document: $error"); diff --git a/lib/api/firebase_meal.dart b/lib/api/firebase_meal.dart index 61c99be..1191285 100644 --- a/lib/api/firebase_meal.dart +++ b/lib/api/firebase_meal.dart @@ -13,7 +13,7 @@ class FirebaseMeal implements IMeal { @override void createMeal(Meal meal) { meals - .add(meal.toJson()) + .add(meal.toFirestore()) .then((value) => log("Meal Added")) .catchError((error) { log("Failed to add meal: $error"); @@ -41,7 +41,7 @@ class FirebaseMeal implements IMeal { updateMeal(Meal meal) { meals .doc('FAKE') - .update(meal.toJson()) + .update(meal.toFirestore()) .then((value) => log("Meal Updated")) .catchError((error) { log("Failed to update meal: $error"); diff --git a/lib/api/firebase_message.dart b/lib/api/firebase_message.dart index 11c79c4..6bfdecf 100644 --- a/lib/api/firebase_message.dart +++ b/lib/api/firebase_message.dart @@ -14,7 +14,7 @@ class FirebaseMessage implements IMessage { @override void createMessage(Message message) { messages - .add(message.toJson()) + .add(message.toFirestore()) .then((value) => log("Message Added")) .catchError((error) { log("Failed to add message: $error"); @@ -42,7 +42,7 @@ class FirebaseMessage implements IMessage { updateMessage(Message message) { messages .doc('FAKE') - .update(message.toJson()) + .update(message.toFirestore()) .then((value) => log("Message Updated")) .catchError((error) { log("Failed to update message: $error"); diff --git a/lib/model/aftercare.dart b/lib/model/aftercare.dart index 7c437eb..eab54eb 100644 --- a/lib/model/aftercare.dart +++ b/lib/model/aftercare.dart @@ -37,7 +37,7 @@ class Aftercare implements IModel { } @override - Map toJson() { + Map toFirestore() { return { 'bmi': bmi, 'weight': weight, diff --git a/lib/model/client.dart b/lib/model/client.dart index 8a68086..e96fda7 100644 --- a/lib/model/client.dart +++ b/lib/model/client.dart @@ -1,7 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:uuid/uuid.dart'; + import 'imodel.dart'; -class Client implements IModel{ - String? uid; +class Client implements IModel { + String uid; String? firstName; String? lastName; String? birthDate; @@ -9,33 +12,35 @@ class Client implements IModel{ String? insurance; Client( - {this.uid, - this.firstName, + {this.firstName, this.lastName, this.birthDate, this.insurance, - this.phoneNumber}); + this.phoneNumber}) + : uid = const Uuid().v1(); - factory Client.fromJson(Map client) { + factory Client.fromFirestore( + DocumentSnapshot> snapshot, + SnapshotOptions? options, + ) { + final data = snapshot.data(); return Client( - uid: client['uid'], - firstName: client['firstName'], - lastName: client['lastName'], - birthDate: client['birthDate'], - insurance: client['insurance'], - phoneNumber: client['phoneNumber'], + firstName: data?['firstName'], + lastName: data?['lastName'], + birthDate: data?['birthDate'], + insurance: data?['insurance'], + phoneNumber: data?['phoneNumber'], ); } @override - Map toJson() { + Map toFirestore() { return { - 'uid': uid, - 'firstName': firstName, - 'lastName': lastName, - 'birthDate': birthDate, - 'phoneNumber': phoneNumber, - 'insurance': insurance, + if (firstName != null) 'firstName': firstName, + if (lastName != null) 'lastName': lastName, + if (birthDate != null) 'birthDate': birthDate, + if (phoneNumber != null) 'phoneNumber': phoneNumber, + if (insurance != null) 'insurance': insurance, }; } @@ -44,4 +49,7 @@ class Client implements IModel{ return 'Client{$uid $firstName $lastName $birthDate $insurance $phoneNumber}'; } + void setFirstName(String name) { + firstName = name; + } } diff --git a/lib/model/dietitian.dart b/lib/model/dietitian.dart index ed644fc..0657713 100644 --- a/lib/model/dietitian.dart +++ b/lib/model/dietitian.dart @@ -28,7 +28,7 @@ class Dietitian implements IModel { } @override - Map toJson() { + Map toFirestore() { return { 'uid': uid, 'firstName': firstName, diff --git a/lib/model/document.dart b/lib/model/document.dart index 708ba21..0f9d130 100644 --- a/lib/model/document.dart +++ b/lib/model/document.dart @@ -13,7 +13,7 @@ class Document implements IModel { } @override - Map toJson() { + Map toFirestore() { return { 'url': url, }; diff --git a/lib/model/imodel.dart b/lib/model/imodel.dart index 510404a..f9d6641 100644 --- a/lib/model/imodel.dart +++ b/lib/model/imodel.dart @@ -1,3 +1,3 @@ abstract class IModel { - Map toJson(); + Map toFirestore(); } \ No newline at end of file diff --git a/lib/model/meal.dart b/lib/model/meal.dart index addcbec..7c67cdc 100644 --- a/lib/model/meal.dart +++ b/lib/model/meal.dart @@ -34,7 +34,7 @@ class Meal implements IModel { } @override - Map toJson() { + Map toFirestore() { return { 'startTime': startTime, 'endTime': endTime, diff --git a/lib/model/message.dart b/lib/model/message.dart index 82f2a7b..7442454 100644 --- a/lib/model/message.dart +++ b/lib/model/message.dart @@ -31,7 +31,7 @@ class Message implements IModel { } @override - Map toJson() { + Map toFirestore() { return { 'id': id, 'time': time, diff --git a/test/aftercare_test.dart b/test/aftercare_test.dart index 6d271de..ffd4f73 100644 --- a/test/aftercare_test.dart +++ b/test/aftercare_test.dart @@ -1,5 +1,4 @@ import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/iaftercare.dart'; import 'package:pdg_app/api/firebase_aftercare.dart'; @@ -11,16 +10,13 @@ Aftercare a1 = Aftercare(bmi: 12, weight: 14.0); void populateMockAftercare(Aftercare c) async { - await db.collection('aftercare').add(c.toJson()); + await db.collection('aftercare').add(c.toFirestore()); } void main() { late final IAftercare aftercareApi; setUp(() async { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); populateMockAftercare(a1); aftercareApi = FirebaseAftercare(); }); diff --git a/test/client_test.dart b/test/client_test.dart index 92f5fdc..561b65e 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -1,65 +1,67 @@ +import 'dart:developer'; + import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/iclient.dart'; import 'package:pdg_app/api/firebase_client.dart'; -import 'package:pdg_app/firebase_options.dart'; import 'package:pdg_app/model/client.dart'; final db = FakeFirebaseFirestore(); Client c1 = Client( - uid: '1', - firstName: 'Olivier', - lastName: 'D\'Ancona', - phoneNumber: '0780001223'); -Client c2 = Client( - uid: '2', - firstName: 'Chloé', - lastName: 'Fontaine', - phoneNumber: '0780002334'); -Client c3 = Client( - uid: '3', firstName: 'Luca', lastName: 'Coduri', phoneNumber: '0780003445'); + firstName: 'Olivier', lastName: 'D\'Ancona', phoneNumber: '0780001223'); +Client c2 = + Client(firstName: 'Chloé', lastName: 'Fontaine', phoneNumber: '0780002334'); +Client c3 = + Client(firstName: 'Luca', lastName: 'Coduri', phoneNumber: '0780003445'); Client c4 = Client( - uid: '4', - firstName: 'Nelson', - lastName: 'Jeanrenaud', - phoneNumber: '0786834556'); + firstName: 'Nelson', lastName: 'Jeanrenaud', phoneNumber: '0786834556'); void populateMockClient(Client c) async { - await db.collection('client').add(c.toJson()); + await db.collection('client').add(c.toFirestore()); } void main() { - late final IClient clientApi; + late IClient clientApi; + final clients = db.collection('client'); setUp(() async { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); populateMockClient(c1); populateMockClient(c2); populateMockClient(c3); populateMockClient(c4); - clientApi = FirebaseClient(); + clientApi = FirebaseClient(db); }); - test("Create Client", () { + test("Create Client", () async { clientApi.createClient(c1); - expect(c1, c1); + final docSnapshot = await clients + .doc(c1.uid) + .withConverter( + fromFirestore: Client.fromFirestore, + toFirestore: (Client city, _) => city.toFirestore(), + ) + .get(); + final c2 = docSnapshot.data(); + log(c2!.uid); + log(c1.uid); + + expect(c1.firstName, c2!.firstName); }); - test("Read Client", () { - clientApi.readClient(c1.uid!); - expect(c1, c1); + test("Read Client", () async { + final Client c1Bis = await clientApi.readClient(c1.uid); + expect(c1.toString(), c1Bis.toString()); }); - test("Update client", () { - clientApi.updateClient(c2); - expect(c1, c1); + test("Update client", () async { + c1.setFirstName('Filippo'); + clientApi.updateClient(c1); + final c2 = await db.doc(c1.uid).get(); + expect(c1, c2); }); test("Delete client", () { - clientApi.deleteClient(c1.uid!); - expect(c1, c1); + clientApi.deleteClient(c1.uid); + expect(db.doc(c1.uid), null); }); } diff --git a/test/default_test.dart b/test/default_test.dart deleted file mode 100644 index 9bbdb6a..0000000 --- a/test/default_test.dart +++ /dev/null @@ -1,14 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility in the flutter_test package. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter_test/flutter_test.dart'; - -void main() { - testWidgets('default', (WidgetTester tester) async { - expect(true, true); - }); -} diff --git a/test/dietitian_test.dart b/test/dietitian_test.dart index 2bdd9d8..cd9834d 100644 --- a/test/dietitian_test.dart +++ b/test/dietitian_test.dart @@ -1,9 +1,7 @@ import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/idietitian.dart'; import 'package:pdg_app/api/firebase_dietitian.dart'; -import 'package:pdg_app/firebase_options.dart'; import 'package:pdg_app/model/dietitian.dart'; final db = FakeFirebaseFirestore(); @@ -11,16 +9,13 @@ final db = FakeFirebaseFirestore(); void populateMockDietitian(Dietitian c) async { - await db.collection('dietitian').add(c.toJson()); + await db.collection('dietitian').add(c.toFirestore()); } void main() { late final IDietitian dietitianApi; setUp(() async { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); populateMockDietitian(d1); dietitianApi = FirebaseDietitian(); }); diff --git a/test/meal_test.dart b/test/meal_test.dart index 1ecdd52..dc97fa0 100644 --- a/test/meal_test.dart +++ b/test/meal_test.dart @@ -1,9 +1,7 @@ import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/imeal.dart'; import 'package:pdg_app/api/firebase_meal.dart'; -import 'package:pdg_app/firebase_options.dart'; import 'package:pdg_app/model/meal.dart'; final db = FakeFirebaseFirestore(); @@ -11,16 +9,13 @@ Meal m1 = Meal(hunger: 4, satiety: 5, comment: 'no comment'); void populateMockMeal(Meal c) async { - await db.collection('meal').add(c.toJson()); + await db.collection('meal').add(c.toFirestore()); } void main() { late final IMeal mealApi; setUp(() async { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); populateMockMeal(m1); mealApi = FirebaseMeal(); }); diff --git a/test/message_test.dart b/test/message_test.dart index a26778c..d649cd0 100644 --- a/test/message_test.dart +++ b/test/message_test.dart @@ -1,9 +1,7 @@ import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/imessage.dart'; import 'package:pdg_app/api/firebase_message.dart'; -import 'package:pdg_app/firebase_options.dart'; import 'package:pdg_app/model/message.dart'; final db = FakeFirebaseFirestore(); @@ -11,16 +9,13 @@ Message msg1 = Message(content: 'Bonjour', fromId: 'alice', toId: 'bob', id: ''); void populateMockMessage(Message c) async { - await db.collection('message').add(c.toJson()); + await db.collection('message').add(c.toFirestore()); } void main() { late final IMessage messageApi; setUp(() async { - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); populateMockMessage(msg1); messageApi = FirebaseMessage(); }); From d28fc45382c6c075402380df09a65a8f3a61a49d Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 09:41:30 +0200 Subject: [PATCH 05/11] create working --- lib/model/client.dart | 2 +- test/client_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/model/client.dart b/lib/model/client.dart index e96fda7..630683e 100644 --- a/lib/model/client.dart +++ b/lib/model/client.dart @@ -46,7 +46,7 @@ class Client implements IModel { @override String toString() { - return 'Client{$uid $firstName $lastName $birthDate $insurance $phoneNumber}'; + return 'Client{$firstName $lastName $birthDate $insurance $phoneNumber}'; } void setFirstName(String name) { diff --git a/test/client_test.dart b/test/client_test.dart index 561b65e..2a3d208 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -45,7 +45,7 @@ void main() { log(c2!.uid); log(c1.uid); - expect(c1.firstName, c2!.firstName); + expect(c1.toString(), c2.toString()); }); test("Read Client", () async { From bf66c11267aa9cf8f90d159b7e3e46734135e7ab Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 10:51:02 +0200 Subject: [PATCH 06/11] CLIENT WORK --- lib/api/firebase_client.dart | 7 +++--- lib/model/client.dart | 7 ++++-- test/client_test.dart | 44 ++++++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/lib/api/firebase_client.dart b/lib/api/firebase_client.dart index 79b7712..7a1d219 100644 --- a/lib/api/firebase_client.dart +++ b/lib/api/firebase_client.dart @@ -29,14 +29,13 @@ class FirebaseClient extends FirebaseAPI implements IClient { fromFirestore: Client.fromFirestore, toFirestore: (Client city, _) => city.toFirestore(), ); - final docSnapshot = await docRef.get(); final client = docSnapshot.data(); - if (client == null) { + if (client != null) { + return client; + } else { log("Doc does not exist"); throw Error(); - } else { - return client; } } diff --git a/lib/model/client.dart b/lib/model/client.dart index 630683e..6cfe88c 100644 --- a/lib/model/client.dart +++ b/lib/model/client.dart @@ -12,12 +12,13 @@ class Client implements IModel { String? insurance; Client( - {this.firstName, + {String? uid, + this.firstName, this.lastName, this.birthDate, this.insurance, this.phoneNumber}) - : uid = const Uuid().v1(); + : uid = uid ?? const Uuid().v1(); factory Client.fromFirestore( DocumentSnapshot> snapshot, @@ -25,6 +26,7 @@ class Client implements IModel { ) { final data = snapshot.data(); return Client( + uid: data?['uid'], firstName: data?['firstName'], lastName: data?['lastName'], birthDate: data?['birthDate'], @@ -36,6 +38,7 @@ class Client implements IModel { @override Map toFirestore() { return { + 'uid': firstName, if (firstName != null) 'firstName': firstName, if (lastName != null) 'lastName': lastName, if (birthDate != null) 'birthDate': birthDate, diff --git a/test/client_test.dart b/test/client_test.dart index 2a3d208..b3d2364 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -16,19 +16,17 @@ Client c3 = Client c4 = Client( firstName: 'Nelson', lastName: 'Jeanrenaud', phoneNumber: '0786834556'); -void populateMockClient(Client c) async { - await db.collection('client').add(c.toFirestore()); +Future populateMockClient(Client c) async { + await db.collection('client').doc(c.uid).set(c.toFirestore()); } void main() { late IClient clientApi; final clients = db.collection('client'); - setUp(() async { - populateMockClient(c1); + setUpAll(() async { populateMockClient(c2); populateMockClient(c3); - populateMockClient(c4); clientApi = FirebaseClient(db); }); @@ -41,27 +39,39 @@ void main() { toFirestore: (Client city, _) => city.toFirestore(), ) .get(); - final c2 = docSnapshot.data(); - log(c2!.uid); - log(c1.uid); - - expect(c1.toString(), c2.toString()); + final client = docSnapshot.data(); + expect(c1.toString(), client.toString()); }); test("Read Client", () async { - final Client c1Bis = await clientApi.readClient(c1.uid); - expect(c1.toString(), c1Bis.toString()); + final Client c2Bis = await clientApi.readClient(c2.uid); + expect(c2.toString(), c2Bis.toString()); }); test("Update client", () async { c1.setFirstName('Filippo'); clientApi.updateClient(c1); - final c2 = await db.doc(c1.uid).get(); - expect(c1, c2); + final docSnapshot = await clients + .doc(c1.uid) + .withConverter( + fromFirestore: Client.fromFirestore, + toFirestore: (Client city, _) => city.toFirestore(), + ) + .get(); + final c2 = docSnapshot.data(); + expect('Filippo', c2!.firstName); }); - test("Delete client", () { - clientApi.deleteClient(c1.uid); - expect(db.doc(c1.uid), null); + test("Delete client", () async { + clientApi.deleteClient(c3.uid); + final docSnapshot = await clients + .doc(c3.uid) + .withConverter( + fromFirestore: Client.fromFirestore, + toFirestore: (Client city, _) => city.toFirestore(), + ) + .get(); + final client = docSnapshot.data(); + expect(client, null); }); } From bfaf4adefd2bcb3e1d268991c2e12a75cfae48ff Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 13:16:24 +0200 Subject: [PATCH 07/11] AFTERCARE DONE --- lib/api/firebase_aftercare.dart | 37 +++++++++++++-------- lib/api/firebase_message.dart | 2 +- lib/model/aftercare.dart | 40 ++++++++++++++++------- test/aftercare_test.dart | 57 ++++++++++++++++++++++++--------- test/dietitian_test.dart | 2 +- test/meal_test.dart | 2 +- test/message_test.dart | 2 +- 7 files changed, 96 insertions(+), 46 deletions(-) diff --git a/lib/api/firebase_aftercare.dart b/lib/api/firebase_aftercare.dart index b3d1388..0c488a0 100644 --- a/lib/api/firebase_aftercare.dart +++ b/lib/api/firebase_aftercare.dart @@ -7,13 +7,17 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'firebase_api.dart'; class FirebaseAftercare extends FirebaseAPI implements IAftercare { - FirebaseAftercare(FirebaseFirestore db) : super(db, 'aftercare'); - + @override void createAftercare(Aftercare aftercare) { collectionReference - .add(aftercare.toJson()) + .withConverter( + fromFirestore: Aftercare.fromFirestore, + toFirestore: (Aftercare aftercare, options) => + aftercare.toFirestore()) + .doc(aftercare.uid) + .set(aftercare) .then((value) => log("Aftercare Added")) .catchError((error) { log("Failed to add aftercare: $error"); @@ -21,26 +25,26 @@ class FirebaseAftercare extends FirebaseAPI implements IAftercare { }); } - @override - void deleteAftercare(String aftercareId) { - collectionReference.doc(aftercareId).delete(); - } - @override Future readAftercare(String aftercareId) async { - final docRef = collectionReference.doc(aftercareId); - final doc = await docRef.get(); - if (!doc.exists) { + final docRef = collectionReference.doc(aftercareId).withConverter( + fromFirestore: Aftercare.fromFirestore, + toFirestore: (Aftercare city, _) => city.toFirestore(), + ); + final docSnapshot = await docRef.get(); + final aftercare = docSnapshot.data(); + if (aftercare != null) { + return aftercare; + } else { + log("Doc does not exist"); throw Error(); } - final data = doc.data() as Map; - return Aftercare.fromJson(data); } @override updateAftercare(Aftercare aftercare) { collectionReference - .doc('FAKE') + .doc(aftercare.uid) .update(aftercare.toFirestore()) .then((value) => log("Aftercare Updated")) .catchError((error) { @@ -48,4 +52,9 @@ class FirebaseAftercare extends FirebaseAPI implements IAftercare { throw Exception(error); }); } + + @override + void deleteAftercare(String aftercareId) { + collectionReference.doc(aftercareId).delete(); + } } diff --git a/lib/api/firebase_message.dart b/lib/api/firebase_message.dart index 1c2807c..cbaa579 100644 --- a/lib/api/firebase_message.dart +++ b/lib/api/firebase_message.dart @@ -12,7 +12,7 @@ class FirebaseMessage extends FirebaseAPI implements IMessage { @override void createMessage(Message message) { - messages + collectionReference .add(message.toFirestore()) .then((value) => log("Message Added")) .catchError((error) { diff --git a/lib/model/aftercare.dart b/lib/model/aftercare.dart index eab54eb..bbe85bd 100644 --- a/lib/model/aftercare.dart +++ b/lib/model/aftercare.dart @@ -1,6 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:uuid/uuid.dart'; + import 'imodel.dart'; class Aftercare implements IModel { + String uid; int? bmi; double? weight; String? diagnostic; @@ -12,7 +16,8 @@ class Aftercare implements IModel { List? documents; Aftercare( - {this.bmi, + {String? uid, + this.bmi, this.weight, this.diagnostic, this.comments, @@ -20,25 +25,32 @@ class Aftercare implements IModel { this.foodObjectives, this.startDate, this.endDate, - this.documents}); + this.documents}) + : uid = uid ?? const Uuid().v1(); - factory Aftercare.fromJson(Map aftercare) { + factory Aftercare.fromFirestore( + DocumentSnapshot> snapshot, + SnapshotOptions? options, + ) { + final data = snapshot.data(); return Aftercare( - bmi: aftercare['bmi'], - weight: aftercare['weight'], - diagnostic: aftercare['diagnostic'], - comments: aftercare['comments'], - motivations: aftercare['motivations'], - foodObjectives: aftercare['foodObjectives'], - startDate: aftercare['startDate'], - endDate: aftercare['endDate'], - documents: aftercare['documents'], + uid: data?['uid'], + bmi: data?['bmi'], + weight: data?['weight'], + diagnostic: data?['diagnostic'], + comments: data?['comments'], + motivations: data?['motivations'], + foodObjectives: data?['foodObjectives'], + startDate: data?['startDate'], + endDate: data?['endDate'], + documents: data?['documents'], ); } @override Map toFirestore() { return { + 'uid': uid, 'bmi': bmi, 'weight': weight, 'diagnostic': diagnostic, @@ -55,4 +67,8 @@ class Aftercare implements IModel { String toString() { return 'Aftercare{$bmi $comments $diagnostic $documents $endDate $foodObjectives $motivations $startDate $weight}'; } + + void setBmi(int newBmi) { + bmi = newBmi; + } } diff --git a/test/aftercare_test.dart b/test/aftercare_test.dart index ffd4f73..fef6ab3 100644 --- a/test/aftercare_test.dart +++ b/test/aftercare_test.dart @@ -2,42 +2,67 @@ import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/iaftercare.dart'; import 'package:pdg_app/api/firebase_aftercare.dart'; -import 'package:pdg_app/firebase_options.dart'; import 'package:pdg_app/model/aftercare.dart'; final db = FakeFirebaseFirestore(); Aftercare a1 = Aftercare(bmi: 12, weight: 14.0); - +Aftercare a2 = Aftercare(bmi: 13, weight: 14.0); void populateMockAftercare(Aftercare c) async { - await db.collection('aftercare').add(c.toFirestore()); + await db.collection('aftercare').doc(c.uid).set(c.toFirestore()); } void main() { - late final IAftercare aftercareApi; + late IAftercare aftercareApi; + final aftercares = db.collection('aftercare'); setUp(() async { - populateMockAftercare(a1); - aftercareApi = FirebaseAftercare(); + populateMockAftercare(a2); + aftercareApi = FirebaseAftercare(db); }); - test("Create Aftercare", () { + test("Create Aftercare", () async { aftercareApi.createAftercare(a1); - expect(a1, a1); + final docSnapshot = await aftercares + .doc(a1.uid) + .withConverter( + fromFirestore: Aftercare.fromFirestore, + toFirestore: (Aftercare city, _) => city.toFirestore(), + ) + .get(); + final aftercare = docSnapshot.data(); + expect(a1.toString(), aftercare.toString()); }); - test("Read Aftercare", () { - aftercareApi.readAftercare('fd'); - expect(a1, a1); + test("Read Aftercare", () async { + final Aftercare a2Bis = await aftercareApi.readAftercare(a2.uid); + expect(a2.toString(), a2Bis.toString()); }); - test("Update aftercare", () { + test("Update aftercare", () async { + a1.setBmi(18); aftercareApi.updateAftercare(a1); - expect(a1, a1); + final docSnapshot = await aftercares + .doc(a1.uid) + .withConverter( + fromFirestore: Aftercare.fromFirestore, + toFirestore: (Aftercare city, _) => city.toFirestore(), + ) + .get(); + final c2 = docSnapshot.data(); + expect(18, c2!.bmi); }); - test("Delete aftercare", () { - aftercareApi.deleteAftercare(''); - expect(a1, a1); + test("Delete aftercare", () async { + aftercareApi.deleteAftercare(a1.uid); + final docSnapshot = await aftercares + .doc(a1.uid) + .withConverter( + fromFirestore: Aftercare.fromFirestore, + toFirestore: (Aftercare city, _) => city.toFirestore(), + ) + .get(); + final aftercare = docSnapshot.data(); + expect(aftercare, null); }); } diff --git a/test/dietitian_test.dart b/test/dietitian_test.dart index cd9834d..0ef4728 100644 --- a/test/dietitian_test.dart +++ b/test/dietitian_test.dart @@ -17,7 +17,7 @@ void main() { setUp(() async { populateMockDietitian(d1); - dietitianApi = FirebaseDietitian(); + dietitianApi = FirebaseDietitian(db); }); test("Create Dietitian", () { diff --git a/test/meal_test.dart b/test/meal_test.dart index dc97fa0..f8d35a5 100644 --- a/test/meal_test.dart +++ b/test/meal_test.dart @@ -17,7 +17,7 @@ void main() { setUp(() async { populateMockMeal(m1); - mealApi = FirebaseMeal(); + mealApi = FirebaseMeal(db); }); test("Create Meal", () { diff --git a/test/message_test.dart b/test/message_test.dart index d649cd0..cf4732a 100644 --- a/test/message_test.dart +++ b/test/message_test.dart @@ -17,7 +17,7 @@ void main() { setUp(() async { populateMockMessage(msg1); - messageApi = FirebaseMessage(); + messageApi = FirebaseMessage(db); }); test("Create Message", () { From 308ca8951c88e7cd6a01486ea281d3d6c02e6f68 Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 13:24:30 +0200 Subject: [PATCH 08/11] DIETITIAN DONE --- lib/api/firebase_dietitian.dart | 23 +++++++++---- lib/model/dietitian.dart | 31 +++++++++++------ test/dietitian_test.dart | 60 ++++++++++++++++++++++++--------- 3 files changed, 81 insertions(+), 33 deletions(-) diff --git a/lib/api/firebase_dietitian.dart b/lib/api/firebase_dietitian.dart index 9a42e00..e80df64 100644 --- a/lib/api/firebase_dietitian.dart +++ b/lib/api/firebase_dietitian.dart @@ -13,7 +13,11 @@ class FirebaseDietitian extends FirebaseAPI implements IDietitian { @override void createDietitian(Dietitian dietitian) { collectionReference - .add(dietitian.toJson()) + .withConverter( + fromFirestore: Dietitian.fromFirestore, + toFirestore: (Dietitian dietitian, options) => dietitian.toFirestore()) + .doc(dietitian.uid) + .set(dietitian) .then((value) => log("Dietitian Added")) .catchError((error) { log("Failed to add dietitian: $error"); @@ -23,19 +27,24 @@ class FirebaseDietitian extends FirebaseAPI implements IDietitian { @override Future readDietitian(String dietitianId) async { - final docRef = collectionReference.doc(dietitianId); - final doc = await docRef.get(); - if (!doc.exists) { + final docRef = collectionReference.doc(dietitianId).withConverter( + fromFirestore: Dietitian.fromFirestore, + toFirestore: (Dietitian city, _) => city.toFirestore(), + ); + final docSnapshot = await docRef.get(); + final dietitian = docSnapshot.data(); + if (dietitian != null) { + return dietitian; + } else { + log("Doc does not exist"); throw Error(); } - final data = doc.data() as Map; - return Dietitian.fromJson(data); } @override void updateDietitian(Dietitian dietitian) { collectionReference - .doc('FAKE') + .doc(dietitian.uid) .update(dietitian.toFirestore()) .then((value) => log("Dietitian Updated")) .catchError((error) { diff --git a/lib/model/dietitian.dart b/lib/model/dietitian.dart index 0657713..8cc695a 100644 --- a/lib/model/dietitian.dart +++ b/lib/model/dietitian.dart @@ -1,7 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:uuid/uuid.dart'; + import 'imodel.dart'; class Dietitian implements IModel { - String? uid; + String uid; String? firstName; String? lastName; List? clientList; @@ -9,21 +12,26 @@ class Dietitian implements IModel { String? avs; Dietitian( - {this.uid, + {String? uid, this.firstName, this.lastName, this.clientList, this.avs, - this.birthDate}); + this.birthDate}) + : uid = uid ?? const Uuid().v1(); - factory Dietitian.fromJson(Map dietitian) { + factory Dietitian.fromFirestore( + DocumentSnapshot> snapshot, + SnapshotOptions? options, + ) { + final data = snapshot.data(); return Dietitian( - uid: dietitian['uid'], - firstName: dietitian['firstName'], - lastName: dietitian['lastName'], - clientList: dietitian['clientList'], - avs: dietitian['avs'], - birthDate: dietitian['birthDate'], + uid: data?['uid'], + firstName: data?['firstName'], + lastName: data?['lastName'], + clientList: data?['clientList'], + avs: data?['avs'], + birthDate: data?['birthDate'], ); } @@ -44,4 +52,7 @@ class Dietitian implements IModel { return 'Dietitian{$firstName $lastName $clientList $avs $birthDate}'; } + void setFirstName(String name) { + firstName = name; + } } diff --git a/test/dietitian_test.dart b/test/dietitian_test.dart index 0ef4728..935fbb4 100644 --- a/test/dietitian_test.dart +++ b/test/dietitian_test.dart @@ -5,38 +5,66 @@ import 'package:pdg_app/api/firebase_dietitian.dart'; import 'package:pdg_app/model/dietitian.dart'; final db = FakeFirebaseFirestore(); - Dietitian d1 = Dietitian(firstName: 'Claire', lastName: 'Emery', uid: '1'); + Dietitian d1 = Dietitian(firstName: 'Claire', lastName: 'Emery'); + Dietitian d2 = Dietitian(firstName: 'Alice', lastName: 'Emery'); -void populateMockDietitian(Dietitian c) async { - await db.collection('dietitian').add(c.toFirestore()); + +Future populateMockDietitian(Dietitian d) async { + await db.collection('dietitian').doc(d.uid).set(d.toFirestore()); } void main() { - late final IDietitian dietitianApi; + late IDietitian dietitianApi; + final dietitians = db.collection('dietitian'); - setUp(() async { - populateMockDietitian(d1); + setUpAll(() async { + populateMockDietitian(d2); dietitianApi = FirebaseDietitian(db); }); - test("Create Dietitian", () { + test("Create Dietitian", () async { dietitianApi.createDietitian(d1); - expect(d1, d1); + final docSnapshot = await dietitians + .doc(d1.uid) + .withConverter( + fromFirestore: Dietitian.fromFirestore, + toFirestore: (Dietitian city, _) => city.toFirestore(), + ) + .get(); + final dietitian = docSnapshot.data(); + expect(d1.toString(), dietitian.toString()); }); - test("Read Dietitian", () { - dietitianApi.readDietitian(d1.uid!); - expect(d1, d1); + test("Read Dietitian", () async { + final Dietitian c2Bis = await dietitianApi.readDietitian(d2.uid); + expect(d2.toString(), c2Bis.toString()); }); - test("Update dietitian", () { + test("Update dietitian", () async { + d1.setFirstName('Filippo'); dietitianApi.updateDietitian(d1); - expect(d1, d1); + final docSnapshot = await dietitians + .doc(d1.uid) + .withConverter( + fromFirestore: Dietitian.fromFirestore, + toFirestore: (Dietitian city, _) => city.toFirestore(), + ) + .get(); + final c2 = docSnapshot.data(); + expect('Filippo', c2!.firstName); }); - test("Delete dietitian", () { - dietitianApi.deleteDietitian(d1.uid!); - expect(d1, d1); + test("Delete dietitian", () async { + dietitianApi.deleteDietitian(d2.uid); + final docSnapshot = await dietitians + .doc(d2.uid) + .withConverter( + fromFirestore: Dietitian.fromFirestore, + toFirestore: (Dietitian city, _) => city.toFirestore(), + ) + .get(); + final dietitian = docSnapshot.data(); + expect(dietitian, null); }); } From e2bb3b05bf72cb5d7636165233b5fb529024cc65 Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 13:43:11 +0200 Subject: [PATCH 09/11] MEAL DONE --- lib/api/firebase_meal.dart | 38 ++++++++++++++++---------- lib/model/meal.dart | 38 ++++++++++++++++++-------- test/aftercare_test.dart | 2 +- test/client_test.dart | 4 +-- test/dietitian_test.dart | 4 +-- test/meal_test.dart | 56 ++++++++++++++++++++++++++++---------- 6 files changed, 96 insertions(+), 46 deletions(-) diff --git a/lib/api/firebase_meal.dart b/lib/api/firebase_meal.dart index 30cccda..c43633b 100644 --- a/lib/api/firebase_meal.dart +++ b/lib/api/firebase_meal.dart @@ -7,13 +7,16 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'firebase_api.dart'; class FirebaseMeal extends FirebaseAPI implements IMeal { - FirebaseMeal(FirebaseFirestore db) : super(db, 'meal'); @override void createMeal(Meal meal) { - meals - .add(meal.toFirestore()) + collectionReference + .withConverter( + fromFirestore: Meal.fromFirestore, + toFirestore: (Meal meal, options) => meal.toFirestore()) + .doc(meal.uid) + .set(meal) .then((value) => log("Meal Added")) .catchError((error) { log("Failed to add meal: $error"); @@ -21,26 +24,26 @@ class FirebaseMeal extends FirebaseAPI implements IMeal { }); } - @override - void deleteMeal(String mealId) { - collectionReference.doc(mealId).delete(); - } - @override Future readMeal(String mealId) async { - final docRef = collectionReference.doc(mealId); - final doc = await docRef.get(); - if (!doc.exists) { + final docRef = collectionReference.doc(mealId).withConverter( + fromFirestore: Meal.fromFirestore, + toFirestore: (Meal city, _) => city.toFirestore(), + ); + final docSnapshot = await docRef.get(); + final meal = docSnapshot.data(); + if (meal != null) { + return meal; + } else { + log("Doc does not exist"); throw Error(); } - final data = doc.data() as Map; - return Meal.fromJson(data); } @override - updateMeal(Meal meal) { + void updateMeal(Meal meal) { collectionReference - .doc('FAKE') + .doc(meal.uid) .update(meal.toFirestore()) .then((value) => log("Meal Updated")) .catchError((error) { @@ -48,4 +51,9 @@ class FirebaseMeal extends FirebaseAPI implements IMeal { throw Exception(error); }); } + + @override + void deleteMeal(String mealId) { + collectionReference.doc(mealId).delete(); + } } diff --git a/lib/model/meal.dart b/lib/model/meal.dart index 7c67cdc..1421f89 100644 --- a/lib/model/meal.dart +++ b/lib/model/meal.dart @@ -1,6 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:uuid/uuid.dart'; + import 'imodel.dart'; class Meal implements IModel { + String uid; DateTime? startTime; DateTime? endTime; String? lastName; @@ -11,31 +15,39 @@ class Meal implements IModel { String? comment; Meal( - {this.startTime, + {String? uid, + this.startTime, this.endTime, this.lastName, this.photo, this.satiety, this.hunger, this.setting, - this.comment}); + this.comment}) + : uid = uid ?? const Uuid().v1(); - factory Meal.fromJson(Map meal) { + factory Meal.fromFirestore( + DocumentSnapshot> snapshot, + SnapshotOptions? options, + ) { + final data = snapshot.data(); return Meal( - startTime: meal['startTime'], - endTime: meal['endTime'], - lastName: meal['lastName'], - photo: meal['photo'], - satiety: meal['satiety'], - hunger: meal['hunger'], - setting: meal['setting'], - comment: meal['comment'], + uid: data?['uid'], + startTime: data?['startTime'], + endTime: data?['endTime'], + lastName: data?['lastName'], + photo: data?['photo'], + satiety: data?['satiety'], + hunger: data?['hunger'], + setting: data?['setting'], + comment: data?['comment'], ); } @override Map toFirestore() { return { + 'uid': uid, 'startTime': startTime, 'endTime': endTime, 'lastName': lastName, @@ -51,4 +63,8 @@ class Meal implements IModel { String toString() { return 'Meal{$endTime $lastName $photo $satiety $hunger}'; } + + void setComment(String newComment) { + comment = newComment; + } } diff --git a/test/aftercare_test.dart b/test/aftercare_test.dart index fef6ab3..5704d82 100644 --- a/test/aftercare_test.dart +++ b/test/aftercare_test.dart @@ -27,7 +27,7 @@ void main() { .doc(a1.uid) .withConverter( fromFirestore: Aftercare.fromFirestore, - toFirestore: (Aftercare city, _) => city.toFirestore(), + toFirestore: (Aftercare aftercare, _) => aftercare.toFirestore(), ) .get(); final aftercare = docSnapshot.data(); diff --git a/test/client_test.dart b/test/client_test.dart index b3d2364..0525915 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -24,7 +24,7 @@ void main() { late IClient clientApi; final clients = db.collection('client'); - setUpAll(() async { + setUp(() async { populateMockClient(c2); populateMockClient(c3); clientApi = FirebaseClient(db); @@ -68,7 +68,7 @@ void main() { .doc(c3.uid) .withConverter( fromFirestore: Client.fromFirestore, - toFirestore: (Client city, _) => city.toFirestore(), + toFirestore: (Client client, _) => client.toFirestore(), ) .get(); final client = docSnapshot.data(); diff --git a/test/dietitian_test.dart b/test/dietitian_test.dart index 935fbb4..ce0ab14 100644 --- a/test/dietitian_test.dart +++ b/test/dietitian_test.dart @@ -18,7 +18,7 @@ void main() { late IDietitian dietitianApi; final dietitians = db.collection('dietitian'); - setUpAll(() async { + setUp(() async { populateMockDietitian(d2); dietitianApi = FirebaseDietitian(db); }); @@ -29,7 +29,7 @@ void main() { .doc(d1.uid) .withConverter( fromFirestore: Dietitian.fromFirestore, - toFirestore: (Dietitian city, _) => city.toFirestore(), + toFirestore: (Dietitian dietitian, _) => dietitian.toFirestore(), ) .get(); final dietitian = docSnapshot.data(); diff --git a/test/meal_test.dart b/test/meal_test.dart index f8d35a5..12b022f 100644 --- a/test/meal_test.dart +++ b/test/meal_test.dart @@ -6,37 +6,63 @@ import 'package:pdg_app/model/meal.dart'; final db = FakeFirebaseFirestore(); Meal m1 = Meal(hunger: 4, satiety: 5, comment: 'no comment'); +Meal m2 = Meal(hunger: 7, satiety: 2, comment: 'wow'); - -void populateMockMeal(Meal c) async { - await db.collection('meal').add(c.toFirestore()); +Future populateMockMeal(Meal c) async { + await db.collection('meal').doc(c.uid).set(c.toFirestore()); } void main() { - late final IMeal mealApi; + late IMeal mealApi; + final meals = db.collection('meal'); setUp(() async { - populateMockMeal(m1); + populateMockMeal(m2); mealApi = FirebaseMeal(db); }); - test("Create Meal", () { + test("Create Meal", () async { mealApi.createMeal(m1); - expect(m1, m1); + final docSnapshot = await meals + .doc(m1.uid) + .withConverter( + fromFirestore: Meal.fromFirestore, + toFirestore: (Meal meal, _) => meal.toFirestore(), + ) + .get(); + final meal = docSnapshot.data(); + expect(m1.toString(), meal.toString()); }); - test("Read Meal", () { - mealApi.readMeal('fd'); - expect(m1, m1); + test("Read Meal", () async { + final Meal m2Bis = await mealApi.readMeal(m2.uid); + expect(m2.toString(), m2Bis.toString()); }); - test("Update meal", () { + test("Update meal", () async { + m1.setComment('Filippo'); mealApi.updateMeal(m1); - expect(m1, m1); + final docSnapshot = await meals + .doc(m1.uid) + .withConverter( + fromFirestore: Meal.fromFirestore, + toFirestore: (Meal city, _) => city.toFirestore(), + ) + .get(); + final c2 = docSnapshot.data(); + expect('Filippo', c2!.comment); }); - test("Delete meal", () { - mealApi.deleteMeal(''); - expect(m1, m1); + test("Delete meal", () async { + mealApi.deleteMeal(m2.uid); + final docSnapshot = await meals + .doc(m2.uid) + .withConverter( + fromFirestore: Meal.fromFirestore, + toFirestore: (Meal city, _) => city.toFirestore(), + ) + .get(); + final meal = docSnapshot.data(); + expect(meal, null); }); } From f1bacc5557b56b93a79076f91eea3f9d88b6b51c Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 13:47:38 +0200 Subject: [PATCH 10/11] MESSAGE DONE --- lib/api/firebase_message.dart | 35 +++++++++++++-------- lib/main.dart | 2 +- lib/model/message.dart | 31 ++++++++++++------- test/message_test.dart | 58 +++++++++++++++++++++++++---------- 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/lib/api/firebase_message.dart b/lib/api/firebase_message.dart index cbaa579..6805b65 100644 --- a/lib/api/firebase_message.dart +++ b/lib/api/firebase_message.dart @@ -13,7 +13,11 @@ class FirebaseMessage extends FirebaseAPI implements IMessage { @override void createMessage(Message message) { collectionReference - .add(message.toFirestore()) + .withConverter( + fromFirestore: Message.fromFirestore, + toFirestore: (Message message, options) => message.toFirestore()) + .doc(message.uid) + .set(message) .then((value) => log("Message Added")) .catchError((error) { log("Failed to add message: $error"); @@ -21,26 +25,26 @@ class FirebaseMessage extends FirebaseAPI implements IMessage { }); } - @override - void deleteMessage(String messageId) { - collectionReference.doc(messageId).delete(); - } - @override Future readMessage(String messageId) async { - final docRef = collectionReference.doc(messageId); - final doc = await docRef.get(); - if (!doc.exists) { + final docRef = collectionReference.doc(messageId).withConverter( + fromFirestore: Message.fromFirestore, + toFirestore: (Message city, _) => city.toFirestore(), + ); + final docSnapshot = await docRef.get(); + final message = docSnapshot.data(); + if (message != null) { + return message; + } else { + log("Doc does not exist"); throw Error(); } - final data = doc.data() as Map; - return Message.fromJson(data); } @override - updateMessage(Message message) { + void updateMessage(Message message) { collectionReference - .doc('FAKE') + .doc(message.uid) .update(message.toFirestore()) .then((value) => log("Message Updated")) .catchError((error) { @@ -48,4 +52,9 @@ class FirebaseMessage extends FirebaseAPI implements IMessage { throw Exception(error); }); } + + @override + void deleteMessage(String messageId) { + collectionReference.doc(messageId).delete(); + } } diff --git a/lib/main.dart b/lib/main.dart index fed9c7b..94a29c2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,7 +20,7 @@ void main() async { ); IMessage msg = FirebaseMessage(FirebaseFirestore.instance); - final m1 = Message(id: '', fromId: 'alice', toId: 'bob', content: "HELLOW"); + final m1 = Message(uid: '', fromId: 'alice', toId: 'bob', content: "HELLOW"); msg.createMessage(m1); log("test"); runApp(MyApp()); diff --git a/lib/model/message.dart b/lib/model/message.dart index 7442454..e5a304b 100644 --- a/lib/model/message.dart +++ b/lib/model/message.dart @@ -1,9 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:uuid/uuid.dart'; import 'imodel.dart'; class Message implements IModel { - String id = const Uuid().v1(); + String uid = const Uuid().v1(); DateTime? time; String? fromId; String? toId; @@ -11,29 +12,33 @@ class Message implements IModel { int? type; Message({ - required this.id, + String? uid, this.time, this.fromId, this.toId, this.content, this.type, - }); + }) : uid = uid ?? const Uuid().v1(); - factory Message.fromJson(Map message) { + factory Message.fromFirestore( + DocumentSnapshot> snapshot, + SnapshotOptions? options, + ) { + final data = snapshot.data(); return Message( - id: message['id'], - time: message['time'], - fromId: message['fromId'], - toId: message['toId'], - content: message['content'], - type: message['type'], + uid: data?['uid'], + time: data?['time'], + fromId: data?['fromId'], + toId: data?['toId'], + content: data?['content'], + type: data?['type'], ); } @override Map toFirestore() { return { - 'id': id, + 'uid': uid, 'time': time, 'fromId': fromId, 'toId': toId, @@ -46,4 +51,8 @@ class Message implements IModel { String toString() { return 'Message{$fromId $toId $content $type}'; } + + void setContent(String newContent) { + content = newContent; + } } diff --git a/test/message_test.dart b/test/message_test.dart index cf4732a..2b47c26 100644 --- a/test/message_test.dart +++ b/test/message_test.dart @@ -5,38 +5,64 @@ import 'package:pdg_app/api/firebase_message.dart'; import 'package:pdg_app/model/message.dart'; final db = FakeFirebaseFirestore(); -Message msg1 = - Message(content: 'Bonjour', fromId: 'alice', toId: 'bob', id: ''); +Message msg1 = Message(content: 'Bonjour', fromId: 'alice', toId: 'bob'); +Message msg2 = Message(content: 'ciao', fromId: 'alice', toId: 'bob'); -void populateMockMessage(Message c) async { - await db.collection('message').add(c.toFirestore()); +Future populateMockMessage(Message c) async { + await db.collection('message').doc(c.uid).set(c.toFirestore()); } void main() { - late final IMessage messageApi; + late IMessage messageApi; + final messages = db.collection('message'); setUp(() async { - populateMockMessage(msg1); + populateMockMessage(msg2); messageApi = FirebaseMessage(db); }); - test("Create Message", () { + test("Create Message", () async { messageApi.createMessage(msg1); - expect(msg1, msg1); + final docSnapshot = await messages + .doc(msg1.uid) + .withConverter( + fromFirestore: Message.fromFirestore, + toFirestore: (Message message, _) => message.toFirestore(), + ) + .get(); + final message = docSnapshot.data(); + expect(msg1.toString(), message.toString()); }); - test("Read Message", () { - messageApi.readMessage('fd'); - expect(msg1, msg1); + test("Read Message", () async { + final Message m2Bis = await messageApi.readMessage(msg2.uid); + expect(msg2.toString(), m2Bis.toString()); }); - test("Update message", () { + test("Update message", () async { + msg1.setContent('Filippo'); messageApi.updateMessage(msg1); - expect(msg1, msg1); + final docSnapshot = await messages + .doc(msg1.uid) + .withConverter( + fromFirestore: Message.fromFirestore, + toFirestore: (Message city, _) => city.toFirestore(), + ) + .get(); + final c2 = docSnapshot.data(); + expect('Filippo', c2!.content); }); - test("Delete message", () { - messageApi.deleteMessage(''); - expect(msg1, msg1); + test("Delete message", () async { + messageApi.deleteMessage(msg2.uid); + final docSnapshot = await messages + .doc(msg2.uid) + .withConverter( + fromFirestore: Message.fromFirestore, + toFirestore: (Message city, _) => city.toFirestore(), + ) + .get(); + final message = docSnapshot.data(); + expect(message, null); }); } From 043f78a889f0c1ef25f9ce61ca495f7404a2f75b Mon Sep 17 00:00:00 2001 From: Olivier D'Ancona Date: Tue, 30 Aug 2022 13:48:14 +0200 Subject: [PATCH 11/11] FIXED --- test/client_test.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/client_test.dart b/test/client_test.dart index 0525915..0cc64c8 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:pdg_app/api/iclient.dart';