import 'package:flutter_test/flutter_test.dart'; import 'package:relationship_saver/app/state/local_data_state.dart'; import 'package:relationship_saver/features/ai_digest/application/anonymized_llm_context_builder.dart'; import 'package:relationship_saver/features/dashboard/domain/dashboard_models.dart'; import 'package:relationship_saver/features/ideas/domain/idea_models.dart'; import 'package:relationship_saver/features/moments/domain/moment_models.dart'; import 'package:relationship_saver/features/people/domain/person_models.dart'; import 'package:relationship_saver/features/reminders/domain/reminder_models.dart'; import 'package:relationship_saver/features/share_intake/domain/share_models.dart'; void main() { test('builds pseudonymous payload without identifiable profile data', () { final LocalDataState state = LocalDataState( people: [ PersonProfile( id: 'p-1', name: 'Alice Secret', relationship: 'Sister', affinityScore: 85, nextMoment: DateTime(2026, 6, 1), tags: const ['coffee', 'books'], notes: 'Passport number and private address should stay local.', aliases: const ['Ally'], location: 'Zurich, Switzerland', lastInteractedAt: DateTime(2026, 5, 1), ), ], moments: const [], ideas: const [], reminders: const [], tasks: const [], sourceLinks: [ SourceProfileLink( id: 'sl-1', sourceApp: 'whatsapp', normalizedDisplayName: 'Alice Secret', profileId: 'p-1', firstSeenAt: DateTime(2026, 5, 1), lastSeenAt: DateTime(2026, 5, 1), sourceUserId: 'wa:alice', sourceThreadId: 'thread-secret', sourceFingerprint: 'whatsapp|u:wa:alice', ), ], sharedMessages: [ SharedMessageEntry( id: 'sm-1', profileId: 'p-1', payload: SharedPayload( sourceApp: 'whatsapp', payloadType: SharedPayloadType.text, rawText: 'Raw private chat text', createdAt: DateTime(2026, 5, 1), receivedAt: DateTime(2026, 5, 1), platform: 'ios', sourceDisplayName: 'Alice Secret', sourceUserId: 'wa:alice', sourceThreadId: 'thread-secret', ), importedAt: DateTime(2026, 5, 1), resolvedAutomatically: true, ), ], personFacts: [ PersonFact( id: 'pf-1', personId: 'p-1', type: CapturedFactType.note, text: 'Secret medical detail', sourceKind: CaptureSourceKind.manual, createdAt: DateTime(2026, 5, 1), updatedAt: DateTime(2026, 5, 1), isSensitive: true, ), ], ); final AnonymizedLlmDigestContext context = AnonymizedLlmContextBuilder( now: () => DateTime(2026, 5, 16), ).build(state); final String prompt = context.toPromptJson(); expect(context.tokenToPersonId, {'person_001': 'p-1'}); expect(prompt, contains('person_001')); expect(prompt, isNot(contains('Alice'))); expect(prompt, isNot(contains('Ally'))); expect(prompt, isNot(contains('Zurich'))); expect(prompt, isNot(contains('Passport'))); expect(prompt, isNot(contains('wa:alice'))); expect(prompt, isNot(contains('thread-secret'))); expect(prompt, isNot(contains('Raw private chat text'))); expect(prompt, isNot(contains('Secret medical detail'))); }); }