forked from eatvio/eatvio_app
chore(version): update app version to 1.3.5+85 and improve test coverage reporting in CI
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/di/app_config_registration.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/cancel_plan_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/cubit/cancel_plan_cubit.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 'cancel_plan_bottom_sheet_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([CancelPlanCubit])
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('CancelPlanBottomSheet', () {
|
||||
late MockCancelPlanCubit mockCancelPlanCubit;
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
AppConfigRegistration.registerAppConfig(buildType: AppBuildType.tests);
|
||||
mockCancelPlanCubit = MockCancelPlanCubit();
|
||||
});
|
||||
|
||||
Widget createTestWidget({
|
||||
bool enableForm = false,
|
||||
required int planId,
|
||||
}) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru'), Locale('en')],
|
||||
locale: const Locale('ru'),
|
||||
home: BlocProvider<CancelPlanCubit>.value(
|
||||
value: mockCancelPlanCubit,
|
||||
child: Scaffold(
|
||||
body: CancelPlanBottomSheet(
|
||||
enableForm: enableForm,
|
||||
planId: planId,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('displays cancel plan bottom sheet without form', (tester) async {
|
||||
when(mockCancelPlanCubit.cancelChosenPlan(id: anyNamed('id')))
|
||||
.thenAnswer((_) async => true);
|
||||
|
||||
await tester.pumpWidget(createTestWidget(planId: 1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CancelPlanBottomSheet), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays cancel plan bottom sheet with form', (tester) async {
|
||||
when(mockCancelPlanCubit.cancelChosenPlan(
|
||||
id: anyNamed('id'),
|
||||
reason: anyNamed('reason'),
|
||||
price: anyNamed('price'),
|
||||
)).thenAnswer((_) async => true);
|
||||
|
||||
await tester.pumpWidget(createTestWidget(enableForm: true, planId: 1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CancelPlanBottomSheet), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays form fields when enableForm is true', (tester) async {
|
||||
when(mockCancelPlanCubit.cancelChosenPlan(
|
||||
id: anyNamed('id'),
|
||||
reason: anyNamed('reason'),
|
||||
price: anyNamed('price'),
|
||||
)).thenAnswer((_) async => true);
|
||||
|
||||
await tester.pumpWidget(createTestWidget(enableForm: true, planId: 1));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(CancelPlanBottomSheet), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,84 +1,81 @@
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/cubit/cancel_plan_cubit.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/cubit/cancel_plan_state.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/models/cancelation_model.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/repository/cancel_plan_repository.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import 'cancel_plan_cubit_test.mocks.dart';
|
||||
class MockCancelPlanRepository extends Mock implements CancelPlanRepository {}
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CancelPlanRepository>()])
|
||||
void main() {
|
||||
group('CancelPlanCubit', () {
|
||||
CancelPlanCubit? cubit;
|
||||
late CancelPlanCubit cubit;
|
||||
late MockCancelPlanRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockCancelPlanRepository();
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
if (cubit != null && !cubit!.isClosed) {
|
||||
await cubit!.close();
|
||||
cubit = null;
|
||||
}
|
||||
});
|
||||
|
||||
test('начальное состояние - пустое', () {
|
||||
cubit = CancelPlanCubit(cancelPlanRepository: mockRepository);
|
||||
|
||||
expect(cubit!.state, isA<CancelPlanState>());
|
||||
});
|
||||
|
||||
test('cancelChosenPlan - успешная отмена плана без причины', () async {
|
||||
cubit = CancelPlanCubit(cancelPlanRepository: mockRepository);
|
||||
|
||||
when(mockRepository.cancelChosenPlan(
|
||||
id: 1,
|
||||
body: anyNamed('body'),
|
||||
)).thenAnswer((_) async => {});
|
||||
|
||||
final result = await cubit!.cancelChosenPlan(id: 1);
|
||||
|
||||
expect(result, isTrue);
|
||||
verify(mockRepository.cancelChosenPlan(id: 1, body: null)).called(1);
|
||||
tearDown(() {
|
||||
cubit.close();
|
||||
});
|
||||
|
||||
test('cancelChosenPlan - успешная отмена плана с причиной', () async {
|
||||
cubit = CancelPlanCubit(cancelPlanRepository: mockRepository);
|
||||
|
||||
when(mockRepository.cancelChosenPlan(
|
||||
id: anyNamed('id'),
|
||||
body: anyNamed('body'),
|
||||
)).thenAnswer((_) async => {});
|
||||
|
||||
final result = await cubit!.cancelChosenPlan(
|
||||
id: 1,
|
||||
reason: 'Test reason',
|
||||
price: 1000,
|
||||
);
|
||||
|
||||
expect(result, isTrue);
|
||||
verify(mockRepository.cancelChosenPlan(
|
||||
id: 1,
|
||||
body: anyNamed('body'),
|
||||
)).called(1);
|
||||
test('начальное состояние - CancelPlanState', () {
|
||||
expect(cubit.state, isA<CancelPlanState>());
|
||||
});
|
||||
|
||||
test('cancelChosenPlan - обработка ошибки', () async {
|
||||
cubit = CancelPlanCubit(cancelPlanRepository: mockRepository);
|
||||
test('cancelChosenPlan - успешная отмена без причины', () async {
|
||||
const planId = 1;
|
||||
|
||||
when(mockRepository.cancelChosenPlan(
|
||||
id: anyNamed('id'),
|
||||
body: anyNamed('body'),
|
||||
)).thenAnswer((_) async {
|
||||
throw Exception('Ошибка отмены');
|
||||
});
|
||||
when(() => mockRepository.cancelChosenPlan(id: planId, body: null))
|
||||
.thenAnswer((_) async => {});
|
||||
|
||||
final result = await cubit!.cancelChosenPlan(id: 1);
|
||||
final result = await cubit.cancelChosenPlan(id: planId);
|
||||
|
||||
expect(result, isFalse);
|
||||
expect(result, true);
|
||||
verify(() => mockRepository.cancelChosenPlan(id: planId, body: null)).called(1);
|
||||
});
|
||||
|
||||
test('cancelChosenPlan - успешная отмена с причиной и ценой', () async {
|
||||
const planId = 1;
|
||||
const reason = 'Test reason';
|
||||
const price = 1000;
|
||||
final body = CancelationModel(description: reason, price: price);
|
||||
|
||||
when(() => mockRepository.cancelChosenPlan(id: planId, body: body))
|
||||
.thenAnswer((_) async => {});
|
||||
|
||||
final result = await cubit.cancelChosenPlan(id: planId, reason: reason, price: price);
|
||||
|
||||
expect(result, true);
|
||||
verify(() => mockRepository.cancelChosenPlan(id: planId, body: body)).called(1);
|
||||
});
|
||||
|
||||
test('cancelChosenPlan - возвращает false при ошибке', () async {
|
||||
const planId = 1;
|
||||
|
||||
when(() => mockRepository.cancelChosenPlan(id: planId, body: null))
|
||||
.thenThrow(Exception('Error'));
|
||||
|
||||
final result = await cubit.cancelChosenPlan(id: planId);
|
||||
|
||||
expect(result, false);
|
||||
});
|
||||
|
||||
test('cancelChosenPlan - не создает body если reason или price null', () async {
|
||||
const planId = 1;
|
||||
|
||||
when(() => mockRepository.cancelChosenPlan(id: planId, body: null))
|
||||
.thenAnswer((_) async => {});
|
||||
|
||||
// Только reason
|
||||
await cubit.cancelChosenPlan(id: planId, reason: 'reason');
|
||||
verify(() => mockRepository.cancelChosenPlan(id: planId, body: null)).called(1);
|
||||
|
||||
// Только price
|
||||
await cubit.cancelChosenPlan(id: planId, price: 100);
|
||||
verify(() => mockRepository.cancelChosenPlan(id: planId, body: null)).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,27 +3,28 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('CancelationModel', () {
|
||||
test('создает CancelationModel с правильными значениями', () {
|
||||
final model = CancelationModel(
|
||||
description: 'Test reason',
|
||||
price: 1000,
|
||||
);
|
||||
test('создает экземпляр с description и price', () {
|
||||
final model = CancelationModel(description: 'Test reason', price: 1000);
|
||||
|
||||
expect(model.description, 'Test reason');
|
||||
expect(model.price, 1000);
|
||||
});
|
||||
|
||||
test('fromJson создает CancelationModel из JSON', () {
|
||||
final json = {
|
||||
'description': 'Test reason',
|
||||
'price': 1000,
|
||||
};
|
||||
test('fromJson создает модель из JSON', () {
|
||||
final json = {'description': 'Test reason', 'price': 1000};
|
||||
|
||||
final model = CancelationModel.fromJson(json);
|
||||
|
||||
expect(model.description, 'Test reason');
|
||||
expect(model.price, 1000);
|
||||
});
|
||||
|
||||
test('toJson преобразует модель в JSON', () {
|
||||
final model = CancelationModel(description: 'Test reason', price: 1000);
|
||||
final json = model.toJson();
|
||||
|
||||
expect(json['description'], 'Test reason');
|
||||
expect(json['price'], 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user