From 14e4d7973e240e0ab62f7c9d73a89629a5d2d861 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Wed, 22 Oct 2025 18:42:01 +0300 Subject: [PATCH] feat(tests): blog post create --- .../blog_post_create_cubit.dart | 4 +-- .../advanced_widget_test.dart | 19 +++++++---- .../integration_widget_test.dart | 32 +++++++++++++------ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/lib/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart b/lib/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart index 6e93944a..2617b664 100644 --- a/lib/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart +++ b/lib/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart @@ -16,7 +16,7 @@ class BlogPostCreateCubit extends BaseCubit { return true; } catch (error, stackTrace) { handleError(error, stackTrace); - emit(const BlogPostCreateState.loaded()); + emit(BlogPostCreateState.error(errorMessage: error.toString())); return false; } } @@ -29,7 +29,7 @@ class BlogPostCreateCubit extends BaseCubit { return true; } catch (error, stackTrace) { handleError(error, stackTrace); - emit(const BlogPostCreateState.loaded()); + emit(BlogPostCreateState.error(errorMessage: error.toString())); return false; } } diff --git a/test/features/blog_post_create/advanced_widget_test.dart b/test/features/blog_post_create/advanced_widget_test.dart index 6d1c6b4a..381a1075 100644 --- a/test/features/blog_post_create/advanced_widget_test.dart +++ b/test/features/blog_post_create/advanced_widget_test.dart @@ -266,7 +266,7 @@ void main() { testWidgets('should handle loading state during blog post creation', (WidgetTester tester) async { // Arrange when(mockBlogPostRepository.createBlogPost(any, any, any, any)).thenAnswer((_) async { - await Future.delayed(const Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 50)); }); Widget loadingWidget = BlocBuilder( @@ -283,11 +283,16 @@ void main() { await tester.pumpAndSettle(); // Trigger loading state - blogPostCreateCubit.createBlogPost(title: 'Test Title', description: 'Test Description', videoUrl: null, image: null); + blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: 'Test Description', image: null); await tester.pump(); + await tester.pump(); // Need to pump twice to get the loading state // Assert expect(find.byType(CircularProgressIndicator), findsOneWidget); + + // Wait for the async operation to complete + await tester.pump(const Duration(milliseconds: 100)); + await tester.pumpAndSettle(); }); testWidgets('should handle error state during blog post creation', (WidgetTester tester) async { @@ -308,8 +313,9 @@ void main() { await tester.pumpAndSettle(); // Trigger error state - blogPostCreateCubit.createBlogPost(title: 'Test Title', description: 'Test Description', videoUrl: null, image: null); + blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: 'Test Description', image: null); await tester.pump(); + await tester.pump(); // Need to pump twice to get the error state // Assert expect(find.textContaining('Error:'), findsOneWidget); @@ -333,8 +339,9 @@ void main() { await tester.pumpAndSettle(); // Trigger success state - blogPostCreateCubit.createBlogPost(title: 'Test Title', description: 'Test Description', videoUrl: null, image: null); + blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: 'Test Description', image: null); await tester.pump(); + await tester.pump(); // Need to pump twice to get the success state // Assert expect(find.text('Blog post created successfully!'), findsOneWidget); @@ -448,7 +455,7 @@ void main() { ElevatedButton( key: AppKeys.blogPostCreateScreenCreateButton, onPressed: () async { - await blogPostCreateCubit.createBlogPost(title: '', description: '', videoUrl: '', image: null); + await blogPostCreateCubit.createBlogPost(title: '', videoUrl: '', description: '', image: null); }, child: const Text('Опубликовать'), ), @@ -492,7 +499,7 @@ void main() { ElevatedButton( key: AppKeys.blogPostCreateScreenCreateButton, onPressed: () async { - await blogPostCreateCubit.createBlogPost(title: 'Test Title', description: longContent, videoUrl: null, image: null); + await blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: longContent, image: null); }, child: const Text('Опубликовать'), ), diff --git a/test/features/blog_post_create/integration_widget_test.dart b/test/features/blog_post_create/integration_widget_test.dart index 5c0955ee..40827f21 100644 --- a/test/features/blog_post_create/integration_widget_test.dart +++ b/test/features/blog_post_create/integration_widget_test.dart @@ -6,6 +6,7 @@ import 'package:eatvio_app/features/blog_post_create/repositories/blog_post_repo import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart'; +import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -25,6 +26,10 @@ void main() { mockBlogPostRepository = MockBlogPostRepository(); mockFeedCubit = MockFeedCubit(); blogPostCreateCubit = BlogPostCreateCubit(blogPostRepository: mockBlogPostRepository); + + // Setup mock stubs for FeedCubit + when(mockFeedCubit.stream).thenAnswer((_) => Stream.value(const FeedState.loading())); + when(mockFeedCubit.close()).thenAnswer((_) async {}); }); tearDown(() { @@ -102,8 +107,8 @@ void main() { onPressed: () async { await blogPostCreateCubit.createBlogPost( title: 'Integration Test Title', - description: 'Integration Test Description', videoUrl: 'https://youtube.com/watch?v=integration', + description: 'Integration Test Description', image: null, ); }, @@ -187,8 +192,8 @@ void main() { await blogPostCreateCubit.updateBlogPost( id: existingBlogPost.id, title: 'Updated Title', - description: 'Updated Description', videoUrl: 'https://youtube.com/watch?v=updated', + description: 'Updated Description', image: null, oldImageUrl: existingBlogPost.image, ); @@ -264,7 +269,7 @@ void main() { ElevatedButton( key: const Key('retryButton'), onPressed: () async { - await blogPostCreateCubit.createBlogPost(title: 'Retry Title', description: 'Retry Description', videoUrl: null, image: null); + await blogPostCreateCubit.createBlogPost(title: 'Retry Title', videoUrl: null, description: 'Retry Description', image: null); }, child: const Text('Повторить'), ), @@ -280,7 +285,7 @@ void main() { await tester.pumpAndSettle(); // Trigger error - await blogPostCreateCubit.createBlogPost(title: 'Test Title', description: 'Test Description', videoUrl: null, image: null); + await blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: 'Test Description', image: null); await tester.pump(); // Assert @@ -291,7 +296,7 @@ void main() { testWidgets('should handle loading state during blog post creation', (WidgetTester tester) async { // Arrange when(mockBlogPostRepository.createBlogPost(any, any, any, any)).thenAnswer((_) async { - await Future.delayed(const Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 50)); }); Widget loadingFlowWidget = BlocBuilder( @@ -308,12 +313,17 @@ void main() { await tester.pumpAndSettle(); // Trigger loading - await blogPostCreateCubit.createBlogPost(title: 'Test Title', description: 'Test Description', videoUrl: null, image: null); + blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: 'Test Description', image: null); await tester.pump(); + await tester.pump(); // Need to pump twice to get the loading state // Assert expect(find.byType(CircularProgressIndicator), findsOneWidget); expect(find.text('Создание блог поста...'), findsOneWidget); + + // Wait for the async operation to complete + await tester.pump(const Duration(milliseconds: 100)); + await tester.pumpAndSettle(); }); testWidgets('should handle success state after blog post creation', (WidgetTester tester) async { @@ -348,7 +358,7 @@ void main() { await tester.pumpAndSettle(); // Trigger success - await blogPostCreateCubit.createBlogPost(title: 'Test Title', description: 'Test Description', videoUrl: null, image: null); + await blogPostCreateCubit.createBlogPost(title: 'Test Title', videoUrl: null, description: 'Test Description', image: null); await tester.pump(); // Assert @@ -429,8 +439,8 @@ void main() { onPressed: () async { await blogPostCreateCubit.createBlogPost( title: 'Test Title', - description: 'Test Description', videoUrl: null, + description: 'Test Description', image: null, // В реальном тесте здесь был бы XFile ); }, @@ -508,8 +518,8 @@ void main() { onPressed: () async { await blogPostCreateCubit.createBlogPost( title: 'Complete Test Title', - description: 'Complete Test Description', videoUrl: 'https://youtube.com/watch?v=complete', + description: 'Complete Test Description', image: null, ); }, @@ -528,6 +538,10 @@ void main() { await tester.enterText(find.byKey(AppKeys.blogPostCreateScreenVideoLinkTextField), 'https://youtube.com/watch?v=complete'); await tester.pump(); + // Scroll to make sure the button is visible + await tester.drag(find.byType(SingleChildScrollView), const Offset(0, -200)); + await tester.pump(); + await tester.tap(find.byKey(AppKeys.blogPostCreateScreenCreateButton)); await tester.pump();