fix(#763): a complete sync ends a recovery still checking by key

Second pre-PR review: a refresh that came back complete while the by-key
checks were still running cleared the union, and the leftover check loop
then reported a shortfall against it. The complete path now bumps the
run counter and stops the loop and the settle timer. Test proves it:
fails without the fix, passes with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix/793-log-composer-budget
diffwireauto 1 month ago committed by Benjamin Wiechel
parent 49c77f09db
commit c458332da2

@ -3957,6 +3957,11 @@ class MeshCoreConnector extends ChangeNotifier {
_contactSyncDecisionPending = false;
_recoveryDelivered.clear();
_recoveryGone.clear();
// A complete sync ends any recovery still running, so a leftover by-key
// loop cannot report a shortfall against the cleared union. (Gemini)
_recoveryRun++;
_recoveryCheckingKeys = false;
_recoverySettleTimer?.cancel();
return;
}

@ -418,6 +418,30 @@ void main() {
expect(names(), {'Alpha', 'Bravo', 'Charlie'});
});
test(
'a complete sync during the by-key checks ends the recovery',
() async {
seedSaved();
final alpha = [_contactFrame(0x11, 'Alpha')];
await connector.getContacts();
await answerStream(350, alpha);
await answerStream(350, alpha);
await answerStream(350, alpha);
// The by-key checks are running; a refresh now comes back complete.
await connector.getContacts();
await answerStream(3, [
_contactFrame(0x11, 'Alpha'),
_contactFrame(0x22, 'Bravo'),
_contactFrame(0x33, 'Charlie'),
]);
await Future<void>.delayed(const Duration(milliseconds: 100));
expect(connector.contactSyncShortfall, isNull);
expect(connector.contactSyncDecisionPending, isFalse);
expect(names(), {'Alpha', 'Bravo', 'Charlie'});
},
);
test('the banner cannot be dismissed while a decision is open', () async {
await threeShortSyncs();
connector.dismissContactSyncShortfall();

Loading…
Cancel
Save

Powered by TurnKey Linux.