forked from eatvio/eatvio_app
132 lines
3.8 KiB
Dart
132 lines
3.8 KiB
Dart
import 'dart:convert';
|
||
import 'dart:io';
|
||
|
||
import 'package:eatvio_app/features/insights/models/insights_payload_model.dart';
|
||
import 'package:eatvio_app/features/insights/models/insights_period.dart';
|
||
import 'package:eatvio_app/features/insights/repositories/insights_repository.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
InsightsPayloadModel loadInsightsPayloadFixture([
|
||
String name = 'insights_payload.json',
|
||
]) {
|
||
final json =
|
||
jsonDecode(File('test/fixtures/insights/$name').readAsStringSync())
|
||
as Map<String, dynamic>;
|
||
return InsightsPayloadModel.fromJson(json);
|
||
}
|
||
|
||
/// Подмена [InsightsRepository] для виджет-тестов: без сети, с журналом вызовов.
|
||
class FakeInsightsRepository extends Fake implements InsightsRepository {
|
||
FakeInsightsRepository({
|
||
InsightsPayloadModel? payload,
|
||
this.error,
|
||
this.heightCm = 176,
|
||
}) : payload = payload ?? loadInsightsPayloadFixture();
|
||
|
||
InsightsPayloadModel payload;
|
||
|
||
/// Ответ [fetchIntra] по запрошенной дате (`YYYY-MM-DD`); для остальных дат
|
||
/// берётся `payload.intra`.
|
||
final Map<String, IntraChartModel> intraByDate = {};
|
||
|
||
/// Если задан — выбрасывается из [fetchIntra].
|
||
Object? intraError;
|
||
|
||
/// Если задан — выбрасывается из [getInsights] (например, [InsightsForbidden]).
|
||
Object? error;
|
||
int? heightCm;
|
||
|
||
/// Задержка ответа [fetchInsights] (для тестов гонок).
|
||
Duration? fetchInsightsDelay;
|
||
|
||
/// Задержка ответа [fetchIntra] (для тестов гонок).
|
||
Duration? fetchIntraDelay;
|
||
|
||
final List<({String? slug, BodyPeriod period})> insightsRequests = [];
|
||
final List<
|
||
({
|
||
String? slug,
|
||
BodyPeriod bodyPeriod,
|
||
DailyPeriod dailyPeriod,
|
||
String? intraDate,
|
||
})
|
||
>
|
||
serverRequests = [];
|
||
final List<({String? slug, String? date})> intraRequests = [];
|
||
final List<double> addedWeights = [];
|
||
final List<({int chest, int waist, int hip})> addedCircumferences = [];
|
||
|
||
@override
|
||
Future<int?> getHeightCm({String? slug}) async => heightCm;
|
||
|
||
@override
|
||
Future<InsightsPayloadModel> getInsights({
|
||
String? slug,
|
||
required BodyPeriod bodyPeriod,
|
||
int? heightCm,
|
||
}) async {
|
||
insightsRequests.add((slug: slug, period: bodyPeriod));
|
||
final failure = error;
|
||
if (failure != null) {
|
||
throw failure;
|
||
}
|
||
return payload;
|
||
}
|
||
|
||
@override
|
||
Future<InsightsPayloadModel> fetchInsights({
|
||
String? slug,
|
||
required BodyPeriod bodyPeriod,
|
||
required DailyPeriod dailyPeriod,
|
||
String? intraDate,
|
||
}) async {
|
||
serverRequests.add((
|
||
slug: slug,
|
||
bodyPeriod: bodyPeriod,
|
||
dailyPeriod: dailyPeriod,
|
||
intraDate: intraDate,
|
||
));
|
||
final delay = fetchInsightsDelay;
|
||
if (delay != null) {
|
||
await Future<void>.delayed(delay);
|
||
}
|
||
final failure = error;
|
||
if (failure != null) {
|
||
throw failure;
|
||
}
|
||
return payload;
|
||
}
|
||
|
||
@override
|
||
Future<IntraChartModel> fetchIntra({String? slug, String? intraDate}) async {
|
||
intraRequests.add((slug: slug, date: intraDate));
|
||
final delay = fetchIntraDelay;
|
||
if (delay != null) {
|
||
await Future<void>.delayed(delay);
|
||
}
|
||
final failure = intraError ?? error;
|
||
if (failure != null) {
|
||
throw failure;
|
||
}
|
||
return intraByDate[intraDate] ?? payload.intra!;
|
||
}
|
||
|
||
@override
|
||
Future<void> addWeight({required double weight}) async {
|
||
addedWeights.add(weight);
|
||
}
|
||
|
||
@override
|
||
Future<void> addCircumference({
|
||
required int chestCircumference,
|
||
required int waistCircumference,
|
||
required int hipCircumference,
|
||
}) async {
|
||
addedCircumferences.add((
|
||
chest: chestCircumference,
|
||
waist: waistCircumference,
|
||
hip: hipCircumference,
|
||
));
|
||
}
|
||
}
|