feat: add local-first private AI digest workflow
Migrate app code into canonical feature slices, add phone-only AI digest scheduling and review, wire local notification/background task support, and cover the flow with tests.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:relationship_saver/core/llm/captured_fact_draft_parser.dart';
|
||||
import 'package:relationship_saver/features/share_intake/domain/share_models.dart';
|
||||
|
||||
void main() {
|
||||
test('parses a JSON suggestion into a captured draft', () {
|
||||
final SharedPayload payload = SharedPayload(
|
||||
sourceApp: 'signal',
|
||||
payloadType: SharedPayloadType.text,
|
||||
rawText: 'Mila birthday is on 2026-05-20',
|
||||
createdAt: DateTime.utc(2026, 4, 17),
|
||||
receivedAt: DateTime.utc(2026, 4, 17),
|
||||
platform: 'android',
|
||||
);
|
||||
final CapturedFactDraft? result = parseCapturedFactDraftSuggestion(
|
||||
'{"type":"importantDate","text":"Birthday to remember","label":"Birthday","dateValue":"2026-05-20","confidence":0.88,"isSensitive":false}',
|
||||
fallbackPayload: payload,
|
||||
);
|
||||
|
||||
expect(result, isNotNull);
|
||||
expect(result!.type, CapturedFactType.importantDate);
|
||||
expect(result.label, 'Birthday');
|
||||
expect(result.dateValue, DateTime(2026, 5, 20));
|
||||
expect(result.confidence, 0.88);
|
||||
expect(result.needsReview, isTrue);
|
||||
});
|
||||
|
||||
test('falls back to payload text when suggestion text is missing', () {
|
||||
final SharedPayload payload = SharedPayload(
|
||||
sourceApp: 'signal',
|
||||
payloadType: SharedPayloadType.text,
|
||||
rawText: 'Mila birthday is on 2026-05-20',
|
||||
createdAt: DateTime.utc(2026, 4, 17),
|
||||
receivedAt: DateTime.utc(2026, 4, 17),
|
||||
platform: 'android',
|
||||
);
|
||||
final CapturedFactDraft? result = parseCapturedFactDraftSuggestion(
|
||||
'{"type":"note","label":""}',
|
||||
fallbackPayload: payload,
|
||||
);
|
||||
|
||||
expect(result, isNotNull);
|
||||
expect(result!.text, payload.rawText);
|
||||
expect(result.label, isNull);
|
||||
});
|
||||
|
||||
test('returns null for non-json responses', () {
|
||||
final SharedPayload payload = SharedPayload(
|
||||
sourceApp: 'signal',
|
||||
payloadType: SharedPayloadType.text,
|
||||
rawText: 'Mila birthday is on 2026-05-20',
|
||||
createdAt: DateTime.utc(2026, 4, 17),
|
||||
receivedAt: DateTime.utc(2026, 4, 17),
|
||||
platform: 'android',
|
||||
);
|
||||
final CapturedFactDraft? result = parseCapturedFactDraftSuggestion(
|
||||
'No structured output available.',
|
||||
fallbackPayload: payload,
|
||||
);
|
||||
|
||||
expect(result, isNull);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user