/ app / test / providers / group_messages_provider_test.dart
group_messages_provider_test.dart
  1  import 'dart:typed_data';
  2  
  3  import 'package:dead_drop/providers/groups_provider.dart';
  4  import 'package:dead_drop/providers/messages_provider.dart' show bytesToHex;
  5  import 'package:dead_drop/services/dead_drop_service.dart';
  6  import 'package:flutter_riverpod/flutter_riverpod.dart';
  7  import 'package:flutter_test/flutter_test.dart';
  8  import 'package:mocktail/mocktail.dart';
  9  
 10  import '../fixtures/test_fixtures.dart';
 11  import '../helpers/test_helpers.dart';
 12  import '../mocks/mock_dead_drop_service.dart';
 13  
 14  class MockUninitializedService extends MockDeadDropService {
 15    @override
 16    bool get isInitialized => false;
 17  }
 18  
 19  void main() {
 20    late MockDeadDropService mockService;
 21    late ProviderContainer container;
 22  
 23    setUpAll(() {
 24      registerFallbackValue(Uint8List(16));
 25      registerFallbackValue(<int>[]);
 26    });
 27  
 28    setUp(() {
 29      mockService = MockDeadDropService();
 30    });
 31  
 32    tearDown(() {
 33      container.dispose();
 34    });
 35  
 36    group('GroupMessagesNotifier', () {
 37      test('build() returns empty list when service not initialized', () async {
 38        final uninitService = MockUninitializedService();
 39  
 40        final groupIdHex = bytesToHex(TestFixtures.groupId(1));
 41        container = createTestContainer(mockService: uninitService);
 42        final result =
 43            await container.read(groupMessagesProvider(groupIdHex).future);
 44  
 45        expect(result, isEmpty);
 46      });
 47  
 48      test('build() returns group messages from service', () async {
 49        final groupId = TestFixtures.groupId(1);
 50        final groupIdHex = bytesToHex(groupId);
 51        final msg1 = TestFixtures.messageInfo(
 52          messageIdBytes: TestFixtures.messageId(1),
 53          groupIdBytes: groupId,
 54        );
 55        final msg2 = TestFixtures.messageInfo(
 56          messageIdBytes: TestFixtures.messageId(2),
 57          groupIdBytes: groupId,
 58        );
 59  
 60        when(() => mockService.getGroupConversation(any()))
 61            .thenReturn([msg1, msg2]);
 62  
 63        container = createTestContainer(mockService: mockService);
 64        final result =
 65            await container.read(groupMessagesProvider(groupIdHex).future);
 66  
 67        expect(result, hasLength(2));
 68        verify(() => mockService.getGroupConversation(any())).called(1);
 69      });
 70  
 71      test('sendText() calls sendGroupMessage and refreshes state', () async {
 72        final groupId = TestFixtures.groupId(1);
 73        final groupIdHex = bytesToHex(groupId);
 74  
 75        when(() => mockService.getGroupConversation(any())).thenReturn([]);
 76        when(() => mockService.sendGroupMessage(any(), any(), any()))
 77            .thenAnswer((_) async => TestFixtures.messageId(10));
 78        when(() => mockService.getGroupMembers(any())).thenReturn([]);
 79  
 80        container = createTestContainer(mockService: mockService);
 81        await container.read(groupMessagesProvider(groupIdHex).future);
 82  
 83        await container
 84            .read(groupMessagesProvider(groupIdHex).notifier)
 85            .sendText('Hello group');
 86  
 87        verify(() => mockService.sendGroupMessage(any(), any(), ContentType.text))
 88            .called(1);
 89        // getGroupConversation called: once for build, once for refresh
 90        verify(() => mockService.getGroupConversation(any())).called(2);
 91      });
 92  
 93      test('sendDocument() calls sendGroupDocument and refreshes state',
 94          () async {
 95        final groupId = TestFixtures.groupId(1);
 96        final groupIdHex = bytesToHex(groupId);
 97        final content = Uint8List.fromList([1, 2, 3]);
 98  
 99        when(() => mockService.getGroupConversation(any())).thenReturn([]);
100        when(() => mockService.sendGroupDocument(any(), any(), any()))
101            .thenAnswer((_) async => TestFixtures.messageId(20));
102        when(() => mockService.getGroupMembers(any())).thenReturn([]);
103  
104        container = createTestContainer(mockService: mockService);
105        await container.read(groupMessagesProvider(groupIdHex).future);
106  
107        await container
108            .read(groupMessagesProvider(groupIdHex).notifier)
109            .sendDocument(content, 'test.pdf');
110  
111        verify(() => mockService.sendGroupDocument(any(), any(), 'test.pdf'))
112            .called(1);
113        verify(() => mockService.getGroupConversation(any())).called(2);
114      });
115  
116      test('refresh() reloads messages from service', () async {
117        final groupId = TestFixtures.groupId(1);
118        final groupIdHex = bytesToHex(groupId);
119  
120        when(() => mockService.getGroupConversation(any())).thenReturn([]);
121  
122        container = createTestContainer(mockService: mockService);
123        await container.read(groupMessagesProvider(groupIdHex).future);
124  
125        // Add a message for next fetch
126        final msg = TestFixtures.messageInfo(groupIdBytes: groupId);
127        when(() => mockService.getGroupConversation(any())).thenReturn([msg]);
128  
129        await container
130            .read(groupMessagesProvider(groupIdHex).notifier)
131            .refresh();
132  
133        final result = container.read(groupMessagesProvider(groupIdHex)).value;
134        expect(result, hasLength(1));
135      });
136    });
137  
138    group('groupMembersProvider', () {
139      test('returns members from service', () {
140        final groupId = TestFixtures.groupId(1);
141        final groupIdHex = bytesToHex(groupId);
142        final member1 = TestFixtures.groupMemberInfo(
143          contactIdBytes: TestFixtures.contactId(1),
144          nickname: 'Alice',
145          role: 1,
146        );
147        final member2 = TestFixtures.groupMemberInfo(
148          contactIdBytes: TestFixtures.contactId(2),
149          nickname: 'Bob',
150        );
151  
152        when(() => mockService.getGroupMembers(any()))
153            .thenReturn([member1, member2]);
154  
155        container = createTestContainer(mockService: mockService);
156        final result = container.read(groupMembersProvider(groupIdHex));
157  
158        expect(result, hasLength(2));
159        expect(result[0].nickname, equals('Alice'));
160        expect(result[0].role, equals(1));
161        expect(result[1].nickname, equals('Bob'));
162        expect(result[1].role, equals(0));
163      });
164  
165      test('returns empty list when service not initialized', () {
166        final uninitService = MockUninitializedService();
167  
168        final groupIdHex = bytesToHex(TestFixtures.groupId(1));
169        container = createTestContainer(mockService: uninitService);
170        final result = container.read(groupMembersProvider(groupIdHex));
171  
172        expect(result, isEmpty);
173      });
174    });
175  }