forked from eatvio/eatvio_app
feat(tests): fixed feed tests failing and added tests for my_diets, my_plans and recipes
This commit is contained in:
@@ -21,6 +21,8 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:network_image_mock/network_image_mock.dart';
|
||||
import 'package:visibility_detector/visibility_detector.dart';
|
||||
|
||||
import 'basic_widget_test.mocks.dart';
|
||||
|
||||
@@ -29,12 +31,13 @@ void main() {
|
||||
group('Feed Basic Widget Tests', () {
|
||||
late MockFeedRepository mockFeedRepository;
|
||||
late FeedCubit feedCubit;
|
||||
VisibilityDetectorController.instance.updateInterval = Duration.zero;
|
||||
|
||||
final testBlogPost = FeedBlogPostModel(
|
||||
id: 1,
|
||||
title: 'Test Post',
|
||||
description: 'Test description',
|
||||
image: 'base64image', // Empty to avoid network calls in tests
|
||||
image: '', // Empty - CachedNetworkImage will show errorWidget (SizedBox.shrink)
|
||||
state: 'published',
|
||||
author: const Author(authorSlug: 'author-1', authorName: 'Author Name', authorProfileIcon: '', authorIsMe: false),
|
||||
videoUrl: '',
|
||||
@@ -50,7 +53,7 @@ void main() {
|
||||
id: 2,
|
||||
title: 'Test Post 2',
|
||||
description: 'Test description 2',
|
||||
image: 'base64image', // Empty to avoid network calls in tests
|
||||
image: '', // Empty - CachedNetworkImage will show errorWidget (SizedBox.shrink)
|
||||
state: 'published',
|
||||
author: const Author(authorSlug: 'author-2', authorName: 'Author Name 2', authorProfileIcon: '', authorIsMe: false),
|
||||
videoUrl: '',
|
||||
@@ -251,26 +254,30 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('should display BlogPosts widget with loaded state', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost, testBlogPost2], isLoading: false));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost, testBlogPost2], isLoading: false));
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
// Use pump() multiple times to allow error widgets to render without waiting for network
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
// Pump frames to allow widgets to render
|
||||
// Note: VisibilityDetector creates a 500ms timer, but we don't need to wait for it
|
||||
// to complete to verify the widget structure
|
||||
await tester.pump();
|
||||
|
||||
// Assert - Verify state and widget structure
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.feedBlogPostList.length, 2);
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
// ListView should be present in loaded state
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
// Assert - Verify state and widget structure
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.feedBlogPostList.length, 2);
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
// ListView should be present in loaded state
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
});
|
||||
// Pump one more time after mockNetworkImagesFor to allow any pending timers to complete
|
||||
await tester.pump(const Duration(milliseconds: 600));
|
||||
});
|
||||
|
||||
testWidgets('should display BlogPosts widget with error state', (WidgetTester tester) async {
|
||||
@@ -282,7 +289,6 @@ void main() {
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateError>());
|
||||
@@ -300,7 +306,8 @@ void main() {
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
@@ -311,22 +318,23 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('should display BlogPosts with loading indicator when isLoading is true', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: true));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: true));
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.isLoading, true);
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.isLoading, true);
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should handle chip selection with multiple chips', (WidgetTester tester) async {
|
||||
@@ -366,28 +374,29 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('should handle BlogPosts refresh', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: false));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: false));
|
||||
|
||||
when(mockFeedRepository.getFeedBlogPosts(query: null)).thenAnswer(
|
||||
(_) async => FeedBlogPostSettingsModel(
|
||||
feedBlogPostList: [testBlogPost, testBlogPost2],
|
||||
meta: const Meta(currentPage: 1, lastPage: 1, total: 2, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
|
||||
),
|
||||
);
|
||||
when(mockFeedRepository.getFeedBlogPosts(query: null)).thenAnswer(
|
||||
(_) async => FeedBlogPostSettingsModel(
|
||||
feedBlogPostList: [testBlogPost, testBlogPost2],
|
||||
meta: const Meta(currentPage: 1, lastPage: 1, total: 2, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
|
||||
),
|
||||
);
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Act - Verify refresh indicator exists
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
// Act - Verify refresh indicator exists
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should display ChipGroup with correct selected chip', (WidgetTester tester) async {
|
||||
@@ -406,40 +415,42 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('should handle BlogPosts visibility detection', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: false));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: false));
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
|
||||
// Assert
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
// Visibility detection is handled by VisibilityDetector internally
|
||||
// Assert
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
// Visibility detection is handled by VisibilityDetector internally
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should display BlogPosts with multiple posts', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost, testBlogPost2], isLoading: false));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost, testBlogPost2], isLoading: false));
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.feedBlogPostList.length, 2);
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
// Assert
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.feedBlogPostList.length, 2);
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should handle ChipGroup with empty label list', (WidgetTester tester) async {
|
||||
@@ -456,21 +467,22 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('should display BlogPosts structure correctly', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: false));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: [testBlogPost], isLoading: false));
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
|
||||
// Assert
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
// Assert
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('should handle chip selection callback', (WidgetTester tester) async {
|
||||
@@ -497,24 +509,25 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('should display BlogPosts with scrollable list', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
final posts = List.generate(10, (index) => testBlogPost.copyWith(id: index + 1));
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: posts, isLoading: false));
|
||||
await mockNetworkImagesFor(() async {
|
||||
// Arrange
|
||||
final posts = List.generate(10, (index) => testBlogPost.copyWith(id: index + 1));
|
||||
feedCubit.emit(FeedState.loaded(feedBlogPostList: posts, isLoading: false));
|
||||
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
final widget = BlogPosts(handleVisibility: ({required visibleFraction, required id, required type}) {});
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
// Act
|
||||
await tester.pumpWidget(createBlogPostsTestWidget(widget));
|
||||
await tester.pump();
|
||||
|
||||
// Assert
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.feedBlogPostList.length, 10);
|
||||
// Assert
|
||||
expect(find.byType(BlogPosts), findsOneWidget);
|
||||
expect(find.byType(RefreshIndicator), findsOneWidget);
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(feedCubit.state, isA<FeedStateLoaded>());
|
||||
final loadedState = feedCubit.state as FeedStateLoaded;
|
||||
expect(loadedState.feedBlogPostList.length, 10);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user