From a09b968d263262be3f16b504c70ada2293731126 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Thu, 31 Mar 2022 23:37:09 +0545 Subject: [PATCH 1/7] Model Classes --- packages/kucc_mobile_data/.gitignore | 4 ++ .../lib/models/communities_model.dart | 49 +++++++++++++ .../lib/models/events_model.dart | 67 ++++++++++++++++++ .../lib/models/it_express_model.dart | 47 +++++++++++++ .../kucc_mobile_data/lib/models/json_map.dart | 2 + .../lib/models/membership_model.dart | 69 +++++++++++++++++++ .../lib/models/schedule_model.dart | 52 ++++++++++++++ .../lib/models/user_model.dart | 66 ++++++++++++++++++ packages/kucc_mobile_data/pubspec.yaml | 5 ++ test/widget_test.dart | 22 +----- 10 files changed, 362 insertions(+), 21 deletions(-) create mode 100644 packages/kucc_mobile_data/lib/models/communities_model.dart create mode 100644 packages/kucc_mobile_data/lib/models/events_model.dart create mode 100644 packages/kucc_mobile_data/lib/models/it_express_model.dart create mode 100644 packages/kucc_mobile_data/lib/models/json_map.dart create mode 100644 packages/kucc_mobile_data/lib/models/membership_model.dart create mode 100644 packages/kucc_mobile_data/lib/models/schedule_model.dart create mode 100644 packages/kucc_mobile_data/lib/models/user_model.dart diff --git a/packages/kucc_mobile_data/.gitignore b/packages/kucc_mobile_data/.gitignore index 9be145f..ae3d956 100644 --- a/packages/kucc_mobile_data/.gitignore +++ b/packages/kucc_mobile_data/.gitignore @@ -27,3 +27,7 @@ .dart_tool/ .packages build/ + + +#Generated +*.g.dart \ No newline at end of file diff --git a/packages/kucc_mobile_data/lib/models/communities_model.dart b/packages/kucc_mobile_data/lib/models/communities_model.dart new file mode 100644 index 0000000..4a376c9 --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/communities_model.dart @@ -0,0 +1,49 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:meta/meta.dart'; + +part 'communities_model.g.dart'; + +@immutable +@JsonSerializable() +class CommunityModel extends Equatable { + final String about; + final String image; + final String name; + final List> coordinators; + + const CommunityModel({ + required this.about, + required this.image, + required this.name, + required this.coordinators, + }); + + @override + List get props => [name, about, coordinators, image]; + + @override + String toString() { + return 'CommunityModel(about: $about, image: $image, name: $name, coordinators: $coordinators)'; + } + + CommunityModel copyWith({ + String? about, + String? image, + String? name, + List>? coordinators, + }) { + return CommunityModel( + about: about ?? this.about, + image: image ?? this.image, + name: name ?? this.name, + coordinators: coordinators ?? this.coordinators, + ); + } + + static CommunityModel fromJson(JsonMap json) => + _$CommunityModelFromJson(json); + + JsonMap tojson() => _$CommunityModelToJson(this); +} diff --git a/packages/kucc_mobile_data/lib/models/events_model.dart b/packages/kucc_mobile_data/lib/models/events_model.dart new file mode 100644 index 0000000..d8d83ff --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/events_model.dart @@ -0,0 +1,67 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:meta/meta.dart'; + +part 'events_model.g.dart'; + +@immutable +@JsonSerializable() +class EventModel extends Equatable { + const EventModel({ + required this.banner, + required this.description, + required this.endDate, + required this.startDate, + required this.label, + this.speakers, + required this.title, + required this.type, + }); + + final String banner; + final String description; + @JsonKey(name: 'end_date') + final DateTime endDate; + @JsonKey(name: 'start_date') + final DateTime startDate; + final List label; + final List>? speakers; + final String title; + final String type; + + @override + List get props => + [banner, description, endDate, startDate, label, title, type, speakers]; + + EventModel copyWith({ + String? banner, + String? description, + DateTime? endDate, + DateTime? startDate, + List? label, + List>? speakers, + String? title, + String? type, + }) { + return EventModel( + banner: banner ?? this.banner, + description: description ?? this.description, + endDate: endDate ?? this.endDate, + startDate: startDate ?? this.startDate, + label: label ?? this.label, + speakers: speakers ?? this.speakers, + title: title ?? this.title, + type: type ?? this.type, + ); + } + + @override + String toString() { + return 'EventModel(banner: $banner, description: $description, endDate: $endDate, startDate: $startDate, label: $label, speakers: $speakers, title: $title, type: $type)'; + } + + static EventModel fromJson(JsonMap json) => _$EventModelFromJson(json); + + JsonMap toJson() => _$EventModelToJson(this); +} diff --git a/packages/kucc_mobile_data/lib/models/it_express_model.dart b/packages/kucc_mobile_data/lib/models/it_express_model.dart new file mode 100644 index 0000000..82752ed --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/it_express_model.dart @@ -0,0 +1,47 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:meta/meta.dart'; + +import 'package:kucc_mobile_data/models/json_map.dart'; + +part 'it_express_model.g.dart'; + +@immutable +@JsonSerializable() +class ITExpressModel extends Equatable { + final String title; + final Uri pdf; + final String year; + final String cover; + const ITExpressModel({ + required this.title, + required this.pdf, + required this.year, + required this.cover, + }); + + @override + List get props => [title, pdf, year, cover]; + + @override + String toString() { + return 'ITExpressModel(title: $title, pdf: $pdf, year: $year, cover: $cover)'; + } + + static ITExpressModel toJson(JsonMap json) => _$ITExpressModelFromJson(json); + JsonMap fromJson() => _$ITExpressModelToJson(this); + + ITExpressModel copyWith({ + String? title, + Uri? pdf, + String? year, + String? cover, + }) { + return ITExpressModel( + title: title ?? this.title, + pdf: pdf ?? this.pdf, + year: year ?? this.year, + cover: cover ?? this.cover, + ); + } +} diff --git a/packages/kucc_mobile_data/lib/models/json_map.dart b/packages/kucc_mobile_data/lib/models/json_map.dart new file mode 100644 index 0000000..153e9ae --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/json_map.dart @@ -0,0 +1,2 @@ +/// The type definition for a JSON-serializable [Map]. +typedef JsonMap = Map; diff --git a/packages/kucc_mobile_data/lib/models/membership_model.dart b/packages/kucc_mobile_data/lib/models/membership_model.dart new file mode 100644 index 0000000..bf8a583 --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/membership_model.dart @@ -0,0 +1,69 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:meta/meta.dart'; + +part 'membership_model.g.dart'; + +@immutable +@JsonSerializable() +class MembershipModel extends Equatable { + @JsonKey(name: 'changed_date') + final DateTime changedDate; + final String document; + @JsonKey(name: 'new_membership') + final bool newMembership; + @JsonKey(name: 'requested_date') + final DateTime requestedDate; + final String status; + @JsonKey(name: 'transaction_id') + final String transactionId; + final String user; + @JsonKey(name: 'user_email') + final String userEmail; + const MembershipModel({ + required this.changedDate, + required this.document, + required this.newMembership, + required this.requestedDate, + required this.status, + required this.transactionId, + required this.user, + required this.userEmail, + }); + + @override + List get props => []; + + MembershipModel copyWith({ + DateTime? changedDate, + String? document, + bool? newMembership, + DateTime? requestedDate, + String? status, + String? transactionId, + String? user, + String? userEmail, + }) { + return MembershipModel( + changedDate: changedDate ?? this.changedDate, + document: document ?? this.document, + newMembership: newMembership ?? this.newMembership, + requestedDate: requestedDate ?? this.requestedDate, + status: status ?? this.status, + transactionId: transactionId ?? this.transactionId, + user: user ?? this.user, + userEmail: userEmail ?? this.userEmail, + ); + } + + @override + String toString() { + return 'MembershipModel(changedDate: $changedDate, document: $document, newMembership: $newMembership, requestedDate: $requestedDate, status: $status, transactionId: $transactionId, user: $user, userEmail: $userEmail)'; + } + + static MembershipModel fromJson(JsonMap json) => + _$MembershipModelFromJson(json); + + JsonMap toJson() => _$MembershipModelToJson(this); +} diff --git a/packages/kucc_mobile_data/lib/models/schedule_model.dart b/packages/kucc_mobile_data/lib/models/schedule_model.dart new file mode 100644 index 0000000..16f0130 --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/schedule_model.dart @@ -0,0 +1,52 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:meta/meta.dart'; + +part 'schedule_model.g.dart'; + +@immutable +@JsonSerializable() +class ScheduleModel extends Equatable { + final String description; + @JsonKey(name: 'end_time') + final DateTime endTime; + final String event; + @JsonKey(name: 'start_time') + final DateTime startTime; + final String title; + const ScheduleModel({ + required this.description, + required this.endTime, + required this.event, + required this.startTime, + required this.title, + }); + + @override + List get props => []; + + ScheduleModel copyWith({ + String? description, + DateTime? endTime, + String? event, + DateTime? startTime, + String? title, + }) { + return ScheduleModel( + description: description ?? this.description, + endTime: endTime ?? this.endTime, + event: event ?? this.event, + startTime: startTime ?? this.startTime, + title: title ?? this.title, + ); + } + + @override + String toString() { + return 'ScheduleModel(description: $description, endTime: $endTime, event: $event, startTime: $startTime, title: $title)'; + } + + static ScheduleModel fromJson(JsonMap json) => _$ScheduleModelFromJson(json); + JsonMap toJson() => _$ScheduleModelToJson(this); +} diff --git a/packages/kucc_mobile_data/lib/models/user_model.dart b/packages/kucc_mobile_data/lib/models/user_model.dart new file mode 100644 index 0000000..441489c --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/user_model.dart @@ -0,0 +1,66 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:meta/meta.dart'; + +import 'json_map.dart'; + +part 'user_model.g.dart'; + +@immutable +@JsonSerializable() +class UserModel extends Equatable { + const UserModel( + {required this.batchOf, + required this.email, + required this.fullName, + required this.isAlumni, + required this.isKUStudent, + required this.isMemeber, + required this.profilePhoto}); + + @JsonKey(name: 'batch_of') + final String batchOf; + final String email; + @JsonKey(name: 'full_name') + final String fullName; + @JsonKey(name: 'is_alumni') + final bool isAlumni; + @JsonKey(name: 'is_ku_student') + final bool isKUStudent; + @JsonKey(name: 'is_member') + final bool isMemeber; + @JsonKey(name: 'profile_photo') + final String profilePhoto; + + static UserModel fromJson(JsonMap json) => _$UserModelFromJson(json); + + JsonMap toJson() => _$UserModelToJson(this); + + @override + List get props => [email]; + + UserModel copyWith({ + String? batchOf, + String? email, + String? fullName, + bool? isAlumni, + bool? isKUStudent, + bool? isMemeber, + String? profilePhoto, + }) { + return UserModel( + batchOf: batchOf ?? this.batchOf, + email: email ?? this.email, + fullName: fullName ?? this.fullName, + isAlumni: isAlumni ?? this.isAlumni, + isKUStudent: isKUStudent ?? this.isKUStudent, + isMemeber: isMemeber ?? this.isMemeber, + profilePhoto: profilePhoto ?? this.profilePhoto, + ); + } + + @override + String toString() { + return 'UserModel(batchOf: $batchOf, email: $email, fullName: $fullName, isAlumni: $isAlumni, isKUStudent: $isKUStudent, isMemeber: $isMemeber, profilePhoto: $profilePhoto)'; + } +} diff --git a/packages/kucc_mobile_data/pubspec.yaml b/packages/kucc_mobile_data/pubspec.yaml index 8f45e2f..202b271 100644 --- a/packages/kucc_mobile_data/pubspec.yaml +++ b/packages/kucc_mobile_data/pubspec.yaml @@ -8,13 +8,18 @@ environment: flutter: ">=1.17.0" dependencies: + equatable: ^2.0.3 flutter: sdk: flutter + json_annotation: ^4.4.0 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 + test: ^1.19.5 + json_serializable: ^6.1.5 + build_runner: ^2.1.8 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/test/widget_test.dart b/test/widget_test.dart index 2779a33..570e0e4 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -5,24 +5,4 @@ // 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'; -import 'package:kucc_mobile/app/app.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const App()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - // await tester.tap(find.byIcon(Icons.add)); - // await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsNothing); - }); -} +void main() {} From 697be57be55e4b02660afe7245c40198f2b2c321 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Fri, 1 Apr 2022 13:12:34 +0545 Subject: [PATCH 2/7] Data Interfaces --- .../lib/data/communities_data.dart | 9 ++++++++ .../lib/data/events_data.dart | 21 +++++++++++++++++++ .../lib/data/it_express_data.dart | 9 ++++++++ .../lib/data/membership_data.dart | 21 +++++++++++++++++++ .../lib/data/schedule_data.dart | 9 ++++++++ .../kucc_mobile_data/lib/data/user_data.dart | 17 +++++++++++++++ .../lib/kucc_mobile_data.dart | 20 +++++++++++++----- .../test/kucc_mobile_data_test.dart | 9 +------- pubspec.lock | 9 +++++++- 9 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 packages/kucc_mobile_data/lib/data/communities_data.dart create mode 100644 packages/kucc_mobile_data/lib/data/events_data.dart create mode 100644 packages/kucc_mobile_data/lib/data/it_express_data.dart create mode 100644 packages/kucc_mobile_data/lib/data/membership_data.dart create mode 100644 packages/kucc_mobile_data/lib/data/schedule_data.dart create mode 100644 packages/kucc_mobile_data/lib/data/user_data.dart diff --git a/packages/kucc_mobile_data/lib/data/communities_data.dart b/packages/kucc_mobile_data/lib/data/communities_data.dart new file mode 100644 index 0000000..cf21792 --- /dev/null +++ b/packages/kucc_mobile_data/lib/data/communities_data.dart @@ -0,0 +1,9 @@ +import '../models/communities_model.dart'; + +class CommunityFetchError implements Exception {} + +abstract class CommmunityData { + const CommmunityData(); + + Future> getAllCommunities(); +} diff --git a/packages/kucc_mobile_data/lib/data/events_data.dart b/packages/kucc_mobile_data/lib/data/events_data.dart new file mode 100644 index 0000000..942d754 --- /dev/null +++ b/packages/kucc_mobile_data/lib/data/events_data.dart @@ -0,0 +1,21 @@ +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class EventsError implements Exception {} + +class RSVPCheckError extends EventsError {} + +class RSVPCreateError extends EventsError {} + +class EventFetchError extends EventsError {} + +abstract class EventData { + const EventData(); + + Future> getAllEvents(); + + Future> getEventsOfCommunity(String cid); + + Future checkRSVP(String uid); + + Future createRSVP(String uid, String eid); +} diff --git a/packages/kucc_mobile_data/lib/data/it_express_data.dart b/packages/kucc_mobile_data/lib/data/it_express_data.dart new file mode 100644 index 0000000..4767909 --- /dev/null +++ b/packages/kucc_mobile_data/lib/data/it_express_data.dart @@ -0,0 +1,9 @@ +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class ITExpressFetchException implements Exception {} + +abstract class ITExpressData { + const ITExpressData(); + + Future> fetchAllITExpress(); +} diff --git a/packages/kucc_mobile_data/lib/data/membership_data.dart b/packages/kucc_mobile_data/lib/data/membership_data.dart new file mode 100644 index 0000000..64dae73 --- /dev/null +++ b/packages/kucc_mobile_data/lib/data/membership_data.dart @@ -0,0 +1,21 @@ +import 'dart:io'; + +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +abstract class MembershipError implements Exception {} + +class MembershipUpdateFailed extends MembershipError {} + +class MembershipApplicationFailed extends MembershipError {} + +abstract class MembershipData { + const MembershipData(); + + Future getMembershipDetail(String uid); + + Future checkMembershipStatus(String uid); + + Future applyForMembership(String uid, MembershipModel membershipDetail); + + Future updateMembership(String mid, String txID, File document); +} diff --git a/packages/kucc_mobile_data/lib/data/schedule_data.dart b/packages/kucc_mobile_data/lib/data/schedule_data.dart new file mode 100644 index 0000000..aeb2e03 --- /dev/null +++ b/packages/kucc_mobile_data/lib/data/schedule_data.dart @@ -0,0 +1,9 @@ +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class ScheduleFetchError implements Exception {} + +abstract class ScheduleData { + const ScheduleData(); + + Stream> getScheduleOfEvent(String eid); +} diff --git a/packages/kucc_mobile_data/lib/data/user_data.dart b/packages/kucc_mobile_data/lib/data/user_data.dart new file mode 100644 index 0000000..a40d448 --- /dev/null +++ b/packages/kucc_mobile_data/lib/data/user_data.dart @@ -0,0 +1,17 @@ +import 'dart:io'; + +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +abstract class UserDataError implements Exception {} + +class ProfilePictureUpdateFailed extends UserDataError {} + +class UserDataFetchError extends UserDataError {} + +abstract class UserData { + const UserData(); + + Future getUserData(String uid); + + Future updateProfilePhoto(File file, String uid); +} diff --git a/packages/kucc_mobile_data/lib/kucc_mobile_data.dart b/packages/kucc_mobile_data/lib/kucc_mobile_data.dart index 335ecdd..eae7c91 100644 --- a/packages/kucc_mobile_data/lib/kucc_mobile_data.dart +++ b/packages/kucc_mobile_data/lib/kucc_mobile_data.dart @@ -1,7 +1,17 @@ library kucc_mobile_data; -/// A Calculator. -class Calculator { - /// Returns [value] plus 1. - int addOne(int value) => value + 1; -} +// Export Models +export 'models/communities_model.dart'; +export 'models/events_model.dart'; +export 'models/it_express_model.dart'; +export 'models/membership_model.dart'; +export 'models/schedule_model.dart'; +export 'models/user_model.dart'; + +//Export Interfaces +export 'data/communities_data.dart'; +export 'data/events_data.dart'; +export 'data/it_express_data.dart'; +export 'data/membership_data.dart'; +export 'data/schedule_data.dart'; +export 'data/user_data.dart'; diff --git a/packages/kucc_mobile_data/test/kucc_mobile_data_test.dart b/packages/kucc_mobile_data/test/kucc_mobile_data_test.dart index a398b23..0da434d 100644 --- a/packages/kucc_mobile_data/test/kucc_mobile_data_test.dart +++ b/packages/kucc_mobile_data/test/kucc_mobile_data_test.dart @@ -1,12 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:kucc_mobile_data/kucc_mobile_data.dart'; - void main() { - test('adds one to input values', () { - final calculator = Calculator(); - expect(calculator.addOne(2), 3); - expect(calculator.addOne(-7), -6); - expect(calculator.addOne(0), 1); - }); + test('adds one to input values', () {}); } diff --git a/pubspec.lock b/pubspec.lock index a74be2b..f2cf3fc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -198,6 +198,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -286,7 +293,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" typed_data: dependency: transitive description: From c5814462bd50ec6f44b9465c79d81b6f03edce57 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Fri, 1 Apr 2022 16:13:50 +0545 Subject: [PATCH 3/7] Google Signin Firebase Data Source Implemented --- .../lib/data/communities_data.dart | 4 +- .../lib/firebase/authentication_firebase.dart | 31 +++++++++ .../lib/firebase/community_firebase.dart | 19 +++++ .../lib/firebase/schedule_firebase.dart | 0 .../lib/kucc_mobile_firebase.dart | 7 +- packages/kucc_mobile_firebase/pubspec.yaml | 6 ++ .../authentication_firebase_test.dart | 69 +++++++++++++++++++ .../test/kucc_mobile_firebase_test.dart | 9 +-- pubspec.lock | 7 ++ 9 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 packages/kucc_mobile_firebase/lib/firebase/authentication_firebase.dart create mode 100644 packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart create mode 100644 packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart create mode 100644 packages/kucc_mobile_firebase/test/firebase/authentication_firebase_test.dart diff --git a/packages/kucc_mobile_data/lib/data/communities_data.dart b/packages/kucc_mobile_data/lib/data/communities_data.dart index cf21792..acac816 100644 --- a/packages/kucc_mobile_data/lib/data/communities_data.dart +++ b/packages/kucc_mobile_data/lib/data/communities_data.dart @@ -2,8 +2,8 @@ import '../models/communities_model.dart'; class CommunityFetchError implements Exception {} -abstract class CommmunityData { - const CommmunityData(); +abstract class CommunityData { + const CommunityData(); Future> getAllCommunities(); } diff --git a/packages/kucc_mobile_firebase/lib/firebase/authentication_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/authentication_firebase.dart new file mode 100644 index 0000000..8c35188 --- /dev/null +++ b/packages/kucc_mobile_firebase/lib/firebase/authentication_firebase.dart @@ -0,0 +1,31 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +class AuthenticationFirebaseData { + AuthenticationFirebaseData(this._auth, this._googleSignIn); + final FirebaseAuth _auth; + final GoogleSignIn _googleSignIn; + + Future signInWithGoogle() async { + final GoogleSignInAccount? googleUser = await _googleSignIn.signIn(); + final GoogleSignInAuthentication? googleAuth = + await googleUser?.authentication; + final credential = GoogleAuthProvider.credential( + accessToken: googleAuth?.accessToken, + idToken: googleAuth?.idToken, + ); + return await _auth.signInWithCredential(credential); + } + + Stream authStatus() { + return _auth.authStateChanges().asyncMap((event) => event != null); + } + + Future signOut() async { + await _auth.signOut(); + } + + User? getLoggedInUser() { + return _auth.currentUser; + } +} diff --git a/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart new file mode 100644 index 0000000..1bad80c --- /dev/null +++ b/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart @@ -0,0 +1,19 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class CommunityFirebase implements CommunityData { + @override + Future> getAllCommunities() async { + QuerySnapshot documents = + await FirebaseFirestore.instance.collection('communities').get(); + List _allCommunities = documents.docs + .map( + (docs) => CommunityModel.fromJson( + docs.data() as Map, + ), + ) + .toList(); + + return _allCommunities; + } +} diff --git a/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart new file mode 100644 index 0000000..e69de29 diff --git a/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart b/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart index afa17e9..a630a35 100644 --- a/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart @@ -1,7 +1,4 @@ library kucc_mobile_firebase; -/// A Calculator. -class Calculator { - /// Returns [value] plus 1. - int addOne(int value) => value + 1; -} +export 'firebase/authentication_firebase.dart'; +export 'firebase/community_firebase.dart'; diff --git a/packages/kucc_mobile_firebase/pubspec.yaml b/packages/kucc_mobile_firebase/pubspec.yaml index 6f464c1..4ba1e65 100644 --- a/packages/kucc_mobile_firebase/pubspec.yaml +++ b/packages/kucc_mobile_firebase/pubspec.yaml @@ -8,8 +8,12 @@ environment: flutter: ">=1.17.0" dependencies: + cloud_firestore: ^3.1.11 + firebase_auth: ^3.3.12 + firebase_storage: ^10.2.10 flutter: sdk: flutter + google_sign_in: ^5.2.4 kucc_mobile_data: path: ../kucc_mobile_data/ @@ -17,6 +21,8 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 + firebase_auth_mocks: ^0.8.3 + google_sign_in_mocks: ^0.2.1 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/packages/kucc_mobile_firebase/test/firebase/authentication_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/authentication_firebase_test.dart new file mode 100644 index 0000000..942a348 --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/authentication_firebase_test.dart @@ -0,0 +1,69 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_auth_mocks/firebase_auth_mocks.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:google_sign_in_mocks/google_sign_in_mocks.dart'; +import 'package:kucc_mobile_firebase/kucc_mobile_firebase.dart'; + +void main() { + late GoogleSignIn googleSignIn = MockGoogleSignIn(); + + final user = MockUser( + isAnonymous: false, + uid: 'tgdufgishdisjfsjfijofjosjfosjfsfsdfs', + email: 'ad11021319@student.ku.edu.np', + displayName: 'Aadarsha Dhakal', + ); + late FirebaseAuth firebaseAuthInstance = MockFirebaseAuth(mockUser: user); + + group('Before Login ', () { + late AuthenticationFirebaseData authenticationFirebaseData = + AuthenticationFirebaseData(firebaseAuthInstance, googleSignIn); + + test('currentUser should return null', () async { + final currentUser = authenticationFirebaseData.getLoggedInUser(); + assert(currentUser == null); + }); + }); + + group('loginStatus Stream', () { + late AuthenticationFirebaseData authenticationFirebaseData = + AuthenticationFirebaseData(firebaseAuthInstance, googleSignIn); + + test( + 'Initially loggedInStatus should be false, after login true and after logout false', + () async { + final loggedInstatus = authenticationFirebaseData.authStatus(); + await authenticationFirebaseData.signInWithGoogle(); + await authenticationFirebaseData.signOut(); + expect(loggedInstatus, emitsInOrder([false, true, false])); + }); + }); + + group('After Login ', () { + late UserCredential result; + + late AuthenticationFirebaseData authenticationFirebaseData = + AuthenticationFirebaseData(firebaseAuthInstance, googleSignIn); + + setUp(() async { + result = await authenticationFirebaseData.signInWithGoogle(); + }); + + test('User should not be null', () async { + assert(result.user != null); + assert(result.user?.displayName == 'Aadarsha Dhakal'); + }); + + test('currentUser should not return null', () async { + final currentUser = authenticationFirebaseData.getLoggedInUser(); + assert(currentUser != null); + }); + + test('currentUser should return null after logout', () async { + await authenticationFirebaseData.signOut(); + final currentUser = authenticationFirebaseData.getLoggedInUser(); + assert(currentUser == null); + }); + }); +} diff --git a/packages/kucc_mobile_firebase/test/kucc_mobile_firebase_test.dart b/packages/kucc_mobile_firebase/test/kucc_mobile_firebase_test.dart index 38c1f54..8584fba 100644 --- a/packages/kucc_mobile_firebase/test/kucc_mobile_firebase_test.dart +++ b/packages/kucc_mobile_firebase/test/kucc_mobile_firebase_test.dart @@ -1,12 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:kucc_mobile_firebase/kucc_mobile_firebase.dart'; - void main() { - test('adds one to input values', () { - final calculator = Calculator(); - expect(calculator.addOne(2), 3); - expect(calculator.addOne(-7), -6); - expect(calculator.addOne(0), 1); - }); + test('Started', () {}); } diff --git a/pubspec.lock b/pubspec.lock index f2cf3fc..ad2b36b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -156,6 +156,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" kucc_mobile_data: dependency: "direct main" description: From 94dddc60eb74bad799b583a49b1d8283baef6091 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Sat, 2 Apr 2022 18:15:54 +0545 Subject: [PATCH 4/7] 13 Methds to implement and a lot of tests to wrte for data layer --- .../lib/firebase/community_firebase.dart | 5 ++- .../lib/firebase/events_firebase.dart | 29 +++++++++++++++++ .../lib/firebase/it_express_firebase.dart | 20 ++++++++++++ .../lib/firebase/membership_firebase.dart | 32 +++++++++++++++++++ .../lib/firebase/schedule_firebase.dart | 20 ++++++++++++ .../lib/firebase/users_firebase.dart | 19 +++++++++++ .../lib/kucc_mobile_firebase.dart | 5 +++ packages/kucc_mobile_firebase/pubspec.yaml | 2 ++ .../firebase/community_firebase_test.dart | 30 +++++++++++++++++ 9 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart create mode 100644 packages/kucc_mobile_firebase/lib/firebase/it_express_firebase.dart create mode 100644 packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart create mode 100644 packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart create mode 100644 packages/kucc_mobile_firebase/test/firebase/community_firebase_test.dart diff --git a/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart index 1bad80c..988d3db 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/community_firebase.dart @@ -2,10 +2,13 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:kucc_mobile_data/kucc_mobile_data.dart'; class CommunityFirebase implements CommunityData { + CommunityFirebase(this._firebaseFirestore); + final FirebaseFirestore _firebaseFirestore; + @override Future> getAllCommunities() async { QuerySnapshot documents = - await FirebaseFirestore.instance.collection('communities').get(); + await _firebaseFirestore.collection('communities').get(); List _allCommunities = documents.docs .map( (docs) => CommunityModel.fromJson( diff --git a/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart new file mode 100644 index 0000000..0b02847 --- /dev/null +++ b/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart @@ -0,0 +1,29 @@ +// TODO: Implement Event Firestore + +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class EventsFirebase implements EventData { + @override + Future checkRSVP(String uid) { + // TODO: implement checkRSVP + throw UnimplementedError(); + } + + @override + Future createRSVP(String uid, String eid) { + // TODO: implement createRSVP + throw UnimplementedError(); + } + + @override + Future> getAllEvents() { + // TODO: implement getAllEvents + throw UnimplementedError(); + } + + @override + Future> getEventsOfCommunity(String cid) { + // TODO: implement getEventsOfCommunity + throw UnimplementedError(); + } +} diff --git a/packages/kucc_mobile_firebase/lib/firebase/it_express_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/it_express_firebase.dart new file mode 100644 index 0000000..d4409b6 --- /dev/null +++ b/packages/kucc_mobile_firebase/lib/firebase/it_express_firebase.dart @@ -0,0 +1,20 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class ITExpressFirebase implements ITExpressData { + ITExpressFirebase(this._firebaseFirestore); + final FirebaseFirestore _firebaseFirestore; + + @override + Future> fetchAllITExpress() async { + QuerySnapshot> snapthots = + await _firebaseFirestore.collection('itexpress').get(); + return snapthots.docs + .map( + (e) => ITExpressModel.fromJson( + e.data(), + ), + ) + .toList(); + } +} diff --git a/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart new file mode 100644 index 0000000..72fd030 --- /dev/null +++ b/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart @@ -0,0 +1,32 @@ +// TODO: Implement Membership Firestore + +import 'dart:io'; + +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class MembershipFirebase implements MembershipData { + @override + Future applyForMembership( + String uid, MembershipModel membershipDetail) { + // TODO: implement applyForMembership + throw UnimplementedError(); + } + + @override + Future checkMembershipStatus(String uid) { + // TODO: implement checkMembershipStatus + throw UnimplementedError(); + } + + @override + Future getMembershipDetail(String uid) { + // TODO: implement getMembershipDetail + throw UnimplementedError(); + } + + @override + Future updateMembership(String mid, String txID, File document) { + // TODO: implement updateMembership + throw UnimplementedError(); + } +} diff --git a/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart index e69de29..5a60dc5 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart @@ -0,0 +1,20 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class ScheduleFirebase implements ScheduleData { + ScheduleFirebase(this._firebaseFirestore); + final FirebaseFirestore _firebaseFirestore; + + @override + Stream> getScheduleOfEvent(String eid) { + return _firebaseFirestore.collection('schedule').snapshots().asyncMap( + (event) => List.from( + event.docs.map( + (e) => ScheduleModel.fromJson( + e.data(), + ), + ), + ), + ); + } +} diff --git a/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart new file mode 100644 index 0000000..2daff3e --- /dev/null +++ b/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart @@ -0,0 +1,19 @@ +// TODO : Implement Users Firestore + +import 'dart:io'; + +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; + +class UsersFirebase implements UserData { + @override + Future getUserData(String uid) { + // TODO: implement getUserData + throw UnimplementedError(); + } + + @override + Future updateProfilePhoto(File file, String uid) { + // TODO: implement updateProfilePhoto + throw UnimplementedError(); + } +} diff --git a/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart b/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart index a630a35..dbb4977 100644 --- a/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/kucc_mobile_firebase.dart @@ -2,3 +2,8 @@ library kucc_mobile_firebase; export 'firebase/authentication_firebase.dart'; export 'firebase/community_firebase.dart'; +export 'firebase/events_firebase.dart'; +export 'firebase/it_express_firebase.dart'; +export 'firebase/membership_firebase.dart'; +export 'firebase/schedule_firebase.dart'; +export 'firebase/users_firebase.dart'; diff --git a/packages/kucc_mobile_firebase/pubspec.yaml b/packages/kucc_mobile_firebase/pubspec.yaml index 4ba1e65..2a3f1fb 100644 --- a/packages/kucc_mobile_firebase/pubspec.yaml +++ b/packages/kucc_mobile_firebase/pubspec.yaml @@ -23,6 +23,8 @@ dev_dependencies: flutter_lints: ^1.0.0 firebase_auth_mocks: ^0.8.3 google_sign_in_mocks: ^0.2.1 + fake_cloud_firestore: ^1.2.2 + firebase_storage_mocks: ^0.5.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/packages/kucc_mobile_firebase/test/firebase/community_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/community_firebase_test.dart new file mode 100644 index 0000000..e05bdd9 --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/community_firebase_test.dart @@ -0,0 +1,30 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:kucc_mobile_firebase/kucc_mobile_firebase.dart'; + +void main() { + late FakeFirebaseFirestore _firebaseFirestore; + late CommunityFirebase _communityFirebase; + group('Community Firebase API Test', () { + setUp(() async { + _firebaseFirestore = FakeFirebaseFirestore(); + _communityFirebase = CommunityFirebase(_firebaseFirestore); + await _firebaseFirestore.collection('communities').add({ + 'about': 'This is about', + 'coordinators': [ + { + 'email': 'aadarshadhakal01@gmail.com', + 'name': 'Aadarsha Dhakal', + } + ], + 'image': 'https://aadarshadhakal.com.np', + 'name': 'Dart Community', + }); + }); + + test('Fetch Collection Models', () async { + final res = await _communityFirebase.getAllCommunities(); + assert(res.length == 1); + }); + }); +} From 5701738b7fc32bfbf96204d3bd8e80a5e4f64309 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Sat, 2 Apr 2022 22:14:09 +0545 Subject: [PATCH 5/7] Implement Schedule Firebase and ITEXpress Firebase --- .../lib/models/it_express_model.dart | 11 +- .../lib/models/schedule_model.dart | 2 +- .../lib/firebase/schedule_firebase.dart | 6 +- .../lib/firebase/users_firebase.dart | 2 - .../firebase/it_express_firebase_test.dart | 28 ++++ .../test/firebase/schedule_firebase_test.dart | 32 +++++ pubspec.lock | 120 +++++++++++++++++- 7 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 packages/kucc_mobile_firebase/test/firebase/it_express_firebase_test.dart create mode 100644 packages/kucc_mobile_firebase/test/firebase/schedule_firebase_test.dart diff --git a/packages/kucc_mobile_data/lib/models/it_express_model.dart b/packages/kucc_mobile_data/lib/models/it_express_model.dart index 82752ed..6e895f9 100644 --- a/packages/kucc_mobile_data/lib/models/it_express_model.dart +++ b/packages/kucc_mobile_data/lib/models/it_express_model.dart @@ -10,14 +10,15 @@ part 'it_express_model.g.dart'; @JsonSerializable() class ITExpressModel extends Equatable { final String title; + @JsonKey(name: 'url') final Uri pdf; final String year; - final String cover; + final String? cover; const ITExpressModel({ required this.title, required this.pdf, required this.year, - required this.cover, + this.cover, }); @override @@ -28,8 +29,10 @@ class ITExpressModel extends Equatable { return 'ITExpressModel(title: $title, pdf: $pdf, year: $year, cover: $cover)'; } - static ITExpressModel toJson(JsonMap json) => _$ITExpressModelFromJson(json); - JsonMap fromJson() => _$ITExpressModelToJson(this); + static ITExpressModel fromJson(JsonMap json) => + _$ITExpressModelFromJson(json); + + JsonMap toJson() => _$ITExpressModelToJson(this); ITExpressModel copyWith({ String? title, diff --git a/packages/kucc_mobile_data/lib/models/schedule_model.dart b/packages/kucc_mobile_data/lib/models/schedule_model.dart index 16f0130..124fa74 100644 --- a/packages/kucc_mobile_data/lib/models/schedule_model.dart +++ b/packages/kucc_mobile_data/lib/models/schedule_model.dart @@ -24,7 +24,7 @@ class ScheduleModel extends Equatable { }); @override - List get props => []; + List get props => [title, startTime, endTime, event, description]; ScheduleModel copyWith({ String? description, diff --git a/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart index 5a60dc5..1726b30 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/schedule_firebase.dart @@ -7,7 +7,11 @@ class ScheduleFirebase implements ScheduleData { @override Stream> getScheduleOfEvent(String eid) { - return _firebaseFirestore.collection('schedule').snapshots().asyncMap( + return _firebaseFirestore + .collection('schedule') + .where('event', isEqualTo: '/events/$eid') + .snapshots() + .asyncMap( (event) => List.from( event.docs.map( (e) => ScheduleModel.fromJson( diff --git a/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart index 2daff3e..38b48ac 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart @@ -1,5 +1,3 @@ -// TODO : Implement Users Firestore - import 'dart:io'; import 'package:kucc_mobile_data/kucc_mobile_data.dart'; diff --git a/packages/kucc_mobile_firebase/test/firebase/it_express_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/it_express_firebase_test.dart new file mode 100644 index 0000000..84ff571 --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/it_express_firebase_test.dart @@ -0,0 +1,28 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; +import 'package:kucc_mobile_firebase/kucc_mobile_firebase.dart'; + +void main() { + late FakeFirebaseFirestore _firebaseFirestore; + late ITExpressFirebase _itExpressFirebase; + group('IT Express Firebase API test', () { + setUp(() async { + _firebaseFirestore = FakeFirebaseFirestore(); + _itExpressFirebase = ITExpressFirebase(_firebaseFirestore); + + await _firebaseFirestore.collection('itexpress').add({ + 'title': 'IT Express 18', + 'url': 'https://something.pdf.com/edition.pdf', + 'year': '2018', + 'cover': 'https://example.com/somephoto.jpg' + }); + }); + + test('Fetch IT Express Documents', () async { + final publications = await _itExpressFirebase.fetchAllITExpress(); + assert(publications.length == 1); + assert(publications.runtimeType == List); + }); + }); +} diff --git a/packages/kucc_mobile_firebase/test/firebase/schedule_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/schedule_firebase_test.dart new file mode 100644 index 0000000..32afb44 --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/schedule_firebase_test.dart @@ -0,0 +1,32 @@ +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; +import 'package:kucc_mobile_firebase/kucc_mobile_firebase.dart'; + +void main() { + FakeFirebaseFirestore _firebaseFirestore; + late ScheduleFirebase _scheduleFirebase; + + ScheduleModel _modelToFeedAndFetch = ScheduleModel( + description: 'This is description', + endTime: DateTime.now().add(const Duration(hours: 20)), + event: '/events/something', + startTime: DateTime.now(), + title: 'title', + ); + + group('Test Schedule Firebase API', () { + setUp(() { + _firebaseFirestore = FakeFirebaseFirestore(); + _scheduleFirebase = ScheduleFirebase(_firebaseFirestore); + _firebaseFirestore.collection('schedule').add( + _modelToFeedAndFetch.toJson(), + ); + }); + + test('Test Schedule Fetch', () async { + final schedules = _scheduleFirebase.getScheduleOfEvent('something'); + expect(schedules, emits([_modelToFeedAndFetch])); + }); + }); +} diff --git a/pubspec.lock b/pubspec.lock index ad2b36b..2a41a4b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -43,6 +43,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + cloud_firestore: + dependency: transitive + description: + name: cloud_firestore + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.11" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "5.5.2" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.11" collection: dependency: transitive description: @@ -71,6 +92,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + firebase_auth: + dependency: transitive + description: + name: firebase_auth + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.12" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "6.2.2" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.10" firebase_core: dependency: "direct main" description: @@ -84,14 +126,14 @@ packages: name: firebase_core_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.2.3" + version: "4.2.5" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.dartlang.org" source: hosted - version: "1.5.3" + version: "1.6.1" firebase_crashlytics: dependency: "direct main" description: @@ -106,6 +148,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.12" + firebase_storage: + dependency: transitive + description: + name: firebase_storage + url: "https://pub.dartlang.org" + source: hosted + version: "10.2.10" + firebase_storage_platform_interface: + dependency: transitive + description: + name: firebase_storage_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.2" + firebase_storage_web: + dependency: transitive + description: + name: firebase_storage_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.11" flutter: dependency: "direct main" description: flutter @@ -149,6 +212,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" + google_sign_in: + dependency: transitive + description: + name: google_sign_in + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.4" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.0+5" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" js: dependency: transitive description: @@ -254,6 +359,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.0.2" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1+1" sky_engine: dependency: transitive description: flutter @@ -316,5 +428,5 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=2.15.1 <3.0.0" - flutter: ">=1.17.0" + dart: ">=2.16.0 <3.0.0" + flutter: ">=2.5.0" From 9937d14e6053635ac2202f9942b16148aab7b941 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Mon, 4 Apr 2022 18:06:43 +0545 Subject: [PATCH 6/7] Implementation Done - More tests needed --- .../lib/data/events_data.dart | 7 ++- .../lib/data/membership_data.dart | 2 + .../kucc_mobile_data/lib/data/user_data.dart | 4 +- .../lib/models/attendees_model.dart | 42 +++++++++++++++++ .../lib/models/events_model.dart | 35 ++++++++------ .../lib/models/speaker_model.dart | 46 +++++++++++++++++++ packages/kucc_mobile_data/pubspec.yaml | 1 + 7 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 packages/kucc_mobile_data/lib/models/attendees_model.dart create mode 100644 packages/kucc_mobile_data/lib/models/speaker_model.dart diff --git a/packages/kucc_mobile_data/lib/data/events_data.dart b/packages/kucc_mobile_data/lib/data/events_data.dart index 942d754..047627c 100644 --- a/packages/kucc_mobile_data/lib/data/events_data.dart +++ b/packages/kucc_mobile_data/lib/data/events_data.dart @@ -1,4 +1,5 @@ import 'package:kucc_mobile_data/kucc_mobile_data.dart'; +import 'package:kucc_mobile_data/models/attendees_model.dart'; class EventsError implements Exception {} @@ -15,7 +16,11 @@ abstract class EventData { Future> getEventsOfCommunity(String cid); - Future checkRSVP(String uid); + Future checkRSVP(String uid, String eid); Future createRSVP(String uid, String eid); + + Stream rsvpCount(String eid); + + Stream> getAttendees(String eid); } diff --git a/packages/kucc_mobile_data/lib/data/membership_data.dart b/packages/kucc_mobile_data/lib/data/membership_data.dart index 64dae73..fa988ab 100644 --- a/packages/kucc_mobile_data/lib/data/membership_data.dart +++ b/packages/kucc_mobile_data/lib/data/membership_data.dart @@ -8,6 +8,8 @@ class MembershipUpdateFailed extends MembershipError {} class MembershipApplicationFailed extends MembershipError {} +class MembershipDoesNotExistError extends MembershipError {} + abstract class MembershipData { const MembershipData(); diff --git a/packages/kucc_mobile_data/lib/data/user_data.dart b/packages/kucc_mobile_data/lib/data/user_data.dart index a40d448..1baa9f2 100644 --- a/packages/kucc_mobile_data/lib/data/user_data.dart +++ b/packages/kucc_mobile_data/lib/data/user_data.dart @@ -11,7 +11,9 @@ class UserDataFetchError extends UserDataError {} abstract class UserData { const UserData(); + Future setUserData(String uid, UserModel model); + Future getUserData(String uid); - Future updateProfilePhoto(File file, String uid); + Stream updateProfilePhoto(File file, String uid); } diff --git a/packages/kucc_mobile_data/lib/models/attendees_model.dart b/packages/kucc_mobile_data/lib/models/attendees_model.dart new file mode 100644 index 0000000..c71a404 --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/attendees_model.dart @@ -0,0 +1,42 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:meta/meta.dart'; + +part 'attendees_model.g.dart'; + +@immutable +@JsonSerializable() +class AttendeeModel extends Equatable { + final String name; + final String? certificate; + final bool completed; + const AttendeeModel({ + required this.name, + this.certificate, + required this.completed, + }); + + @override + List get props => [certificate, completed, name]; + + AttendeeModel copyWith({ + String? certificate, + bool? completed, + String? name, + }) { + return AttendeeModel( + certificate: certificate ?? this.certificate, + completed: completed ?? this.completed, + name: name ?? this.name, + ); + } + + @override + String toString() => + 'Attendee(certificate: $certificate, completed: $completed, name: $name)'; + + static AttendeeModel fromJson(JsonMap json) => _$AttendeeModelFromJson(json); + + JsonMap toJson() => _$AttendeeModelToJson(this); +} diff --git a/packages/kucc_mobile_data/lib/models/events_model.dart b/packages/kucc_mobile_data/lib/models/events_model.dart index d8d83ff..01d8574 100644 --- a/packages/kucc_mobile_data/lib/models/events_model.dart +++ b/packages/kucc_mobile_data/lib/models/events_model.dart @@ -1,7 +1,8 @@ import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; -import 'package:kucc_mobile_data/models/json_map.dart'; import 'package:meta/meta.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:kucc_mobile_data/models/speaker_model.dart'; part 'events_model.g.dart'; @@ -9,9 +10,9 @@ part 'events_model.g.dart'; @JsonSerializable() class EventModel extends Equatable { const EventModel({ - required this.banner, + this.banner, required this.description, - required this.endDate, + this.endDate, required this.startDate, required this.label, this.speakers, @@ -19,20 +20,32 @@ class EventModel extends Equatable { required this.type, }); - final String banner; + final String? banner; final String description; @JsonKey(name: 'end_date') - final DateTime endDate; + final DateTime? endDate; @JsonKey(name: 'start_date') final DateTime startDate; final List label; - final List>? speakers; + final List? speakers; final String title; final String type; @override - List get props => - [banner, description, endDate, startDate, label, title, type, speakers]; + List get props => [ + banner, + description, + endDate, + startDate, + label, + title, + type, + speakers, + ]; + + static EventModel fromJson(JsonMap json) => _$EventModelFromJson(json); + + JsonMap toJson() => _$EventModelToJson(this); EventModel copyWith({ String? banner, @@ -40,7 +53,7 @@ class EventModel extends Equatable { DateTime? endDate, DateTime? startDate, List? label, - List>? speakers, + List? speakers, String? title, String? type, }) { @@ -60,8 +73,4 @@ class EventModel extends Equatable { String toString() { return 'EventModel(banner: $banner, description: $description, endDate: $endDate, startDate: $startDate, label: $label, speakers: $speakers, title: $title, type: $type)'; } - - static EventModel fromJson(JsonMap json) => _$EventModelFromJson(json); - - JsonMap toJson() => _$EventModelToJson(this); } diff --git a/packages/kucc_mobile_data/lib/models/speaker_model.dart b/packages/kucc_mobile_data/lib/models/speaker_model.dart new file mode 100644 index 0000000..37f6876 --- /dev/null +++ b/packages/kucc_mobile_data/lib/models/speaker_model.dart @@ -0,0 +1,46 @@ +import 'package:equatable/equatable.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:kucc_mobile_data/models/json_map.dart'; +import 'package:meta/meta.dart'; + +part 'speaker_model.g.dart'; + +@immutable +@JsonSerializable() +class SpeakerModel extends Equatable { + final String? designation; + final String? photo; + final String? topic; + final String? name; + const SpeakerModel({ + this.designation, + this.photo, + this.topic, + this.name, + }); + + @override + List get props => [designation, photo, topic, name]; + + static SpeakerModel fromJson(JsonMap json) => _$SpeakerModelFromJson(json); + JsonMap toJson() => _$SpeakerModelToJson(this); + + SpeakerModel copyWith({ + String? designation, + String? photo, + String? topic, + String? name, + }) { + return SpeakerModel( + designation: designation ?? this.designation, + photo: photo ?? this.photo, + topic: topic ?? this.topic, + name: name ?? this.name, + ); + } + + @override + String toString() { + return 'SpeakersModel(designation: $designation, photo: $photo, topic: $topic, name: $name)'; + } +} diff --git a/packages/kucc_mobile_data/pubspec.yaml b/packages/kucc_mobile_data/pubspec.yaml index 202b271..e705a7b 100644 --- a/packages/kucc_mobile_data/pubspec.yaml +++ b/packages/kucc_mobile_data/pubspec.yaml @@ -9,6 +9,7 @@ environment: dependencies: equatable: ^2.0.3 + firebase_storage: ^3.1.6 flutter: sdk: flutter json_annotation: ^4.4.0 From b13754866cc93f316a605466f6dfbb2d64a58186 Mon Sep 17 00:00:00 2001 From: Aadarsha Dhakal Date: Mon, 4 Apr 2022 18:07:02 +0545 Subject: [PATCH 7/7] Finished implementing Firebase APi --- .../lib/firebase/events_firebase.dart | 82 ++++++++++++++++--- .../lib/firebase/membership_firebase.dart | 51 ++++++++---- .../lib/firebase/users_firebase.dart | 34 ++++++-- .../test/firebase/events_firebase_test.dart | 13 +++ .../firebase/membership_firebase_test.dart | 1 + .../test/firebase/users_firebase_test.dart | 32 ++++++++ 6 files changed, 180 insertions(+), 33 deletions(-) create mode 100644 packages/kucc_mobile_firebase/test/firebase/events_firebase_test.dart create mode 100644 packages/kucc_mobile_firebase/test/firebase/membership_firebase_test.dart create mode 100644 packages/kucc_mobile_firebase/test/firebase/users_firebase_test.dart diff --git a/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart index 0b02847..045f31a 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/events_firebase.dart @@ -1,29 +1,85 @@ -// TODO: Implement Event Firestore - +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:kucc_mobile_data/kucc_mobile_data.dart'; +import 'package:kucc_mobile_data/models/attendees_model.dart'; class EventsFirebase implements EventData { + final FirebaseFirestore _firebaseFirestore; + EventsFirebase(this._firebaseFirestore); + @override - Future checkRSVP(String uid) { - // TODO: implement checkRSVP - throw UnimplementedError(); + Future checkRSVP(String uid, String eid) async { + DocumentSnapshot snapshot = await _firebaseFirestore + .collection('events') + .doc(eid) + .collection('attendees') + .doc(uid) + .get(); + return snapshot.exists; } @override - Future createRSVP(String uid, String eid) { - // TODO: implement createRSVP - throw UnimplementedError(); + Future createRSVP(String uid, String eid) async { + try { + await _firebaseFirestore + .collection('events') + .doc(eid) + .collection('attendees') + .doc(uid) + .set( + { + 'certificate': '', + 'completed': false, + }, + ); + } catch (e) { + throw RSVPCreateError(); + } } @override - Future> getAllEvents() { - // TODO: implement getAllEvents - throw UnimplementedError(); + Future> getAllEvents() async { + QuerySnapshot> result = + await _firebaseFirestore.collection('events').get(); + return result.docs + .map( + (e) => EventModel.fromJson( + e.data(), + ), + ) + .toList(); } + @Deprecated("Not Implemented, Thus Deprecated. LOL") @override - Future> getEventsOfCommunity(String cid) { - // TODO: implement getEventsOfCommunity + Future> getEventsOfCommunity(String cid) async { throw UnimplementedError(); } + + @override + Stream rsvpCount(String eid) { + return _firebaseFirestore + .collection('events') + .doc(eid) + .collection('attendees') + .snapshots() + .asyncMap((event) => event.size); + } + + @override + Stream> getAttendees(String eid) { + return _firebaseFirestore + .collection('events') + .doc(eid) + .collection('attendees') + .snapshots() + .asyncMap>( + (event) => event.docs + .map( + (e) => AttendeeModel.fromJson( + e.data(), + ), + ) + .toList(), + ); + } } diff --git a/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart index 72fd030..1bffdc0 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/membership_firebase.dart @@ -1,32 +1,55 @@ -// TODO: Implement Membership Firestore - import 'dart:io'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_storage/firebase_storage.dart'; import 'package:kucc_mobile_data/kucc_mobile_data.dart'; class MembershipFirebase implements MembershipData { + final FirebaseFirestore _firebaseFirestore; + final FirebaseStorage _firebaseStorage; + + MembershipFirebase(this._firebaseFirestore, this._firebaseStorage); + @override Future applyForMembership( - String uid, MembershipModel membershipDetail) { - // TODO: implement applyForMembership - throw UnimplementedError(); + String uid, MembershipModel membershipDetail) async { + await _firebaseFirestore.collection('membership').doc(uid).set( + membershipDetail.toJson(), + ); } @override - Future checkMembershipStatus(String uid) { - // TODO: implement checkMembershipStatus - throw UnimplementedError(); + Future checkMembershipStatus(String uid) async { + DocumentSnapshot snapshot = + await _firebaseFirestore.collection('membership').doc(uid).get(); + return snapshot.exists; } @override - Future getMembershipDetail(String uid) { - // TODO: implement getMembershipDetail - throw UnimplementedError(); + Future getMembershipDetail(String uid) async { + DocumentSnapshot> result = + await _firebaseFirestore.collection('membership').doc(uid).get(); + if (result.data() != null) { + return MembershipModel.fromJson(result.data()!); + } else { + throw MembershipDoesNotExistError(); + } } @override - Future updateMembership(String mid, String txID, File document) { - // TODO: implement updateMembership - throw UnimplementedError(); + Future updateMembership(String mid, String txID, File document) async { + try { + UploadTask task = + _firebaseStorage.ref('membership/$mid').putFile(document); + + await task.then((p0) async { + await _firebaseFirestore.collection('membership').doc(mid).update({ + 'transaction_id': txID, + 'document': p0.ref, + }); + }); + } on FirebaseException { + throw MembershipUpdateFailed(); + } } } diff --git a/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart b/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart index 38b48ac..80f1992 100644 --- a/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart +++ b/packages/kucc_mobile_firebase/lib/firebase/users_firebase.dart @@ -1,17 +1,39 @@ import 'dart:io'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_storage/firebase_storage.dart'; import 'package:kucc_mobile_data/kucc_mobile_data.dart'; class UsersFirebase implements UserData { + final FirebaseFirestore _firebaseFirestore; + final FirebaseStorage _firebaseStorage; + + const UsersFirebase(this._firebaseFirestore, this._firebaseStorage); + + @override + Future getUserData(String uid) async { + DocumentSnapshot> result = + await _firebaseFirestore.collection('users').doc(uid).get(); + if (result.data() != null) { + return UserModel.fromJson(result.data()!); + } else { + throw UserDataFetchError(); + } + } + @override - Future getUserData(String uid) { - // TODO: implement getUserData - throw UnimplementedError(); + Stream updateProfilePhoto(File file, String uid) { + return _firebaseStorage + .ref('users/profilephotos/$uid/') + .putFile(file) + .asStream() + .asyncMap( + (event) => (event.bytesTransferred / event.totalBytes) * 100, + ); } @override - Future updateProfilePhoto(File file, String uid) { - // TODO: implement updateProfilePhoto - throw UnimplementedError(); + Future setUserData(String uid, UserModel model) async { + await _firebaseFirestore.collection('users').doc(uid).set(model.toJson()); } } diff --git a/packages/kucc_mobile_firebase/test/firebase/events_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/events_firebase_test.dart new file mode 100644 index 0000000..503babc --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/events_firebase_test.dart @@ -0,0 +1,13 @@ +/* +TEST CASES + +1. Fetch All Events +2. Create RSVP +3. Check RSVP +4. RSVP Number Count +5. CHeck for null value in banner, end_date, speakers, +6. Fetch all attendees + +*/ + +// TODO: Write all test cases diff --git a/packages/kucc_mobile_firebase/test/firebase/membership_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/membership_firebase_test.dart new file mode 100644 index 0000000..0c6dba8 --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/membership_firebase_test.dart @@ -0,0 +1 @@ +// TODO: Add Tests \ No newline at end of file diff --git a/packages/kucc_mobile_firebase/test/firebase/users_firebase_test.dart b/packages/kucc_mobile_firebase/test/firebase/users_firebase_test.dart new file mode 100644 index 0000000..adc0ede --- /dev/null +++ b/packages/kucc_mobile_firebase/test/firebase/users_firebase_test.dart @@ -0,0 +1,32 @@ +// TODO : Add Tests + +import 'package:fake_cloud_firestore/fake_cloud_firestore.dart'; +import 'package:firebase_storage_mocks/firebase_storage_mocks.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:kucc_mobile_data/kucc_mobile_data.dart'; +import 'package:kucc_mobile_firebase/kucc_mobile_firebase.dart'; + +void main() { + FakeFirebaseFirestore _firebaseFirestore; + MockFirebaseStorage _firebaseStorage; + late UsersFirebase _userFirebase; + + const UserModel _userModeltoFetchandget = UserModel( + batchOf: '2019', + email: 'email@rmail.com', + fullName: 'fullName', + isAlumni: false, + isKUStudent: true, + isMemeber: true, + profilePhoto: 'profilePhoto'); + + group('Test User Firebase', () { + setUp(() { + _firebaseStorage = MockFirebaseStorage(); + _firebaseFirestore = FakeFirebaseFirestore(); + _userFirebase = UsersFirebase(_firebaseFirestore, _firebaseStorage); + }); + + test('Test user data', () {}); + }); +}