import 'package:eatvio_app/features/notifications/models/notification_model.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { group('NotificationType.getTypeFromString', () { test('returns correct type for new string-based keys', () { final cases = { 'diet-cancelled': NotificationType.dietCancelled, 'entity-commented': NotificationType.entityCommented, 'comment-replied': NotificationType.commentReplied, 'phone-changed': NotificationType.phoneChanged, 'diet-started': NotificationType.dietStarted, 'personal-diet-creation-needed-to-author': NotificationType.personalDietCreationNeeded, 'chosen-plan-client-last-day-finished': NotificationType.chosenPlanClientLastDayFinished, 'chosen-plan-consultant-last-day-started': NotificationType.chosenPlanConsultantLastDayStarted, 'chosen-plan-client-last-day-started': NotificationType.chosenPlanClientLastDayStarted, 'subscription': NotificationType.subscription, 'badge-awarded': NotificationType.badgeAwarded, 'badge-revoked': NotificationType.badgeRevoked, 'diet-expired': NotificationType.dietExpired, 'consultant-request-started': NotificationType.consultantRequestStarted, 'diet-will-started-in': NotificationType.dietWillStartedIn, 'client-close-complaint-success': NotificationType.clientCloseComplaintSuccess, 'complaint-to-moderation-for-user': NotificationType.complaintToModerationForUser, 'client-refund-success': NotificationType.clientRefundSuccess, 'consultant-refund-success': NotificationType.consultantRefundSuccess, 'client-reject-success': NotificationType.clientRejectSuccess, 'consultant-reject-success': NotificationType.consultantRejectSuccess, 'score-added': NotificationType.scoreAdded, 'score-substracted': NotificationType.scoreSubstracted, 'product-status-updated-for-author': NotificationType.productStatusUpdatedForAuthor, 'diet-can-not-started': NotificationType.dietCanNotBeStarted, 'stay-on-track-to-author': NotificationType.stayOnTrackToAuthor, 'chosen-plan-started-to-client': NotificationType.chosenPlanStartedToClient, 'client-start-plan-subscription-to-subscriber': NotificationType.clientStartPlanSubscriptionToSubscriber, 'consultant-confirm-plan-subscription-to-subscriber': NotificationType.consultantConfirmPlanSubscriptionToSubscriber, 'client-paid-plan-subscription-to-author': NotificationType.clientPaidPlanSubscriptionToAuthor, 'chosen-plan-tomorrow-reminder-to-client': NotificationType.chosenPlanTomorrowReminderToClient, 'chosen-plan-tomorrow-reminder-to-consultant': NotificationType.chosenPlanTomorrowReminderToConsultant, 'chosen-plan-started-to-consultant': NotificationType.chosenPlanStartedToConsultant, 'consultant-left-diary-comment': NotificationType.consultantLeftDiaryComment, 'chosen-plan-finished-to-client': NotificationType.chosenPlanFinishedToClient, 'consultant-confirm-plan-subscription-to-author': NotificationType.consultantConfirmPlanSubscriptionToAuthor, 'client-paid-plan-subscription-to-subscriber': NotificationType.clientPaidPlanSubscriptionToSubscriber, 'client-start-plan-subscription-to-author': NotificationType.clientStartPlanSubscriptionToAuthor, 'client-cancel-plan-subscription-to-author': NotificationType.clientCancelPlanSubscriptionToAuthor, 'client-cancel-plan-subscription-to-subscriber': NotificationType.clientCancelPlanSubscriptionToSubscriber, 'user-daily-report-completed': NotificationType.userDailyReportCompleted, 'chosen-plan-finished-to-consultant': NotificationType.chosenPlanFinishedToConsultant, 'stay-on-track-to-customer': NotificationType.stayOnTrackToCustomer, 'diary-reminder-for-users': NotificationType.diaryReminderForUsers, 'personal-diet-is-defined-to-customer': NotificationType.personalDietIsDefinedToCustomer, }; cases.forEach((key, expected) { expect(NotificationType.getTypeFromString(key), expected, reason: key); }); }); test('returns correct type for legacy FQCN values', () { final cases = { 'App\\Notifications\\Plan\\PlanSubscriptionStartedToAuthor': NotificationType.planSubscriptionStartedToAuthor, 'App\\Notifications\\Plan\\PlanSubscriptionCanceledToAuthor': NotificationType.planSubscriptionCanceledToAuthor, 'App\\Notifications\\Plan\\ChosenPlanStartedToClientNotification': NotificationType.chosenPlanStartedToClientNotification, 'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToClientNotification': NotificationType.chosenPlanTomorrowReminderToClientNotification, 'App\\Notifications\\DiaryReminderNotification': NotificationType.diaryReminderNotification, 'App\\Notifications\\Plan\\ConsultantLeftComment': NotificationType.consultantLeftComment, 'App\\Notifications\\Plan\\PersonalizedDietIsDefined': NotificationType.personalizedDietIsDefined, 'App\\Notifications\\Plan\\ChosenPlanFinishedToClient': NotificationType.chosenPlanFinishedToClient, 'App\\Notifications\\Plan\\PlanSubscriptionCanceledToCustomer': NotificationType.planSubscriptionCanceledToCustomer, 'App\\Notifications\\Plan\\ChosenPlanStartedToConsultantNotification': NotificationType.chosenPlanStartedToConsultantNotification, 'App\\Notifications\\Plan\\ChosenPlanTomorrowReminderToConsultantNotification': NotificationType.chosenPlanTomorrowReminderToConsultantNotification, 'App\\Notifications\\Plan\\PlanSubscriptionPaidToAuthor': NotificationType.planSubscriptionPaidToAuthor, 'App\\Notifications\\Plan\\ChosenPlanFinishedToConsultant': NotificationType.chosenPlanFinishedToConsultant, 'App\\Notifications\\ChosenPlan\\LastDayFinishedForUser': NotificationType.chosenPlanLastDayFinishedForUser, 'App\\Notifications\\ChosenPlan\\LastDayStartedForConsultant': NotificationType.chosenPlanConsultantLastDayStarted, 'App\\Notifications\\ComplaintToModerationNotify': NotificationType.complaintToModerationForUser, 'App\\Notifications\\Comment\\Replied': NotificationType.commentReplied, 'App\\Notifications\\Score\\ScoreAdded': NotificationType.scoreAdded, 'App\\Notifications\\Comment\\EntityCommented': NotificationType.entityCommented, 'App\\Notifications\\Plan\\PlanSubscriptionExpired': NotificationType.planSubscriptionExpired, 'App\\Notifications\\Plan\\PlanSubscriptionRenewed': NotificationType.planSubscriptionRenewed, 'App\\Notifications\\Plan\\ConsultantAssigned': NotificationType.consultantAssigned, 'App\\Notifications\\Plan\\ConsultantUnassigned': NotificationType.consultantUnassigned, 'App\\Notifications\\Payment\\PaymentFailed': NotificationType.paymentFailed, 'App\\Notifications\\Payment\\PaymentSuccessful': NotificationType.paymentSuccessful, 'App\\Notifications\\Goal\\GoalAchieved': NotificationType.goalAchieved, 'App\\Notifications\\Workout\\WorkoutReminder': NotificationType.workoutReminder, 'App\\Notifications\\Meal\\MealReminder': NotificationType.mealReminder, }; cases.forEach((key, expected) { expect(NotificationType.getTypeFromString(key), expected, reason: key); }); }); test('returns unknown for unexpected type', () { expect(NotificationType.getTypeFromString('some-unknown-type'), NotificationType.unknown); }); }); group('Notification model factories', () { test('PlanSubscriptionStartedToAuthorNotification.fromJson parses basic fields', () { final json = {'plan_name': 'Plan', 'user_name': 'User', 'chat_id': 'chat-1', 'created_at': '2024-01-01T12:00:00Z'}; final notification = PlanSubscriptionStartedToAuthorNotification.fromJson(json, NotificationType.planSubscriptionStartedToAuthor, isRead: true); expect(notification.planName, 'Plan'); expect(notification.customerName, 'User'); expect(notification.chatId, 'chat-1'); expect(notification.isRead, true); expect(notification.type, NotificationType.planSubscriptionStartedToAuthor); }); test('ChosenPlanStartedToClientNotification.fromJson with default isRead', () { final json = {'plan_name': 'Plan', 'plan_id': 10, 'created_at': '2024-01-01T12:00:00Z'}; final notification = ChosenPlanStartedToClientNotification.fromJson(json, NotificationType.chosenPlanStartedToClient); expect(notification.planName, 'Plan'); expect(notification.planId, 10); expect(notification.isRead, false); expect(notification.type, NotificationType.chosenPlanStartedToClient); }); test('UnknownNotification uses default createdAt when not provided', () { final notification = UnknownNotification(type: NotificationType.unknown); expect(notification.type, NotificationType.unknown); expect(notification.isRead, true); // createdAt is initialized with epoch when not provided expect(notification.createdAt.isBefore(DateTime.now()), isTrue); }); }); }