test: add unit tests for poultry repository and searchable dropdown functionalities
- Introduced tests for `PoultryScienceRepositoryImp` to validate delegated remote calls. - Added comprehensive tests for `SearchableDropdownLogic` covering selection, overlay, and search logic. - Enhanced `SearchableDropdown` widget tests for multi-select, label building, and overlay management.
This commit is contained in:
@@ -5,7 +5,7 @@ import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/steward/inventory_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
import 'package:rasadyar_core/core.dart' hide modalDatePicker;
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
@@ -412,12 +412,14 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
controller: controller,
|
||||
date: controller.fromDateFilter,
|
||||
onChanged: (jalali) => controller.fromDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
controller: controller,
|
||||
isFrom: false,
|
||||
date: controller.toDateFilter,
|
||||
onChanged: (jalali) => controller.toDateFilter.value = jalali,
|
||||
@@ -441,6 +443,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
|
||||
}
|
||||
|
||||
GestureDetector timeFilterWidget({
|
||||
required SalesInProvinceLogic controller,
|
||||
isFrom = true,
|
||||
required Rx<Jalali> date,
|
||||
required Function(Jalali jalali) onChanged,
|
||||
@@ -482,139 +485,4 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container modalDatePicker(ValueChanged<Jalali> onDateSelected) {
|
||||
Jalali? tempPickedDate;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'تایید',
|
||||
),
|
||||
Spacer(),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
backgroundColor: AppColor.error,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'لغو',
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 0, thickness: 1),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: PersianCupertinoDatePicker(
|
||||
initialDateTime: Jalali.now(),
|
||||
mode: PersianCupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget show2StepAddBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: Get.height * .39,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow(
|
||||
title: 'تاریخ ثبت',
|
||||
value: controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نام و نام خانوادگی خریدار',
|
||||
value:
|
||||
controller.guildsModel
|
||||
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
|
||||
.user
|
||||
?.fullname ??
|
||||
'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'شماره خریدار',
|
||||
value:
|
||||
controller.guildsModel
|
||||
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
|
||||
.user
|
||||
?.mobile ??
|
||||
'ندارد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'قیمت هر کیلو',
|
||||
value: '${controller.tmpStewardAllocation?.amount.separatedByCommaFa ?? 0} ریال ',
|
||||
),
|
||||
buildRow(
|
||||
title: 'وزن تخصیصی',
|
||||
value:
|
||||
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByCommaFa ?? 0} کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت کل',
|
||||
value: '${controller.tmpStewardAllocation?.totalAmount.separatedByCommaFa ?? 0} ریال',
|
||||
),
|
||||
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Expanded(
|
||||
child: RElevated(
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
height: 40,
|
||||
text: 'ثبت',
|
||||
textStyle: AppFonts.yekan18.copyWith(color: Colors.white),
|
||||
onPressed: () async {
|
||||
await controller.submitAllocation();
|
||||
Get
|
||||
..back()
|
||||
..back();
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ROutlinedElevated(
|
||||
height: 40,
|
||||
borderColor: AppColor.error,
|
||||
text: ' بازگشت',
|
||||
textStyle: AppFonts.yekan18.copyWith(color: AppColor.error),
|
||||
onPressed: () {
|
||||
Get
|
||||
..back()
|
||||
..back();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,15 +31,24 @@ Widget addOrEditBottomSheet(SalesInProvinceLogic controller, {bool isEditMode =
|
||||
spacing: 12,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
RTextField(
|
||||
controller: TextEditingController(),
|
||||
filledColor: AppColor.bgLight,
|
||||
label: 'تاریخ',
|
||||
readonly: true,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
initText: Jalali.now().formatCompactDate(),
|
||||
),
|
||||
|
||||
ObxValue((data) {
|
||||
return RTextField(
|
||||
controller: TextEditingController(),
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
label: 'تاریخ',
|
||||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
modalDatePicker((value) {
|
||||
controller.fromDateFilter.value = value;
|
||||
controller.fromDateFilter.refresh();
|
||||
}),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
initText: (data.value ?? Jalali.now()).formatCompactDate(),
|
||||
);
|
||||
}, controller.fromDateFilter),
|
||||
Visibility(
|
||||
visible: isEditMode == false,
|
||||
child: Container(
|
||||
@@ -271,9 +280,11 @@ Widget addOrEditBottomSheet(SalesInProvinceLogic controller, {bool isEditMode =
|
||||
onPressed: isEditMode
|
||||
? () async {
|
||||
await controller.updateAllocation();
|
||||
Get.back();
|
||||
}
|
||||
: () async {
|
||||
await controller.submitAllocation();
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
}, controller.isValid),
|
||||
@@ -365,3 +376,140 @@ Widget productDropDown(SalesInProvinceLogic controller) {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Container modalDatePicker(ValueChanged<Jalali> onDateSelected) {
|
||||
Jalali? tempPickedDate;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'تایید',
|
||||
),
|
||||
Spacer(),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
backgroundColor: AppColor.error,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'لغو',
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 0, thickness: 1),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: PersianCupertinoDatePicker(
|
||||
initialDateTime: Jalali.now(),
|
||||
minimumDate: Jalali.now().add(days: -1),
|
||||
maximumDate: Jalali.now(),
|
||||
mode: PersianCupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget show2StepAddBottomSheet(SalesInProvinceLogic controller) {
|
||||
return BaseBottomSheet(
|
||||
height: Get.height * .39,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow(
|
||||
title: 'تاریخ ثبت',
|
||||
value: controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نام و نام خانوادگی خریدار',
|
||||
value:
|
||||
controller.guildsModel
|
||||
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
|
||||
.user
|
||||
?.fullname ??
|
||||
'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'شماره خریدار',
|
||||
value:
|
||||
controller.guildsModel
|
||||
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
|
||||
.user
|
||||
?.mobile ??
|
||||
'ندارد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'قیمت هر کیلو',
|
||||
value: '${controller.tmpStewardAllocation?.amount.separatedByCommaFa ?? 0} ریال ',
|
||||
),
|
||||
buildRow(
|
||||
title: 'وزن تخصیصی',
|
||||
value:
|
||||
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByCommaFa ?? 0} کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت کل',
|
||||
value: '${controller.tmpStewardAllocation?.totalAmount.separatedByCommaFa ?? 0} ریال',
|
||||
),
|
||||
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Expanded(
|
||||
child: RElevated(
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
height: 40,
|
||||
text: 'ثبت',
|
||||
textStyle: AppFonts.yekan18.copyWith(color: Colors.white),
|
||||
onPressed: () async {
|
||||
await controller.submitAllocation();
|
||||
Get
|
||||
..back()
|
||||
..back();
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ROutlinedElevated(
|
||||
height: 40,
|
||||
borderColor: AppColor.error,
|
||||
text: ' بازگشت',
|
||||
textStyle: AppFonts.yekan18.copyWith(color: AppColor.error),
|
||||
onPressed: () {
|
||||
Get
|
||||
..back()
|
||||
..back();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -357,4 +357,26 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void setSaleDate(Jalali value) {
|
||||
saleDate.value = value;
|
||||
saleDate.refresh();
|
||||
dateErrorDialog();
|
||||
}
|
||||
|
||||
void setProductionDate(DayInfo value) {
|
||||
productionDate.value = value.date;
|
||||
remainingStock.value = value.remainingStock;
|
||||
dateErrorDialog();
|
||||
}
|
||||
|
||||
void dateErrorDialog() {
|
||||
if ((productionDate.value?.distanceTo(saleDate.value) ?? 0) >= 1) {
|
||||
saleDate.value = Jalali.now();
|
||||
Future.delayed(
|
||||
Duration(milliseconds: 300),
|
||||
() => defaultShowErrorMessage("تاریخ تولید نمی تواند قبل از تاریخ فروش باشد"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,14 +352,21 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
RTextField(
|
||||
controller: TextEditingController(),
|
||||
filledColor: AppColor.bgLight,
|
||||
label: 'تاریخ',
|
||||
readonly: true,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
initText: Jalali.now().formatCompactDate(),
|
||||
),
|
||||
ObxValue((data) {
|
||||
return RTextField(
|
||||
controller: TextEditingController(),
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
label: 'تاریخ',
|
||||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
modalDatePicker((value) => controller.setSaleDate(value)),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
initText: data.value.formatCompactDate(),
|
||||
);
|
||||
}, controller.saleDate),
|
||||
Visibility(
|
||||
visible: isOnEdit == false,
|
||||
child: Container(
|
||||
@@ -430,8 +437,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
label: 'تاریخ تولید گوشت',
|
||||
selectedDate: controller.productionDate.value?.formatCompactDate(),
|
||||
onDateSelect: (value) {
|
||||
controller.productionDate.value = value.date;
|
||||
controller.remainingStock.value = value.remainingStock;
|
||||
controller.setProductionDate(value);
|
||||
},
|
||||
dayData: controller.quotaType.value == 1
|
||||
? controller.governmentalProductionDateData
|
||||
|
||||
@@ -323,7 +323,7 @@ void main() {
|
||||
).thenAnswer((_) async => mockResponse);
|
||||
|
||||
// Act
|
||||
await authRemoteDataSource.submitUserInfo(userInfo);
|
||||
await authRemoteDataSource.stewardAppLogin(token: 'test-token', queryParameters: userInfo);
|
||||
|
||||
// Assert
|
||||
verify(
|
||||
|
||||
@@ -146,45 +146,6 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('submitUserInfo', () {
|
||||
test(
|
||||
'should call remote submitUserInfo with correct parameters',
|
||||
() async {
|
||||
// Arrange
|
||||
const phone = '09123456789';
|
||||
const deviceName = 'Test Device';
|
||||
final expectedData = {'mobile': phone, 'device_name': deviceName};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.submitUserInfo(
|
||||
phone: phone,
|
||||
deviceName: deviceName,
|
||||
);
|
||||
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.submitUserInfo(expectedData)).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('should call remote submitUserInfo without device name', () async {
|
||||
// Arrange
|
||||
const phone = '09123456789';
|
||||
final expectedData = {'mobile': phone, 'device_name': null};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.submitUserInfo(phone: phone);
|
||||
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.submitUserInfo(expectedData)).called(1);
|
||||
});
|
||||
});
|
||||
// submitUserInfo removed from API; covered by stewardAppLogin at remote layer
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository_imp.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class _MockRemote extends Mock implements PoultryScienceRemoteDatasource {}
|
||||
|
||||
void main() {
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FormData());
|
||||
registerFallbackValue(const KillRegistrationRequest());
|
||||
registerFallbackValue(<String, dynamic>{});
|
||||
});
|
||||
|
||||
group('PoultryScienceRepositoryImp', () {
|
||||
late _MockRemote remote;
|
||||
late PoultryScienceRepositoryImp repo;
|
||||
|
||||
setUp(() {
|
||||
remote = _MockRemote();
|
||||
repo = PoultryScienceRepositoryImp(remote);
|
||||
});
|
||||
|
||||
test('getHomePoultry delegates', () async {
|
||||
when(() => remote.getHomePoultryScience(token: any(named: 'token'), type: any(named: 'type')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getHomePoultry(token: 't', type: 'x');
|
||||
expect(res, null);
|
||||
verify(() => remote.getHomePoultryScience(token: 't', type: 'x')).called(1);
|
||||
});
|
||||
|
||||
test('getHatchingPoultry delegates', () async {
|
||||
when(() => remote.getHatchingPoultry(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getHatchingPoultry(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getHatchingPoultry(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('submitPoultryScienceReport delegates', () async {
|
||||
when(() => remote.submitPoultryScienceReport(token: any(named: 'token'), data: any(named: 'data'), onSendProgress: any(named: 'onSendProgress')))
|
||||
.thenAnswer((_) async {});
|
||||
await repo.submitPoultryScienceReport(token: 't', data: FormData());
|
||||
verify(() => remote.submitPoultryScienceReport(token: 't', data: any(named: 'data'), onSendProgress: any(named: 'onSendProgress'))).called(1);
|
||||
});
|
||||
|
||||
test('getHatchingPoultryReport delegates', () async {
|
||||
when(() => remote.getPoultryScienceReport(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getHatchingPoultryReport(token: 't', queryParameters: {'q': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getPoultryScienceReport(token: 't', queryParameters: {'q': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getPoultryScienceFarmList delegates', () async {
|
||||
when(() => remote.getPoultryScienceFarmList(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getPoultryScienceFarmList(token: 't', queryParameters: {'p': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getPoultryScienceFarmList(token: 't', queryParameters: {'p': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getApprovedPrice delegates', () async {
|
||||
when(() => remote.getApprovedPrice(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getApprovedPrice(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getApprovedPrice(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getAllPoultry delegates', () async {
|
||||
when(() => remote.getAllPoultry(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getAllPoultry(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getAllPoultry(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getSellForFreezing delegates', () async {
|
||||
when(() => remote.getSellForFreezing(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getSellForFreezing(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getSellForFreezing(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getPoultryExport delegates', () async {
|
||||
when(() => remote.getPoultryExport(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getPoultryExport(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getPoultryExport(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getUserPoultry delegates', () async {
|
||||
when(() => remote.getUserPoultry(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getUserPoultry(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getUserPoultry(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getPoultryHatching delegates', () async {
|
||||
when(() => remote.getPoultryHatching(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getPoultryHatching(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getPoultryHatching(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('getKillHouseList delegates', () async {
|
||||
when(() => remote.getKillHouseList(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getKillHouseList(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getKillHouseList(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('submitKillRegistration delegates', () async {
|
||||
when(() => remote.submitKillRegistration(token: any(named: 'token'), request: any(named: 'request')))
|
||||
.thenAnswer((_) async {});
|
||||
await repo.submitKillRegistration(token: 't', request: const KillRegistrationRequest());
|
||||
verify(() => remote.submitKillRegistration(token: 't', request: any(named: 'request'))).called(1);
|
||||
});
|
||||
|
||||
test('getPoultryOderList delegates', () async {
|
||||
when(() => remote.getPoultryOderList(token: any(named: 'token'), queryParameters: any(named: 'queryParameters')))
|
||||
.thenAnswer((_) async => null);
|
||||
final res = await repo.getPoultryOderList(token: 't', queryParameters: {'a': 1});
|
||||
expect(res, null);
|
||||
verify(() => remote.getPoultryOderList(token: 't', queryParameters: {'a': 1})).called(1);
|
||||
});
|
||||
|
||||
test('deletePoultryOder delegates', () async {
|
||||
when(() => remote.deletePoultryOder(token: any(named: 'token'), orderId: any(named: 'orderId')))
|
||||
.thenAnswer((_) async {});
|
||||
await repo.deletePoultryOder(token: 't', orderId: 'id');
|
||||
verify(() => remote.deletePoultryOder(token: 't', orderId: 'id')).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {}
|
||||
|
||||
@@ -22,7 +21,6 @@ void main() {
|
||||
test('should complete full login flow successfully', () async {
|
||||
// Arrange
|
||||
const phoneNumber = '09123456789';
|
||||
const deviceName = 'Test Device';
|
||||
final authRequest = {
|
||||
'username': 'test@example.com',
|
||||
'password': 'password',
|
||||
@@ -48,28 +46,18 @@ void main() {
|
||||
|
||||
// Mock the flow
|
||||
when(
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
).thenAnswer((_) async => expectedUserInfo);
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
).thenAnswer((_) async => expectedUserProfile);
|
||||
|
||||
// Act - Step 1: Get user info
|
||||
final userInfo = await authRepository.getUserInfo(phoneNumber);
|
||||
expect(userInfo, equals(expectedUserInfo));
|
||||
|
||||
// Act - Step 2: Submit user info
|
||||
await authRepository.submitUserInfo(
|
||||
phone: phoneNumber,
|
||||
deviceName: deviceName,
|
||||
);
|
||||
|
||||
// Act - Step 3: Login
|
||||
// Act - Step 2: Login
|
||||
final userProfile = await authRepository.login(
|
||||
authRequest: authRequest,
|
||||
);
|
||||
@@ -77,7 +65,6 @@ void main() {
|
||||
// Assert
|
||||
expect(userProfile, equals(expectedUserProfile));
|
||||
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
||||
//verify(() => mockAuthRemote.submitUserInfo(any())).called(1);
|
||||
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
||||
});
|
||||
|
||||
@@ -100,11 +87,11 @@ void main() {
|
||||
|
||||
// Mock the flow
|
||||
when(
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
).thenAnswer((_) async => false);
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
).thenAnswer((_) async => expectedUserProfile);
|
||||
|
||||
// Act - Step 1: Check authentication status
|
||||
@@ -129,7 +116,7 @@ void main() {
|
||||
const phoneNumber = '09123456789';
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
).thenAnswer((_) async => null);
|
||||
|
||||
// Act
|
||||
@@ -143,7 +130,6 @@ void main() {
|
||||
test('should handle login failure after successful user info', () async {
|
||||
// Arrange
|
||||
const phoneNumber = '09123456789';
|
||||
const deviceName = 'Test Device';
|
||||
final authRequest = {
|
||||
'username': 'test@example.com',
|
||||
'password': 'wrong',
|
||||
@@ -158,28 +144,18 @@ void main() {
|
||||
|
||||
// Mock the flow
|
||||
when(
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
() => mockAuthRemote.getUserInfo(phoneNumber),
|
||||
).thenAnswer((_) async => expectedUserInfo);
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
() => mockAuthRemote.login(authRequest: authRequest),
|
||||
).thenAnswer((_) async => null);
|
||||
|
||||
// Act - Step 1: Get user info (success)
|
||||
final userInfo = await authRepository.getUserInfo(phoneNumber);
|
||||
expect(userInfo, equals(expectedUserInfo));
|
||||
|
||||
// Act - Step 2: Submit user info (success)
|
||||
await authRepository.submitUserInfo(
|
||||
phone: phoneNumber,
|
||||
deviceName: deviceName,
|
||||
);
|
||||
|
||||
// Act - Step 3: Login (failure)
|
||||
// Act - Step 2: Login (failure)
|
||||
final userProfile = await authRepository.login(
|
||||
authRequest: authRequest,
|
||||
);
|
||||
@@ -187,7 +163,6 @@ void main() {
|
||||
// Assert
|
||||
expect(userProfile, isNull);
|
||||
verify(() => mockAuthRemote.getUserInfo(phoneNumber)).called(1);
|
||||
verify(() => mockAuthRemote.submitUserInfo(any())).called(1);
|
||||
verify(() => mockAuthRemote.login(authRequest: authRequest)).called(1);
|
||||
});
|
||||
});
|
||||
@@ -209,7 +184,7 @@ void main() {
|
||||
test('should track authentication state correctly', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
).thenAnswer((_) async => true);
|
||||
|
||||
// Act
|
||||
@@ -223,7 +198,7 @@ void main() {
|
||||
test('should handle authentication state changes', () async {
|
||||
// Arrange
|
||||
when(
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
() => mockAuthRemote.hasAuthenticated(),
|
||||
).thenAnswer((_) async => false);
|
||||
|
||||
// Act
|
||||
@@ -236,40 +211,23 @@ void main() {
|
||||
});
|
||||
|
||||
group('User Info Management', () {
|
||||
test('should handle user info submission without device name', () async {
|
||||
test('should get user info by phone', () async {
|
||||
// Arrange
|
||||
const phone = '09123456789';
|
||||
final expectedData = {'mobile': phone, 'device_name': null};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.submitUserInfo(phone: phone);
|
||||
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.submitUserInfo(expectedData)).called(1);
|
||||
});
|
||||
|
||||
test('should handle user info submission with device name', () async {
|
||||
// Arrange
|
||||
const phone = '09123456789';
|
||||
const deviceName = 'Test Device';
|
||||
final expectedData = {'mobile': phone, 'device_name': deviceName};
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.submitUserInfo(any()),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
// Act
|
||||
await authRepository.submitUserInfo(
|
||||
phone: phone,
|
||||
deviceName: deviceName,
|
||||
final expectedUserInfo = UserInfoModel(
|
||||
isUser: true,
|
||||
address: 'Test Address',
|
||||
backend: 'test-backend',
|
||||
apiKey: 'test-api-key',
|
||||
);
|
||||
|
||||
when(
|
||||
() => mockAuthRemote.getUserInfo(phone),
|
||||
).thenAnswer((_) async => expectedUserInfo);
|
||||
// Act
|
||||
final res = await authRepository.getUserInfo(phone);
|
||||
// Assert
|
||||
verify(() => mockAuthRemote.submitUserInfo(expectedData)).called(1);
|
||||
expect(res, expectedUserInfo);
|
||||
verify(() => mockAuthRemote.getUserInfo(phone)).called(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user