forked from eatvio/eatvio_app
feat(tests): increased tests coverage
This commit is contained in:
@@ -1,14 +1,21 @@
|
||||
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/diary/entities/diary_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.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/diary/presentation/widgets/add_product_modal.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_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'add_product_modal_smoke_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<DiaryCubit>()])
|
||||
class FakeDiaryCubit extends Cubit<DiaryState> implements DiaryCubit {
|
||||
FakeDiaryCubit(super.initialState);
|
||||
|
||||
@@ -103,5 +110,241 @@ void main() {
|
||||
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
testWidgets('searches glossary items when typing in product name field', (tester) async {
|
||||
final state = makeLoadedState(withPortion: false);
|
||||
final cubit = 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(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(
|
||||
cubit.addProductToMeal(
|
||||
diaryId: anyNamed('diaryId'),
|
||||
mealId: anyNamed('mealId'),
|
||||
productName: anyNamed('productName'),
|
||||
portion: anyNamed('portion'),
|
||||
quantity: anyNamed('quantity'),
|
||||
productNutritionalValueId: anyNamed('productNutritionalValueId'),
|
||||
),
|
||||
).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(AddProductModal(state: state as DiaryStateLoaded, diaryCubit: cubit), cubit));
|
||||
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);
|
||||
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
testWidgets('selects glossary item from list', (tester) async {
|
||||
final state = makeLoadedState(withPortion: false);
|
||||
final cubit = 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(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(
|
||||
cubit.addProductToMeal(
|
||||
diaryId: anyNamed('diaryId'),
|
||||
mealId: anyNamed('mealId'),
|
||||
productName: anyNamed('productName'),
|
||||
portion: anyNamed('portion'),
|
||||
quantity: anyNamed('quantity'),
|
||||
productNutritionalValueId: anyNamed('productNutritionalValueId'),
|
||||
),
|
||||
).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(AddProductModal(state: state as DiaryStateLoaded, diaryCubit: cubit), cubit));
|
||||
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);
|
||||
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
testWidgets('displays correct suffix text for grams when glossary has grInPortion 0', (tester) async {
|
||||
final state = makeLoadedState(withPortion: false);
|
||||
final cubit = 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(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(
|
||||
cubit.addProductToMeal(
|
||||
diaryId: anyNamed('diaryId'),
|
||||
mealId: anyNamed('mealId'),
|
||||
productName: anyNamed('productName'),
|
||||
portion: anyNamed('portion'),
|
||||
quantity: anyNamed('quantity'),
|
||||
productNutritionalValueId: anyNamed('productNutritionalValueId'),
|
||||
),
|
||||
).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(AddProductModal(state: state as DiaryStateLoaded, diaryCubit: cubit), cubit));
|
||||
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);
|
||||
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
testWidgets('displays correct suffix text for pieces when glossary has grInPortion not 0', (tester) async {
|
||||
final state = makeLoadedState(withPortion: false);
|
||||
final cubit = 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(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(
|
||||
cubit.addProductToMeal(
|
||||
diaryId: anyNamed('diaryId'),
|
||||
mealId: anyNamed('mealId'),
|
||||
productName: anyNamed('productName'),
|
||||
portion: anyNamed('portion'),
|
||||
quantity: anyNamed('quantity'),
|
||||
productNutritionalValueId: anyNamed('productNutritionalValueId'),
|
||||
),
|
||||
).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(AddProductModal(state: state as DiaryStateLoaded, diaryCubit: cubit), cubit));
|
||||
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);
|
||||
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
testWidgets('calls deleteProductFromMeal when delete button is tapped', (tester) async {
|
||||
final state = makeLoadedState(withPortion: true);
|
||||
final cubit = MockDiaryCubit();
|
||||
final loaded = state as DiaryStateLoaded;
|
||||
final portion = loaded.diary.meals.first.portions.first;
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(
|
||||
cubit.deleteProductFromMeal(diaryId: anyNamed('diaryId'), mealId: anyNamed('mealId'), portionId: anyNamed('portionId')),
|
||||
).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(AddProductModal(state: loaded, diaryCubit: cubit, portion: portion), cubit));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final deleteButton = find.byIcon(Icons.delete_outline_rounded);
|
||||
await tester.tap(deleteButton);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
verify(cubit.deleteProductFromMeal(diaryId: 1, mealId: 1, portionId: 10)).called(1);
|
||||
|
||||
await cubit.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.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/diary/presentation/widgets/comment_for_consultant_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'comment_for_consultant_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<DiaryCubit>()])
|
||||
void main() {
|
||||
group('CommentForConsultantWidget smoke', () {
|
||||
Widget wrap(Widget child, DiaryCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: BlocProvider<DiaryCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders comment for consultant widget', (tester) async {
|
||||
final cubit = MockDiaryCubit();
|
||||
final diary = DiaryDayEntity(
|
||||
id: 1,
|
||||
date: '2025-01-01',
|
||||
wakeup: '07:00',
|
||||
retire: '23:00',
|
||||
closed: 0,
|
||||
comment: '',
|
||||
typeOfDiary: const TypeOfDiaryModel(hasChosenDiet: false, hasChosenPlan: false, diaryState: null),
|
||||
meals: const [MealModel(id: 1, time: '08:00', typeNumber: 1, satiety: 3, mood: 2, portions: [], photos: [])],
|
||||
chosenPlanId: null,
|
||||
dayOfChosenDiet: null,
|
||||
diet: null,
|
||||
);
|
||||
const nutrition = NutritionDataModel(
|
||||
dailyNutritionIntake: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
dailyNutritionRecommendation: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
);
|
||||
final state = DiaryState.loaded(diary: diary, nutrition: nutrition, selectedDay: DateTime(2025, 1, 1), selectedMeal: 1) as DiaryStateLoaded;
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.fillComment(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(wrap(const CommentForConsultantWidget(), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(CommentForConsultantWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:eatvio_app/features/diary/models/consultant_comment_model.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/consultant_comments_cubit/consultant_comments_cubit.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/consultant_comments_cubit/consultant_comments_state.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/widgets/day_comment_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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_comment_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<ConsultantCommentsCubit>()])
|
||||
void main() {
|
||||
group('DayCommentWidget smoke', () {
|
||||
Widget wrap(Widget child, ConsultantCommentsCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Scaffold(
|
||||
body: BlocProvider<ConsultantCommentsCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders day comment widget', (tester) async {
|
||||
final cubit = MockConsultantCommentsCubit();
|
||||
final commentsModel = ConsultantCommentModel(comment: '', mealsComments: {}, portions: []);
|
||||
final state = ConsultantCommentsState(commentsModel: commentsModel, dayCommentNeedsToBeFilled: false);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(const DayCommentWidget(), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(DayCommentWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,70 +1,23 @@
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/widgets/finish_day_button_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('FinishDayButtonWidget', () {
|
||||
testWidgets('displays finish day button', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: FinishDayButtonWidget(
|
||||
onPressed: () async {},
|
||||
),
|
||||
),
|
||||
),
|
||||
group('FinishDayButtonWidget smoke', () {
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders finish day button widget', (tester) async {
|
||||
await tester.pumpWidget(wrap(FinishDayButtonWidget(onPressed: () async {})));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(FinishDayButtonWidget), findsOneWidget);
|
||||
expect(find.text('Закончить день'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calls onPressed when tapped', (tester) async {
|
||||
bool wasCalled = false;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: FinishDayButtonWidget(
|
||||
onPressed: () async {
|
||||
wasCalled = true;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Закончить день'));
|
||||
await tester.pump();
|
||||
|
||||
expect(wasCalled, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +1,32 @@
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/consultations/models/consultation_model.dart';
|
||||
import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/entities/diary_future_diet_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/models/consultant_review_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.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/diary/presentation/widgets/meal_button_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
class FakeDiaryCubit extends Cubit<DiaryState> implements DiaryCubit {
|
||||
FakeDiaryCubit(super.initialState);
|
||||
|
||||
int? lastSelectedMeal;
|
||||
|
||||
@override
|
||||
void setSelectedMeal(int meal) {
|
||||
lastSelectedMeal = meal;
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
import 'meal_button_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<DiaryCubit>()])
|
||||
void main() {
|
||||
group('MealButtonWidget', () {
|
||||
Widget wrap(DiaryCubit cubit, Widget child) {
|
||||
group('MealButtonWidget smoke', () {
|
||||
Widget wrap(Widget child, DiaryCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(size: Size(500, 900)),
|
||||
child: BlocProvider<DiaryCubit>.value(
|
||||
value: cubit,
|
||||
child: Scaffold(body: child),
|
||||
),
|
||||
home: Scaffold(
|
||||
body: BlocProvider<DiaryCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
DiaryStateLoaded loadedState({required int selectedMeal, required List<List<PortionModel>> mealsPortions, bool withConsultantComment = false}) {
|
||||
const caloriesInfo = ProductCaloriesInfoModel(
|
||||
id: 1,
|
||||
productName: 'P',
|
||||
calories: 100,
|
||||
proteins: 10,
|
||||
fats: 10,
|
||||
carbohydrates: 10,
|
||||
energyOnPortion: 100,
|
||||
proteinsOnPortion: 10,
|
||||
fatsOnPortion: 10,
|
||||
carbohydratesOnPortion: 10,
|
||||
);
|
||||
|
||||
final meals = List<MealModel>.generate(
|
||||
5,
|
||||
(i) => MealModel(
|
||||
id: i + 1,
|
||||
time: '08:00',
|
||||
typeNumber: i + 1,
|
||||
satiety: 0,
|
||||
mood: 0,
|
||||
portions: mealsPortions.length > i
|
||||
? mealsPortions[i]
|
||||
: const [
|
||||
PortionModel(
|
||||
id: 1,
|
||||
productNutritionalValueId: 1,
|
||||
productCaloriesInfo: caloriesInfo,
|
||||
productName: 'P',
|
||||
quantity: 100,
|
||||
portion: 'gr',
|
||||
fromDiet: false,
|
||||
portionState: PortionState.eaten,
|
||||
),
|
||||
],
|
||||
photos: const [],
|
||||
),
|
||||
);
|
||||
|
||||
testWidgets('renders meal button widget - loaded state', (tester) async {
|
||||
final cubit = MockDiaryCubit();
|
||||
final diary = DiaryDayEntity(
|
||||
id: 1,
|
||||
date: '2025-01-01',
|
||||
@@ -88,129 +34,26 @@ void main() {
|
||||
retire: '23:00',
|
||||
closed: 0,
|
||||
comment: '',
|
||||
typeOfDiary: const TypeOfDiaryModel(hasChosenDiet: false, hasChosenPlan: true, diaryState: DiaryStateEnum.started),
|
||||
meals: meals,
|
||||
chosenPlanId: 1,
|
||||
typeOfDiary: const TypeOfDiaryModel(hasChosenDiet: false, hasChosenPlan: false, diaryState: null),
|
||||
meals: const [MealModel(id: 1, time: '08:00', typeNumber: 1, satiety: 3, mood: 2, portions: [], photos: [])],
|
||||
chosenPlanId: null,
|
||||
dayOfChosenDiet: null,
|
||||
diet: null,
|
||||
);
|
||||
|
||||
const nutrition = NutritionDataModel(
|
||||
dailyNutritionIntake: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
dailyNutritionRecommendation: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
);
|
||||
final state = DiaryState.loaded(diary: diary, nutrition: nutrition, selectedDay: DateTime(2025, 1, 1), selectedMeal: 1) as DiaryStateLoaded;
|
||||
|
||||
return DiaryState.loaded(
|
||||
diary: diary,
|
||||
nutrition: nutrition,
|
||||
selectedDay: DateTime(2025, 1, 1),
|
||||
selectedMeal: selectedMeal,
|
||||
isConsultantView: false,
|
||||
isDiaryFinished: false,
|
||||
isDiaryCommented: false,
|
||||
consultantReview: ConsultantReviewModel(
|
||||
planName: 'Plan',
|
||||
planDuration: 10,
|
||||
currentPlanDay: 1,
|
||||
consultantComments: ConsultantComments(
|
||||
dayComment: null,
|
||||
mealsComments: withConsultantComment ? [MealComment(comment: 'c', typeNo: 2)] : const [],
|
||||
portionsComments: const [],
|
||||
),
|
||||
),
|
||||
)
|
||||
as DiaryStateLoaded;
|
||||
}
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
testWidgets('shows calories for loaded state and calls setSelectedMeal on tap', (tester) async {
|
||||
const caloriesInfo = ProductCaloriesInfoModel(
|
||||
id: 1,
|
||||
productName: 'P',
|
||||
calories: 100,
|
||||
proteins: 10,
|
||||
fats: 10,
|
||||
carbohydrates: 10,
|
||||
energyOnPortion: 100,
|
||||
proteinsOnPortion: 10,
|
||||
fatsOnPortion: 10,
|
||||
carbohydratesOnPortion: 10,
|
||||
);
|
||||
const portion = PortionModel(
|
||||
id: 1,
|
||||
productNutritionalValueId: 1,
|
||||
productCaloriesInfo: caloriesInfo,
|
||||
productName: 'P',
|
||||
quantity: 100,
|
||||
portion: 'gr',
|
||||
fromDiet: false,
|
||||
portionState: PortionState.eaten,
|
||||
);
|
||||
|
||||
final cubit = FakeDiaryCubit(
|
||||
loadedState(
|
||||
selectedMeal: 1,
|
||||
mealsPortions: const [
|
||||
[portion],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
],
|
||||
),
|
||||
);
|
||||
await tester.pumpWidget(wrap(cubit, const MealButtonWidget(mealNumber: 1)));
|
||||
await tester.pumpWidget(wrap(const MealButtonWidget(mealNumber: 1), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('100 ккал'), findsOneWidget);
|
||||
await tester.tap(find.text('1'));
|
||||
await tester.pump();
|
||||
expect(cubit.lastSelectedMeal, 1);
|
||||
});
|
||||
|
||||
testWidgets('shows dash calories when meal empty', (tester) async {
|
||||
final cubit = FakeDiaryCubit(loadedState(selectedMeal: 1, mealsPortions: const [[], [], [], [], []]));
|
||||
await tester.pumpWidget(wrap(cubit, const MealButtonWidget(mealNumber: 3)));
|
||||
await tester.pump();
|
||||
expect(find.text('— ккал'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('works for tomorrow-with-diet state', (tester) async {
|
||||
const caloriesInfo = ProductCaloriesInfoModel(
|
||||
id: 1,
|
||||
productName: 'P',
|
||||
calories: 100,
|
||||
proteins: 10,
|
||||
fats: 10,
|
||||
carbohydrates: 10,
|
||||
energyOnPortion: 100,
|
||||
proteinsOnPortion: 10,
|
||||
fatsOnPortion: 10,
|
||||
carbohydratesOnPortion: 10,
|
||||
);
|
||||
const portion = PortionModel(
|
||||
id: 1,
|
||||
productNutritionalValueId: 1,
|
||||
productCaloriesInfo: caloriesInfo,
|
||||
productName: 'P',
|
||||
quantity: 100,
|
||||
portion: 'gr',
|
||||
fromDiet: true,
|
||||
portionState: PortionState.eatenFromDiet,
|
||||
);
|
||||
const diary = DiaryFutureDietDayEntity(
|
||||
date: '2025-01-02',
|
||||
typeOfDiary: TypeOfDiaryModel(hasChosenDiet: true, hasChosenPlan: false, diaryState: null),
|
||||
meals: [
|
||||
MealModel(id: 1, time: '08:00', typeNumber: 1, satiety: 0, mood: 0, portions: [portion], photos: []),
|
||||
],
|
||||
diet: null,
|
||||
dayOfChosenDiet: 1,
|
||||
);
|
||||
final cubit = FakeDiaryCubit(DiaryState.loadedTomorrowWithDiet(diary: diary, selectedDay: DateTime(2025, 1, 2), selectedMeal: 1));
|
||||
|
||||
await tester.pumpWidget(wrap(cubit, const MealButtonWidget(mealNumber: 1)));
|
||||
await tester.pump();
|
||||
expect(find.text('100 ккал'), findsOneWidget);
|
||||
expect(find.byType(MealButtonWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.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/diary/presentation/widgets/mood_rating_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'mood_rating_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<DiaryCubit>()])
|
||||
void main() {
|
||||
group('MoodRatingWidget smoke', () {
|
||||
Widget wrap(Widget child, DiaryCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: BlocProvider<DiaryCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders mood rating widget - loaded state', (tester) async {
|
||||
final cubit = MockDiaryCubit();
|
||||
final diary = DiaryDayEntity(
|
||||
id: 1,
|
||||
date: '2025-01-01',
|
||||
wakeup: '07:00',
|
||||
retire: '23:00',
|
||||
closed: 0,
|
||||
comment: '',
|
||||
typeOfDiary: const TypeOfDiaryModel(hasChosenDiet: false, hasChosenPlan: false, diaryState: null),
|
||||
meals: const [MealModel(id: 1, time: '08:00', typeNumber: 1, satiety: 3, mood: 2, portions: [], photos: [])],
|
||||
chosenPlanId: null,
|
||||
dayOfChosenDiet: null,
|
||||
diet: null,
|
||||
);
|
||||
const nutrition = NutritionDataModel(
|
||||
dailyNutritionIntake: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
dailyNutritionRecommendation: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
);
|
||||
final state = DiaryState.loaded(diary: diary, nutrition: nutrition, selectedDay: DateTime(2025, 1, 1), selectedMeal: 1) as DiaryStateLoaded;
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.fillMood(diaryId: anyNamed('diaryId'), mood: anyNamed('mood'))).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(const MoodRatingWidget(), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(MoodRatingWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.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/diary/presentation/widgets/satiety_rating_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'satiety_rating_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<DiaryCubit>()])
|
||||
void main() {
|
||||
group('SatietyRatingWidget smoke', () {
|
||||
Widget wrap(Widget child, DiaryCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: BlocProvider<DiaryCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders satiety rating widget - loaded state', (tester) async {
|
||||
final cubit = MockDiaryCubit();
|
||||
final diary = DiaryDayEntity(
|
||||
id: 1,
|
||||
date: '2025-01-01',
|
||||
wakeup: '07:00',
|
||||
retire: '23:00',
|
||||
closed: 0,
|
||||
comment: '',
|
||||
typeOfDiary: const TypeOfDiaryModel(hasChosenDiet: false, hasChosenPlan: false, diaryState: null),
|
||||
meals: const [MealModel(id: 1, time: '08:00', typeNumber: 1, satiety: 3, mood: 2, portions: [], photos: [])],
|
||||
chosenPlanId: null,
|
||||
dayOfChosenDiet: null,
|
||||
diet: null,
|
||||
);
|
||||
const nutrition = NutritionDataModel(
|
||||
dailyNutritionIntake: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
dailyNutritionRecommendation: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
);
|
||||
final state = DiaryState.loaded(diary: diary, nutrition: nutrition, selectedDay: DateTime(2025, 1, 1), selectedMeal: 1) as DiaryStateLoaded;
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.fillSatiety(diaryId: anyNamed('diaryId'), satiety: anyNamed('satiety'))).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(const SatietyRatingWidget(), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(SatietyRatingWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart';
|
||||
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/nutrition_model.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/diary/presentation/widgets/time_of_meal_picker_widget.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'time_of_meal_picker_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<DiaryCubit>()])
|
||||
void main() {
|
||||
group('TimeOfMealPickerWidget smoke', () {
|
||||
Widget wrap(Widget child, DiaryCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: BlocProvider<DiaryCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders time of meal picker widget - loaded state', (tester) async {
|
||||
final cubit = MockDiaryCubit();
|
||||
final diary = DiaryDayEntity(
|
||||
id: 1,
|
||||
date: '2025-01-01',
|
||||
wakeup: '07:00',
|
||||
retire: '23:00',
|
||||
closed: 0,
|
||||
comment: '',
|
||||
typeOfDiary: const TypeOfDiaryModel(hasChosenDiet: false, hasChosenPlan: false, diaryState: null),
|
||||
meals: const [MealModel(id: 1, time: '08:00', typeNumber: 1, satiety: 3, mood: 2, portions: [], photos: [])],
|
||||
chosenPlanId: null,
|
||||
dayOfChosenDiet: null,
|
||||
diet: null,
|
||||
);
|
||||
const nutrition = NutritionDataModel(
|
||||
dailyNutritionIntake: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
dailyNutritionRecommendation: NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0),
|
||||
);
|
||||
final state = DiaryState.loaded(diary: diary, nutrition: nutrition, selectedDay: DateTime(2025, 1, 1), selectedMeal: 1) as DiaryStateLoaded;
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.fillTime(diaryId: anyNamed('diaryId'), time: anyNamed('time'))).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(const TimeOfMealPickerWidget(), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(TimeOfMealPickerWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user