-
Notifications
You must be signed in to change notification settings - Fork 18
Test/calendar provider #1766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Test/calendar provider #1766
Changes from all commits
91810eb
5246551
839b86e
57bcf75
8b4508f
50cc7be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,202 @@ | ||||||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||||||
| import 'package:flutter_test/flutter_test.dart'; | ||||||
| import 'package:shared_preferences/shared_preferences.dart'; | ||||||
| import 'package:uni/controller/fetchers/calendar_fetcher_json.dart'; | ||||||
| import 'package:uni/controller/local_storage/preferences_controller.dart'; | ||||||
| import 'package:uni/model/entities/app_locale.dart'; | ||||||
| import 'package:uni/model/entities/calendar_event.dart'; | ||||||
| import 'package:uni/model/providers/riverpod/calendar_provider.dart'; | ||||||
|
|
||||||
| class FakeCalendarFetcher extends CalendarFetcherJson { | ||||||
| bool throwError = false; | ||||||
|
|
||||||
| Map<String, List<CalendarEvent>> mockGroups = {'pt': [], 'en': []}; | ||||||
|
|
||||||
| @override | ||||||
| Future<List<CalendarEvent>> getCalendar(String locale) async { | ||||||
| if (throwError) { | ||||||
| throw Exception('Fetcher failed'); | ||||||
| } | ||||||
|
|
||||||
| return mockGroups[locale] ?? []; | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| void main() { | ||||||
| late ProviderContainer container; | ||||||
| late FakeCalendarFetcher fakeFetcher; | ||||||
|
|
||||||
| setUp(() async { | ||||||
| SharedPreferences.setMockInitialValues({}); | ||||||
| PreferencesController.prefs = await SharedPreferences.getInstance(); | ||||||
|
|
||||||
| fakeFetcher = FakeCalendarFetcher(); | ||||||
|
|
||||||
| container = ProviderContainer( | ||||||
| overrides: [ | ||||||
| calendarProvider.overrideWith( | ||||||
| () => CalendarNotifier(fetcher: fakeFetcher), | ||||||
| ), | ||||||
| ], | ||||||
| ); | ||||||
| addTearDown(() => container.dispose()); | ||||||
| }); | ||||||
|
|
||||||
| group('CalendarNotifier Tests', () { | ||||||
| test('Must load English event successfully', () async { | ||||||
| final event = CalendarEvent( | ||||||
| name: 'Start of classes, others', | ||||||
| startDate: DateTime.parse('2025-09-15'), | ||||||
| endDate: DateTime.parse('2025-09-15'), | ||||||
| ); | ||||||
|
|
||||||
| fakeFetcher.mockGroups['en'] = [event]; | ||||||
|
|
||||||
| final data = await container.read(calendarProvider.future); | ||||||
| expect( | ||||||
| data?.getEvents(AppLocale.en).first.name, | ||||||
| equals('Start of classes, others'), | ||||||
| ); | ||||||
| expect(data?.getEvents(AppLocale.pt), isEmpty); | ||||||
| }); | ||||||
|
|
||||||
| test('Must load Portuguese event successfully', () async { | ||||||
| final event = CalendarEvent( | ||||||
| name: 'Início de aulas, outros', | ||||||
| startDate: DateTime.parse('2025-09-15'), | ||||||
| endDate: DateTime.parse('2025-09-15'), | ||||||
| ); | ||||||
|
|
||||||
| fakeFetcher.mockGroups['pt'] = [event]; | ||||||
|
|
||||||
| final data = await container.read(calendarProvider.future); | ||||||
| expect( | ||||||
| data?.getEvents(AppLocale.pt).first.name, | ||||||
| equals('Início de aulas, outros'), | ||||||
| ); | ||||||
| expect(data?.getEvents(AppLocale.en), isEmpty); | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| test('Must return empty lists when no events are provided', () async { | ||||||
| fakeFetcher.mockGroups['en'] = []; | ||||||
| fakeFetcher.mockGroups['pt'] = []; | ||||||
|
|
||||||
| final data = await container.read(calendarProvider.future); | ||||||
|
|
||||||
| expect(data?.getEvents(AppLocale.en), isEmpty); | ||||||
| expect(data?.getEvents(AppLocale.pt), isEmpty); | ||||||
| expect(data?.getEvents(AppLocale.en).length, 0); | ||||||
| expect(data?.getEvents(AppLocale.pt).length, 0); | ||||||
| }); | ||||||
| test('Must handle fetcher error gracefully', () async { | ||||||
| fakeFetcher.throwError = true; | ||||||
|
|
||||||
| await container.read(calendarProvider.future).catchError((_) => null); | ||||||
|
|
||||||
| final state = container.read(calendarProvider); | ||||||
|
|
||||||
| expect(state.hasError, isTrue); | ||||||
| expect(state.error.toString(), contains('Fetcher failed')); | ||||||
| }); | ||||||
|
|
||||||
| test('Must reload from remote if cache is expired', () async { | ||||||
|
||||||
| final oldDate = DateTime.now().subtract(const Duration(days: 31)); | ||||||
|
||||||
| final oldDate = DateTime.now().subtract(const Duration(days: 31)); | |
| final oldDate = DateTime.now().subtract(const Duration(days: 30)); |
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The event name is in Portuguese ('Início de aulas, outros') but it's being added to the English events list (fakeFetcher.mockGroups['en']). This appears to be a copy-paste error. The event should either have an English name like 'Start of classes, others' to match the language, or should be added to the Portuguese events list instead.
Copilot
AI
Dec 27, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test name suggests it validates behavior when the language changes, but it doesn't actually test a language change scenario. The test loads data once, invalidates the provider, and loads again, but both calls would fetch both PT and EN events simultaneously (as seen in loadFromStorage). This test actually validates that provider invalidation works, not that data updates when language changes. Consider renaming the test to better reflect what it actually tests, such as 'Must reload all events when provider is invalidated'.
| test('Data must update when the language changes', () async { | |
| test('Must reload all events when provider is invalidated', () async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant test assertions. Lines 87-88 check if the lists are empty using isEmpty, and lines 89-90 check if the length is 0. These assertions are testing the same condition in different ways. Consider removing lines 89-90 as they add no additional test coverage.