import 'package:flutter/material.dart'; import 'package:flutter_boring_avatars/flutter_boring_avatars.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tane/services/profile_cache.dart'; import 'package:tane/ui/avatar.dart'; import 'package:tane/ui/peer_avatar.dart'; import 'package:tane/ui/seed_glyph.dart'; import '../support/test_support.dart'; void main() { group('avatar value scheme', () { test('every offered illustration maps to a glyph; unknown → null', () { for (final name in avatarGlyphNames) { expect(avatarGlyphChar(name), isNotNull, reason: name); } expect(avatarGlyphChar('nope'), isNull); expect(avatarGlyphToken('jars'), 'tane:seed:jars'); }); }); group('peerAvatarColor', () { test('is deterministic for the same pubkey', () { expect(peerAvatarColor('ab' * 32), peerAvatarColor('ab' * 32)); }); test('differs for different pubkeys', () { expect(peerAvatarColor('ab' * 32), isNot(peerAvatarColor('cd' * 32))); }); test('is fully opaque (legible disc)', () { expect(peerAvatarColor('feed').a, 1.0); }); }); group('PeerAvatar', () { Widget host(Widget child) => MaterialApp( home: Scaffold(body: Center(child: child)), ); testWidgets('falls back to a generated pattern keyed by pubkey', ( tester, ) async { await tester.pumpWidget(host(PeerAvatar(pubkey: 'aa', name: 'rosa'))); final generated = tester.widget(find.byType(BoringAvatar)); expect(generated.name, 'aa'); // pubkey, not name → stable across renames expect(find.byType(Text), findsNothing); }); testWidgets('generates it even when the name is unknown', (tester) async { await tester.pumpWidget(host(const PeerAvatar(pubkey: 'aa'))); expect(find.byType(BoringAvatar), findsOneWidget); }); testWidgets('renders a seed illustration when the avatar is a token', ( tester, ) async { await tester.pumpWidget(host(const PeerAvatar( pubkey: 'aa', name: 'rosa', picture: 'tane:seed:jars'))); expect(find.byType(SeedGlyph), findsOneWidget); expect(find.text('R'), findsNothing); // the initial isn't used }); }); group('CachedAvatar', () { Widget host(Widget child) => MaterialApp( home: Scaffold(body: Center(child: child)), ); testWidgets('paints the cached illustration for the peer', (tester) async { final cache = ProfileCache(InMemorySecretStore()); await cache.setPicture('peer1', 'tane:seed:sack'); await tester.pumpWidget(host( CachedAvatar(pubkey: 'peer1', name: 'Bea', cache: cache))); await tester.pumpAndSettle(); expect(find.byType(SeedGlyph), findsOneWidget); }); testWidgets('falls back to the generated pattern when nothing is cached', ( tester, ) async { final cache = ProfileCache(InMemorySecretStore()); await tester.pumpWidget(host( CachedAvatar(pubkey: 'peer2', name: 'Bea', cache: cache))); await tester.pumpAndSettle(); expect(find.byType(BoringAvatar), findsOneWidget); }); testWidgets('no cache → the generated pattern', (tester) async { await tester.pumpWidget(host(const CachedAvatar(pubkey: 'x', name: 'Bea'))); expect(find.byType(BoringAvatar), findsOneWidget); }); }); }