From be11dc040c242ba63d911f97b4de1ed9e99c5da4 Mon Sep 17 00:00:00 2001 From: daniel-michel <65034538+daniel-michel@users.noreply.github.com> Date: Tue, 9 Jan 2024 21:52:32 +0100 Subject: [PATCH] test: more testing of the home page, MovieItem, MovieList test: add testing for MoviePage fix: remove global accidentally used instance of movie manager --- lib/main.dart | 7 ++- lib/model/live_search.dart | 3 +- lib/model/movie_manager.dart | 4 -- lib/view/movie_list.dart | 3 +- test/view/home_page_test.dart | 48 +++++++++++++-- test/view/movie_item_test.dart | 85 ++++++++++++++++++++++++++ test/view/movie_list_test.dart | 31 ++++++++++ test/view/movie_page_test.dart | 105 +++++++++++++++++++++++++++++++++ 8 files changed, 272 insertions(+), 14 deletions(-) create mode 100644 test/view/movie_page_test.dart diff --git a/lib/main.dart b/lib/main.dart index a3c0452..00d1d55 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:release_schedule/api/wikidata_movie_api.dart'; import 'package:release_schedule/model/dates.dart'; import 'package:release_schedule/model/live_search.dart'; +import 'package:release_schedule/model/local_movie_storage.dart'; import 'package:release_schedule/model/movie_manager.dart'; import 'package:release_schedule/view/movie_item.dart'; import 'package:release_schedule/view/movie_manager_list.dart'; @@ -30,7 +32,10 @@ class MyApp extends StatelessWidget { colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange), useMaterial3: true, ), - home: HomePage(movieManager), + home: HomePage( + MovieManager(WikidataMovieApi(), + LocalMovieStorageGetStorage(WikidataMovieData.fromEncodable)), + ), ); } } diff --git a/lib/model/live_search.dart b/lib/model/live_search.dart index 5fba03a..9346c08 100644 --- a/lib/model/live_search.dart +++ b/lib/model/live_search.dart @@ -42,8 +42,7 @@ class LiveSearch extends ChangeNotifier { searchingOnline = true; try { String startedSearching = searchTerm; - List onlineResults = - await movieManager.onlineSearch(searchTerm); + List onlineResults = await manager.onlineSearch(searchTerm); searchingOnline = false; // if the search term has changed since we started searching, ignore the results if (startedSearching != searchTerm) { diff --git a/lib/model/movie_manager.dart b/lib/model/movie_manager.dart index 60939fd..1952e29 100644 --- a/lib/model/movie_manager.dart +++ b/lib/model/movie_manager.dart @@ -2,15 +2,11 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:release_schedule/api/movie_api.dart'; -import 'package:release_schedule/api/wikidata_movie_api.dart'; import 'package:release_schedule/model/delayed_function_caller.dart'; import 'package:release_schedule/model/local_movie_storage.dart'; import 'package:release_schedule/model/movie.dart'; import 'package:release_schedule/model/search.dart'; -final movieManager = MovieManager(WikidataMovieApi(), - LocalMovieStorageGetStorage(WikidataMovieData.fromEncodable)); - class MovieManager extends ChangeNotifier { final List movies = List.empty(growable: true); final LocalMovieStorage cache; diff --git a/lib/view/movie_list.dart b/lib/view/movie_list.dart index 8430780..53e2ea8 100644 --- a/lib/view/movie_list.dart +++ b/lib/view/movie_list.dart @@ -150,7 +150,8 @@ class GroupedList extends StatelessWidget { List<({int index, GroupType group})> newGroupStarts = [ (index: 0, group: groupBy(0)) ]; - int internalInitialScrollIndex = initialScrollIndex + 1; + int internalInitialScrollIndex = + initialScrollIndex + (initialScrollIndex > 0 ? 1 : 0); GroupType last = newGroupStarts[0].group; for (int i = 1; i < itemCount; i++) { final GroupType current = groupBy(i); diff --git a/test/view/home_page_test.dart b/test/view/home_page_test.dart index 8ad4f63..a50e52d 100644 --- a/test/view/home_page_test.dart +++ b/test/view/home_page_test.dart @@ -2,26 +2,62 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:release_schedule/api/movie_api.dart'; import 'package:release_schedule/main.dart'; +import 'package:release_schedule/model/dates.dart'; import 'package:release_schedule/model/local_movie_storage.dart'; +import 'package:release_schedule/model/movie.dart'; import 'package:release_schedule/model/movie_manager.dart'; import 'package:release_schedule/view/movie_manager_list.dart'; void main() { group('HomePage', () { - testWidgets('displays title', (WidgetTester tester) async { - MovieManager movieManager = - MovieManager(MovieApi(), InMemoryMovieStorage()); - await tester.pumpWidget(MaterialApp(home: HomePage(movieManager))); + late LocalMovieStorage storage; + setUp(() { + storage = InMemoryMovieStorage(); + storage.update([ + MovieData( + 'The Shawshank Redemption', + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US'), + ), + MovieData( + 'The Godfather', + DateWithPrecisionAndCountry( + DateTime(1972, 3, 24), DatePrecision.day, 'US'), + ), + MovieData( + 'The Dark Knight', + DateWithPrecisionAndCountry( + DateTime(2008, 7, 18), DatePrecision.day, 'US'), + ), + ]); + }); + + testWidgets('displays search bar', (WidgetTester tester) async { + MovieManager movieManager = MovieManager(MovieApi(), storage); + await tester.pumpWidget(MaterialApp(home: HomePage(movieManager))); + await tester.pump(const Duration(seconds: 3)); expect(find.text('Search'), findsOneWidget); }); testWidgets('displays list of releases', (WidgetTester tester) async { - MovieManager movieManager = - MovieManager(MovieApi(), InMemoryMovieStorage()); + MovieManager movieManager = MovieManager(MovieApi(), storage); await tester.pumpWidget(MaterialApp(home: HomePage(movieManager))); + await tester.pump(const Duration(seconds: 3)); expect(find.byType(MovieManagerList), findsOneWidget); }); + + testWidgets('displays search results', (WidgetTester tester) async { + MovieManager movieManager = MovieManager(MovieApi(), storage); + await tester.pumpWidget(MaterialApp(home: HomePage(movieManager))); + + await tester.enterText( + find.byType(TextField), 'The Shawshank Redemption'); + await tester.pump(const Duration(seconds: 3)); + await tester.pumpAndSettle(); + + expect(find.text('The Shawshank Redemption'), findsNWidgets(2)); + }); }); } diff --git a/test/view/movie_item_test.dart b/test/view/movie_item_test.dart index a3773d8..8bb76ed 100644 --- a/test/view/movie_item_test.dart +++ b/test/view/movie_item_test.dart @@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:release_schedule/model/dates.dart'; import 'package:release_schedule/model/movie.dart'; import 'package:release_schedule/view/movie_item.dart'; +import 'package:release_schedule/view/movie_page.dart'; void main() { testWidgets('MovieItem displays movie data', (WidgetTester tester) async { @@ -56,4 +57,88 @@ void main() { expect(find.textContaining('Action, Adventure, Comedy'), findsOneWidget); }); + + testWidgets('should update when the movie is bookmarked', (tester) async { + final movie = MovieData( + 'Test Movie', + DateWithPrecisionAndCountry( + DateTime(2023, 1, 1), DatePrecision.day, 'US'), + ); + movie.setDetails( + genres: ['Action', 'Adventure'], + ); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MovieItem(movie), + ), + ), + ); + + expect(find.byIcon(Icons.bookmark_border), findsOneWidget); + + movie.setDetails( + bookmarked: true, + ); + + await tester.pump(); + + expect(find.byIcon(Icons.bookmark_added), findsOneWidget); + }); + + testWidgets("should update the bookmark state when the icon is tapped", + (tester) async { + final movie = MovieData( + 'Test Movie', + DateWithPrecisionAndCountry( + DateTime(2023, 1, 1), DatePrecision.day, 'US'), + ); + movie.setDetails( + genres: ['Action', 'Adventure'], + ); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MovieItem(movie), + ), + ), + ); + + expect(find.byIcon(Icons.bookmark_border), findsOneWidget); + + await tester.tap(find.byIcon(Icons.bookmark_outline)); + + await tester.pump(); + + expect(find.byIcon(Icons.bookmark_added), findsOneWidget); + }); + + testWidgets("should navigate to MoviePage when tapped", (tester) async { + final movie = MovieData( + 'Test Movie', + DateWithPrecisionAndCountry( + DateTime(2023, 1, 1), DatePrecision.day, 'US'), + ); + movie.setDetails( + genres: ['Action', 'Adventure'], + ); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MovieItem(movie), + ), + ), + ); + + expect(find.byIcon(Icons.bookmark_border), findsOneWidget); + + await tester.tap(find.byType(ListTile)); + + await tester.pumpAndSettle(); + + expect(find.byType(MoviePage), findsOneWidget); + }); } diff --git a/test/view/movie_list_test.dart b/test/view/movie_list_test.dart index d259e1f..bf6af9b 100644 --- a/test/view/movie_list_test.dart +++ b/test/view/movie_list_test.dart @@ -33,5 +33,36 @@ void main() { expect(find.byType(MovieItem), findsNWidgets(movies.length)); }); + + testWidgets("should filter the list of movies", + (WidgetTester tester) async { + final movies = [ + MovieData( + 'The Shawshank Redemption', + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US'), + ), + MovieData( + 'The Godfather', + DateWithPrecisionAndCountry( + DateTime(1972, 3, 24), DatePrecision.day, 'US'), + ), + ]; + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MovieList( + movies, + filter: (movie) => movie.title.contains('Godfather'), + ), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.byType(MovieItem), findsOneWidget); + }); }); } diff --git a/test/view/movie_page_test.dart b/test/view/movie_page_test.dart new file mode 100644 index 0000000..b21936c --- /dev/null +++ b/test/view/movie_page_test.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:release_schedule/model/dates.dart'; +import 'package:release_schedule/model/movie.dart'; +import 'package:release_schedule/view/movie_page.dart'; + +void main() { + group('MoviePage', () { + testWidgets('should render the movie details', (WidgetTester tester) async { + final movie = MovieData( + 'The Shawshank Redemption', + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US'), + ); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MoviePage(movie), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.text(movie.title), findsAtLeastNWidgets(1)); + }); + + testWidgets('should bookmark the movie', (WidgetTester tester) async { + final movie = MovieData( + 'The Shawshank Redemption', + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US'), + ); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MoviePage(movie), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(movie.bookmarked, isFalse); + + await tester.tap(find.byIcon(Icons.bookmark_outline)); + await tester.pumpAndSettle(); + + expect(movie.bookmarked, isTrue); + }); + }); + + testWidgets("should display the movie's genres", (WidgetTester tester) async { + final movie = MovieData( + 'The Shawshank Redemption', + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US'), + )..setDetails(genres: ['Drama']); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MoviePage(movie), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.text('Drama'), findsOneWidget); + }); + + testWidgets("should display the movie's titles and release dates", + (WidgetTester tester) async { + final movie = MovieData( + 'The Shawshank Redemption', + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US'), + )..setDetails( + titles: [(title: 'The Shawshank Redemption', language: 'en')], + releaseDates: [ + DateWithPrecisionAndCountry( + DateTime(1994, 9, 22), DatePrecision.day, 'US') + ], + ); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: MoviePage(movie), + ), + ), + ); + + await tester.pumpAndSettle(); + + expect(find.text('en'), findsOneWidget); + expect(find.text('The Shawshank Redemption'), findsNWidgets(2)); + + expect(find.text('US'), findsOneWidget); + expect(find.textContaining('1994'), findsOneWidget); + }); +}