wake-alarm/phone_app/test/home_history_card_test.dart
Krzysztof kuhy Rudnicki c3c129b068 Make the morning session the carrot: earn 11:00 by finishing it in time
On 2026-09-19 the phone was powered off after the bathroom tag and nothing
on the PC noticed: every finished session was published and nothing read
it. Now wake-alarm distils the phone's morning into an HMAC-signed
~/.local/state/wake_alarm/morning_session.json (wake-alarm-session.timer,
07:00-11:00 every 2 min) that screen-locker and leetcode-guard read to
defer their locks -- provisionally until min(start + 90 min, 09:30) while
the session is live, until 11:00 once it completed inside that cutoff,
and not at all for a session finished later (the phone switched on at
noon completes the legs then; that must un-lock nothing).

The phone publishes the session at start as well as at finish
(current_session, cleared with the finish stamp), so the PC can tell
"started, not finished" from "never started". A required 1-5 energy tap
joins the weigh-in and ships as latest_energy with a PC reader mirroring
_weight (the shared half is _field_reader).

Also fixes the vmbox harness, red since the 2026-09-11 home-tidy: the
guest tree lives at ~/wake-alarm, and the INSTALL-OK grep matched vm's
echo of the command line. Takes Flutter 3.47.5.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tp54ewdXRLaimUuT8LgYyn
2026-09-19 16:40:51 +02:00

88 lines
2.7 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 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:wake_alarm_sync/screens/home_history_card.dart';
import 'package:wake_alarm_sync/services/morning_session.dart';
import 'package:wake_alarm_sync/services/session_rules.dart';
import 'package:wake_alarm_sync/services/session_store.dart';
import 'package:wake_alarm_sync/services/session_tag_settings.dart';
MorningSession _session(
DateTime at, {
double? kg,
int reRings = 0,
SessionOutcome outcome = SessionOutcome.completed,
}) =>
SessionRules.start(
now: at,
tags: const SessionTagSettings(),
nfcAvailable: false,
)
..weightKg = kg
..reRings = reRings
..outcome = outcome;
void main() {
setUp(() => SharedPreferences.setMockInitialValues(<String, Object>{}));
test('describes a morning in one line', () {
expect(
describeMorning(
_session(DateTime(2026, 9, 17, 8), kg: 72.4, reRings: 1),
previousWeight: 72.7,
),
'09-17 ✓ 1 re-ring · 72.4 kg (−0.3)',
);
expect(
describeMorning(
_session(
DateTime(2026, 9, 16, 8),
kg: 73,
outcome: SessionOutcome.failed,
),
previousWeight: 72,
),
'09-16 ✗ 0 re-rings · 73.0 kg (+1.0)',
);
expect(
describeMorning(
_session(DateTime(2026, 9, 15, 8), kg: 72),
previousWeight: 72,
),
'09-15 ✓ 0 re-rings · 72.0 kg (±0.0)',
);
expect(
describeMorning(
_session(DateTime(2026, 9, 14, 8), outcome: SessionOutcome.active),
),
'09-14 … 0 re-rings',
);
expect(
describeMorning(_session(DateTime(2026, 9, 13, 8), kg: 72)..energy = 4),
'09-13 ✓ 0 re-rings · 72.0 kg · energy 4/5',
);
});
testWidgets('is absent until a morning has finished', (tester) async {
await tester.pumpWidget(const MaterialApp(home: HomeHistoryCard()));
await tester.pump();
expect(find.text('Last mornings'), findsNothing);
});
testWidgets('lists the last seven with weight deltas', (tester) async {
final store = SessionStore();
for (var day = 1; day <= 9; day++) {
await store.archive(_session(DateTime(2026, 9, day, 8), kg: 70.0 + day));
}
await tester.pumpWidget(const MaterialApp(home: HomeHistoryCard()));
await tester.pump();
expect(find.text('Last mornings'), findsOneWidget);
expect(
find.textContaining('09-09 ✓ 0 re-rings · 79.0 kg (+1.0)'),
findsOne,
);
expect(find.textContaining('09-03'), findsOneWidget);
expect(find.textContaining('09-02'), findsNothing);
});
}