Files
eatvio_app/test/fixtures/doubles/insights_doubles.dart
2026-11-11 16:05:11 +03:00

132 lines
3.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
));
}
}