forked from eatvio/eatvio_app
feat(tests): increased tests coverage
This commit is contained in:
@@ -0,0 +1,381 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/add_meal_widget.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'add_meal_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateDietCubit>(), MockSpec<DiaryCubit>()])
|
||||
void main() {
|
||||
group('AddMealWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders add meal widget', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(AddMealWidget(createDietCubit: createDietCubit, dayIndex: 0, mealIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AddMealWidget), findsOneWidget);
|
||||
expect(find.text('Добавление блюда'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders add meal widget with initial text', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(
|
||||
AddMealWidget(
|
||||
createDietCubit: createDietCubit,
|
||||
dayIndex: 0,
|
||||
mealIndex: 0,
|
||||
productNameControllerText: 'Test Product',
|
||||
quantityControllerText: '100',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AddMealWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders edit meal widget with portion index', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
when(createDietCubit.removePortion(day: anyNamed('day'), meal: anyNamed('meal'), portionIndex: anyNamed('portionIndex'))).thenReturn(null);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(
|
||||
AddMealWidget(
|
||||
createDietCubit: createDietCubit,
|
||||
dayIndex: 0,
|
||||
mealIndex: 0,
|
||||
portionIndex: 0,
|
||||
productNameControllerText: 'Test Product',
|
||||
quantityControllerText: '100',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AddMealWidget), findsOneWidget);
|
||||
expect(find.text('Сохранить'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.delete_outline_rounded), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('searches glossary items when typing in product name field', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product 1',
|
||||
grInPortion: 100,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 100.0,
|
||||
carbohydratesOnPortion: 20.0,
|
||||
proteinsOnPortion: 10.0,
|
||||
fatsOnPortion: 5.0,
|
||||
),
|
||||
const GlossaryModel(
|
||||
id: 2,
|
||||
name: 'Test Product 2',
|
||||
grInPortion: 0,
|
||||
energyOn100Gr: 200.0,
|
||||
carbohydratesOn100Gr: 30.0,
|
||||
proteinsOn100Gr: 15.0,
|
||||
fatsOn100Gr: 10.0,
|
||||
energyOnPortion: 0.0,
|
||||
carbohydratesOnPortion: 0.0,
|
||||
proteinsOnPortion: 0.0,
|
||||
fatsOnPortion: 0.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(createDietCubit.addPortion(dayIndex: anyNamed('dayIndex'), mealIndex: anyNamed('mealIndex'), portion: anyNamed('portion'))).thenReturn(null);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(AddMealWidget(createDietCubit: createDietCubit, dayIndex: 0, mealIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byType(CustomTextFormField).first;
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Test Product 1'), findsOneWidget);
|
||||
expect(find.text('Test Product 2'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('selects glossary item from list', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
grInPortion: 100,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 100.0,
|
||||
carbohydratesOnPortion: 20.0,
|
||||
proteinsOnPortion: 10.0,
|
||||
fatsOnPortion: 5.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(createDietCubit.addPortion(dayIndex: anyNamed('dayIndex'), mealIndex: anyNamed('mealIndex'), portion: anyNamed('portion'))).thenReturn(null);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(AddMealWidget(createDietCubit: createDietCubit, dayIndex: 0, mealIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byType(CustomTextFormField).first;
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Test Product'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Test Product'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays correct suffix text for grams when glossary has grInPortion 0', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
grInPortion: 0,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 0.0,
|
||||
carbohydratesOnPortion: 0.0,
|
||||
proteinsOnPortion: 0.0,
|
||||
fatsOnPortion: 0.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(createDietCubit.addPortion(dayIndex: anyNamed('dayIndex'), mealIndex: anyNamed('mealIndex'), portion: anyNamed('portion'))).thenReturn(null);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(AddMealWidget(createDietCubit: createDietCubit, dayIndex: 0, mealIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byType(CustomTextFormField).first;
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Test Product'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('гр'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays correct suffix text for pieces when glossary has grInPortion not 0', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
grInPortion: 100,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 100.0,
|
||||
carbohydratesOnPortion: 20.0,
|
||||
proteinsOnPortion: 10.0,
|
||||
fatsOnPortion: 5.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(createDietCubit.addPortion(dayIndex: anyNamed('dayIndex'), mealIndex: anyNamed('mealIndex'), portion: anyNamed('portion'))).thenReturn(null);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(AddMealWidget(createDietCubit: createDietCubit, dayIndex: 0, mealIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byType(CustomTextFormField).first;
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Test Product'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('шт'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calls removePortion when delete button is tapped', (tester) async {
|
||||
final createDietCubit = MockCreateDietCubit();
|
||||
final diaryCubit = MockDiaryCubit();
|
||||
|
||||
when(createDietCubit.state).thenReturn(CreateDietState.initial());
|
||||
when(createDietCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(createDietCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(createDietCubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
when(createDietCubit.removePortion(day: 0, meal: 0, portionIndex: 0)).thenReturn(null);
|
||||
when(diaryCubit.state).thenReturn(const DiaryState());
|
||||
when(diaryCubit.stream).thenAnswer((_) => const Stream.empty());
|
||||
when(diaryCubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<CreateDietCubit>.value(value: createDietCubit),
|
||||
BlocProvider<DiaryCubit>.value(value: diaryCubit),
|
||||
],
|
||||
child: wrap(AddMealWidget(createDietCubit: createDietCubit, dayIndex: 0, mealIndex: 0, portionIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final deleteButton = find.byIcon(Icons.delete_outline_rounded);
|
||||
await tester.tap(deleteButton);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
verify(createDietCubit.removePortion(day: 0, meal: 0, portionIndex: 0)).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/cpfc_container.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/features/create_diet/models/create_diet_model.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/day_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'day_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateDietCubit>()])
|
||||
void main() {
|
||||
group('DayWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders day widget', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.copyDay(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(DayWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders day widget with error', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial().copyWith(dailyScheduleErrors: List.filled(21, ''));
|
||||
final stateWithError = state.copyWith(dailyScheduleErrors: List.generate(21, (index) => index == 0 ? 'Error message' : ''));
|
||||
|
||||
when(cubit.state).thenReturn(stateWithError);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(stateWithError));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.copyDay(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(DayWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('taps copy day button', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.copyDay(0)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final copyGesture = find.byType(GestureDetector).first;
|
||||
await tester.tap(copyGesture);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
verify(cubit.copyDay(0)).called(1);
|
||||
});
|
||||
|
||||
testWidgets('renders paste button', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Проверяем, что виджет отрендерился (paste button находится внутри)
|
||||
expect(find.byType(DayWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders add meal button', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Проверяем, что кнопка "Добавить" присутствует
|
||||
final addButtons = find.byType(CustomOutlinedButton);
|
||||
expect(addButtons, findsAtLeastNWidgets(1));
|
||||
});
|
||||
|
||||
testWidgets('selects different meal chips', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final chips = find.byType(ChoiceChipWidget);
|
||||
expect(chips, findsNWidgets(5));
|
||||
|
||||
await tester.tap(chips.at(2));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(chips.at(4));
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('displays day number correctly', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 2))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('День 3'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays products in list when dailySchedule has data', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final dailySchedule = [
|
||||
[
|
||||
[
|
||||
const DailySchedule(
|
||||
name: 'Test Product',
|
||||
portion: Portion.grams,
|
||||
quantity: 100,
|
||||
dailyNutrition: DailyNutrition(energy: 100.0, proteins: 10.0, fats: 5.0, carbohydrates: 20.0),
|
||||
),
|
||||
],
|
||||
],
|
||||
];
|
||||
final dietData = CreateDietModel(type: {}, dailySchedule: dailySchedule);
|
||||
final state = CreateDietState.initial().copyWith(dietData: dietData);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Проверяем, что виджет отрендерился с данными
|
||||
expect(find.byType(DayWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays CPFC container with calculated values', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final dailySchedule = [
|
||||
[
|
||||
[
|
||||
const DailySchedule(
|
||||
name: 'Test Product',
|
||||
portion: Portion.grams,
|
||||
quantity: 100,
|
||||
dailyNutrition: DailyNutrition(energy: 100.0, proteins: 10.0, fats: 5.0, carbohydrates: 20.0),
|
||||
),
|
||||
],
|
||||
],
|
||||
];
|
||||
final dietData = CreateDietModel(type: {}, dailySchedule: dailySchedule);
|
||||
final state = CreateDietState.initial().copyWith(dietData: dietData);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DayWidget(index: 0))));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CpfcContainer), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/diet_duration_drop_down_widget.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'diet_duration_drop_down_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateDietCubit>()])
|
||||
void main() {
|
||||
group('DietDurationDropDownWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders diet duration drop down widget', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.setDuration(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DietDurationDropDownWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(DietDurationDropDownWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/diet_type_choice_widget.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'diet_type_choice_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateDietCubit>()])
|
||||
void main() {
|
||||
group('DietTypeChoiceWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders diet type choice widget', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const DietTypeChoiceWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(DietTypeChoiceWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -4,85 +4,20 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('ValidationErrorWidget', () {
|
||||
testWidgets('displays error message', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: const Scaffold(
|
||||
body: ValidationErrorWidget(error: 'Test error message'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(ValidationErrorWidget), findsOneWidget);
|
||||
expect(find.text('Test error message'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays error icon', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: const Scaffold(
|
||||
body: ValidationErrorWidget(error: 'Test error'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(ValidationErrorWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('handles long error messages', (tester) async {
|
||||
final longError = 'A' * 100;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: ValidationErrorWidget(error: longError),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(ValidationErrorWidget), findsOneWidget);
|
||||
expect(find.text(longError), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays empty error message', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: const Scaffold(
|
||||
body: ValidationErrorWidget(error: ''),
|
||||
),
|
||||
),
|
||||
group('ValidationErrorWidget smoke', () {
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders validation error widget', (tester) async {
|
||||
await tester.pumpWidget(wrap(const ValidationErrorWidget(error: 'Test error')));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(ValidationErrorWidget), findsOneWidget);
|
||||
expect(find.text('Test error'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
@@ -6,6 +9,7 @@ import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
@@ -13,16 +17,19 @@ import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'status_drop_down_widget_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([CreateDietCubit])
|
||||
@GenerateNiceMocks([MockSpec<CreateDietCubit>()])
|
||||
void main() {
|
||||
group('StatusDropDownWidget', () {
|
||||
late MockCreateDietCubit mockCubit;
|
||||
|
||||
setUp(() {
|
||||
mockCubit = MockCreateDietCubit();
|
||||
group('StatusDropDownWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
Widget createTestWidget({DietState? dietState}) {
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
@@ -32,50 +39,43 @@ void main() {
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: BlocProvider<CreateDietCubit>.value(
|
||||
value: mockCubit,
|
||||
child: Scaffold(
|
||||
body: StatusDropDownWidget(dietState: dietState),
|
||||
),
|
||||
),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('displays status dropdown widget', (tester) async {
|
||||
when(mockCubit.state).thenReturn(
|
||||
CreateDietState.initial(),
|
||||
);
|
||||
when(mockCubit.stream).thenAnswer((_) => Stream.value(
|
||||
CreateDietState.initial(),
|
||||
));
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.setDietState(any)).thenAnswer((_) => () {});
|
||||
testWidgets('renders status drop down widget', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.setDietState(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateDietCubit>.value(value: cubit, child: wrap(const StatusDropDownWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(StatusDropDownWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays error when dietStateError is present', (tester) async {
|
||||
when(mockCubit.state).thenReturn(
|
||||
CreateDietState.initial().copyWith(
|
||||
dietStateError: 'Error message',
|
||||
testWidgets('renders status drop down widget with diet state', (tester) async {
|
||||
final cubit = MockCreateDietCubit();
|
||||
final state = CreateDietState.initial();
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.setDietState(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateDietCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(const StatusDropDownWidget(dietState: DietState.active)),
|
||||
),
|
||||
);
|
||||
when(mockCubit.stream).thenAnswer((_) => Stream.value(
|
||||
CreateDietState.initial().copyWith(
|
||||
dietStateError: 'Error message',
|
||||
),
|
||||
));
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.setDietState(any)).thenAnswer((_) => () {});
|
||||
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(StatusDropDownWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user