forked from eatvio/eatvio_app
441 lines
16 KiB
Dart
441 lines
16 KiB
Dart
import 'package:eatvio_app/app_keys.dart';
|
|
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
|
import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../../fixtures/doubles/blog_post_doubles.dart';
|
|
|
|
void main() {
|
|
group('Blog Post Creation Basic Widget Tests', () {
|
|
late FixtureBlogPostRepository blogPostRepository;
|
|
late BlogPostCreateCubit blogPostCreateCubit;
|
|
|
|
setUp(() {
|
|
blogPostRepository = FixtureBlogPostRepository();
|
|
blogPostCreateCubit = BlogPostCreateCubit(blogPostRepository: blogPostRepository);
|
|
});
|
|
|
|
tearDown(() {
|
|
blogPostCreateCubit.close();
|
|
});
|
|
|
|
Widget createTestWidget(Widget child) {
|
|
return MaterialApp(
|
|
theme: ThemeHelper().themeData(),
|
|
home: BlocProvider<BlogPostCreateCubit>(
|
|
create: (context) => blogPostCreateCubit,
|
|
child: Scaffold(body: SingleChildScrollView(child: child)),
|
|
),
|
|
);
|
|
}
|
|
|
|
testWidgets('should create BlogPostCreateCubit successfully', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
final cubit = BlogPostCreateCubit(blogPostRepository: blogPostRepository);
|
|
|
|
// Assert
|
|
expect(cubit, isA<BlogPostCreateCubit>());
|
|
|
|
cubit.close();
|
|
});
|
|
|
|
testWidgets('should display basic blog post form fields', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = Column(
|
|
children: [
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenTitleTextField,
|
|
decoration: const InputDecoration(labelText: 'Заголовок', hintText: 'Введите заголовок поста'),
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenContentTextField,
|
|
decoration: const InputDecoration(labelText: 'Описание'),
|
|
maxLines: 6,
|
|
minLines: 4,
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenVideoLinkTextField,
|
|
decoration: const InputDecoration(labelText: 'Ссылка на видео'),
|
|
),
|
|
const SizedBox(height: 16),
|
|
ElevatedButton(key: AppKeys.blogPostCreateScreenCreateButton, onPressed: () {}, child: const Text('Опубликовать')),
|
|
],
|
|
);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenTitleTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenContentTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenVideoLinkTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenCreateButton), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update title when user types in title field', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = TextFormField(
|
|
key: AppKeys.blogPostCreateScreenTitleTextField,
|
|
decoration: const InputDecoration(labelText: 'Заголовок', hintText: 'Введите заголовок поста'),
|
|
);
|
|
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testTitle = 'Тестовый заголовок поста';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.blogPostCreateScreenTitleTextField), testTitle);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testTitle), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update description when user types in description field', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = TextFormField(
|
|
key: AppKeys.blogPostCreateScreenContentTextField,
|
|
decoration: const InputDecoration(labelText: 'Описание'),
|
|
maxLines: 6,
|
|
minLines: 4,
|
|
);
|
|
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testDescription = 'Это тестовое описание блог поста';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.blogPostCreateScreenContentTextField), testDescription);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testDescription), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update video URL when user types in video field', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = TextFormField(
|
|
key: AppKeys.blogPostCreateScreenVideoLinkTextField,
|
|
decoration: const InputDecoration(labelText: 'Ссылка на видео'),
|
|
);
|
|
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testVideoUrl = 'https://youtube.com/watch?v=example';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.blogPostCreateScreenVideoLinkTextField), testVideoUrl);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testVideoUrl), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display form labels correctly', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = const Column(children: [Text('Заголовок'), Text('Описание'), Text('Ссылка на видео')]);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Заголовок'), findsOneWidget);
|
|
expect(find.text('Описание'), findsOneWidget);
|
|
expect(find.text('Ссылка на видео'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display placeholder text in title field', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = TextFormField(
|
|
key: AppKeys.blogPostCreateScreenTitleTextField,
|
|
decoration: const InputDecoration(labelText: 'Заголовок', hintText: 'Введите заголовок поста'),
|
|
);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Введите заголовок поста'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display create button', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget formWidget = ElevatedButton(key: AppKeys.blogPostCreateScreenCreateButton, onPressed: () {}, child: const Text('Опубликовать'));
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenCreateButton), findsOneWidget);
|
|
expect(find.text('Опубликовать'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should handle button tap', (WidgetTester tester) async {
|
|
// Arrange
|
|
bool buttonPressed = false;
|
|
Widget formWidget = ElevatedButton(
|
|
key: AppKeys.blogPostCreateScreenCreateButton,
|
|
onPressed: () {
|
|
buttonPressed = true;
|
|
},
|
|
child: const Text('Опубликовать'),
|
|
);
|
|
|
|
await tester.pumpWidget(createTestWidget(formWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Act
|
|
await tester.tap(find.byKey(AppKeys.blogPostCreateScreenCreateButton));
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(buttonPressed, isTrue);
|
|
});
|
|
|
|
testWidgets('should display loading state', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget loadingWidget = const Center(child: CircularProgressIndicator());
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(loadingWidget));
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display error message', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget errorWidget = const Center(child: Text('Произошла ошибка при создании блог поста'));
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(errorWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Произошла ошибка при создании блог поста'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display success message', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget successWidget = const Center(child: Text('Блог пост успешно создан!'));
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(successWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Блог пост успешно создан!'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should validate required fields', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget validationWidget = Column(
|
|
children: [
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenTitleTextField,
|
|
decoration: const InputDecoration(labelText: 'Заголовок', errorText: 'Заголовок обязателен'),
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenContentTextField,
|
|
decoration: const InputDecoration(labelText: 'Описание', errorText: 'Описание обязательно'),
|
|
),
|
|
],
|
|
);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(validationWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Заголовок обязателен'), findsOneWidget);
|
|
expect(find.text('Описание обязательно'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display form with all required fields', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget completeForm = Column(
|
|
children: [
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenTitleTextField,
|
|
decoration: const InputDecoration(labelText: 'Заголовок', hintText: 'Введите заголовок поста'),
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenContentTextField,
|
|
decoration: const InputDecoration(labelText: 'Описание'),
|
|
maxLines: 6,
|
|
minLines: 4,
|
|
),
|
|
const SizedBox(height: 16),
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenVideoLinkTextField,
|
|
decoration: const InputDecoration(labelText: 'Ссылка на видео'),
|
|
),
|
|
const SizedBox(height: 32),
|
|
ElevatedButton(key: AppKeys.blogPostCreateScreenCreateButton, onPressed: () {}, child: const Text('Опубликовать')),
|
|
],
|
|
);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(completeForm));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenTitleTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenContentTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenVideoLinkTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenCreateButton), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display image upload widget', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget imageWidget = GestureDetector(
|
|
key: AppKeys.imageWidget,
|
|
onTap: () {},
|
|
child: Container(
|
|
height: 200,
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Colors.grey),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(Icons.add_photo_alternate, size: 48, color: Colors.grey),
|
|
SizedBox(height: 8),
|
|
Text('Добавить изображение'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(imageWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.imageWidget), findsOneWidget);
|
|
expect(find.text('Добавить изображение'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should handle image upload tap', (WidgetTester tester) async {
|
|
// Arrange
|
|
bool imageUploadTapped = false;
|
|
Widget imageWidget = GestureDetector(
|
|
key: AppKeys.imageWidget,
|
|
onTap: () {
|
|
imageUploadTapped = true;
|
|
},
|
|
child: Container(
|
|
height: 200,
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Colors.grey),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(Icons.add_photo_alternate, size: 48, color: Colors.grey),
|
|
SizedBox(height: 8),
|
|
Text('Добавить изображение'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(createTestWidget(imageWidget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Act
|
|
await tester.tap(find.byKey(AppKeys.imageWidget));
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(imageUploadTapped, isTrue);
|
|
});
|
|
|
|
testWidgets('should display blog post creation form with image and video options', (WidgetTester tester) async {
|
|
// Arrange
|
|
Widget completeForm = Column(
|
|
children: [
|
|
const Text('Заголовок'),
|
|
const SizedBox(height: 8),
|
|
TextFormField(
|
|
key: AppKeys.blogPostCreateScreenTitleTextField,
|
|
decoration: const InputDecoration(hintText: 'Введите заголовок поста'),
|
|
),
|
|
const SizedBox(height: 16),
|
|
const Text('Описание'),
|
|
const SizedBox(height: 8),
|
|
TextFormField(key: AppKeys.blogPostCreateScreenContentTextField, decoration: const InputDecoration(), maxLines: 6, minLines: 4),
|
|
const SizedBox(height: 16),
|
|
const Text('Изображение поста'),
|
|
const SizedBox(height: 8),
|
|
GestureDetector(
|
|
key: AppKeys.imageWidget,
|
|
onTap: () {},
|
|
child: Container(
|
|
height: 200,
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Colors.grey),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(Icons.add_photo_alternate, size: 48, color: Colors.grey),
|
|
SizedBox(height: 8),
|
|
Text('Добавить изображение'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
const Text('Ссылка на видео'),
|
|
const SizedBox(height: 8),
|
|
TextFormField(key: AppKeys.blogPostCreateScreenVideoLinkTextField, decoration: const InputDecoration()),
|
|
const SizedBox(height: 32),
|
|
ElevatedButton(key: AppKeys.blogPostCreateScreenCreateButton, onPressed: () {}, child: const Text('Опубликовать')),
|
|
],
|
|
);
|
|
|
|
// Act
|
|
await tester.pumpWidget(createTestWidget(completeForm));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Заголовок'), findsOneWidget);
|
|
expect(find.text('Описание'), findsOneWidget);
|
|
expect(find.text('Изображение поста'), findsOneWidget);
|
|
expect(find.text('Ссылка на видео'), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenTitleTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenContentTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.imageWidget), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenVideoLinkTextField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.blogPostCreateScreenCreateButton), findsOneWidget);
|
|
});
|
|
});
|
|
}
|