Main coves client
1import 'package:coves_flutter/models/community.dart';
2import 'package:flutter_test/flutter_test.dart';
3
4void main() {
5 group('CommunitiesResponse', () {
6 test('should parse valid JSON with communities', () {
7 final json = {
8 'communities': [
9 {
10 'did': 'did:plc:community1',
11 'name': 'test-community',
12 'handle': 'test.coves.social',
13 'displayName': 'Test Community',
14 'description': 'A test community',
15 'avatar': 'https://example.com/avatar.jpg',
16 'visibility': 'public',
17 'subscriberCount': 100,
18 'memberCount': 50,
19 'postCount': 200,
20 },
21 ],
22 'cursor': 'next-cursor',
23 };
24
25 final response = CommunitiesResponse.fromJson(json);
26
27 expect(response.communities.length, 1);
28 expect(response.cursor, 'next-cursor');
29 expect(response.communities[0].did, 'did:plc:community1');
30 expect(response.communities[0].name, 'test-community');
31 expect(response.communities[0].displayName, 'Test Community');
32 });
33
34 test('should handle null communities array', () {
35 final json = {
36 'communities': null,
37 'cursor': null,
38 };
39
40 final response = CommunitiesResponse.fromJson(json);
41
42 expect(response.communities, isEmpty);
43 expect(response.cursor, null);
44 });
45
46 test('should handle empty communities array', () {
47 final json = {
48 'communities': [],
49 'cursor': null,
50 };
51
52 final response = CommunitiesResponse.fromJson(json);
53
54 expect(response.communities, isEmpty);
55 expect(response.cursor, null);
56 });
57
58 test('should parse without cursor', () {
59 final json = {
60 'communities': [
61 {
62 'did': 'did:plc:community1',
63 'name': 'test-community',
64 },
65 ],
66 };
67
68 final response = CommunitiesResponse.fromJson(json);
69
70 expect(response.cursor, null);
71 expect(response.communities.length, 1);
72 });
73 });
74
75 group('CommunityView', () {
76 test('should parse complete JSON with all fields', () {
77 final json = {
78 'did': 'did:plc:community1',
79 'name': 'test-community',
80 'handle': 'test.coves.social',
81 'displayName': 'Test Community',
82 'description': 'A community for testing',
83 'avatar': 'https://example.com/avatar.jpg',
84 'visibility': 'public',
85 'subscriberCount': 1000,
86 'memberCount': 500,
87 'postCount': 2500,
88 'viewer': {
89 'subscribed': true,
90 'member': false,
91 },
92 };
93
94 final community = CommunityView.fromJson(json);
95
96 expect(community.did, 'did:plc:community1');
97 expect(community.name, 'test-community');
98 expect(community.handle, 'test.coves.social');
99 expect(community.displayName, 'Test Community');
100 expect(community.description, 'A community for testing');
101 expect(community.avatar, 'https://example.com/avatar.jpg');
102 expect(community.visibility, 'public');
103 expect(community.subscriberCount, 1000);
104 expect(community.memberCount, 500);
105 expect(community.postCount, 2500);
106 expect(community.viewer, isNotNull);
107 expect(community.viewer!.subscribed, true);
108 expect(community.viewer!.member, false);
109 });
110
111 test('should parse minimal JSON with required fields only', () {
112 final json = {
113 'did': 'did:plc:community1',
114 'name': 'test-community',
115 };
116
117 final community = CommunityView.fromJson(json);
118
119 expect(community.did, 'did:plc:community1');
120 expect(community.name, 'test-community');
121 expect(community.handle, null);
122 expect(community.displayName, null);
123 expect(community.description, null);
124 expect(community.avatar, null);
125 expect(community.visibility, null);
126 expect(community.subscriberCount, null);
127 expect(community.memberCount, null);
128 expect(community.postCount, null);
129 expect(community.viewer, null);
130 });
131
132 test('should handle null optional fields', () {
133 final json = {
134 'did': 'did:plc:community1',
135 'name': 'test-community',
136 'handle': null,
137 'displayName': null,
138 'description': null,
139 'avatar': null,
140 'visibility': null,
141 'subscriberCount': null,
142 'memberCount': null,
143 'postCount': null,
144 'viewer': null,
145 };
146
147 final community = CommunityView.fromJson(json);
148
149 expect(community.did, 'did:plc:community1');
150 expect(community.name, 'test-community');
151 expect(community.handle, null);
152 expect(community.displayName, null);
153 expect(community.description, null);
154 expect(community.avatar, null);
155 expect(community.visibility, null);
156 expect(community.subscriberCount, null);
157 expect(community.memberCount, null);
158 expect(community.postCount, null);
159 expect(community.viewer, null);
160 });
161 });
162
163 group('CommunityViewerState', () {
164 test('should parse with all fields', () {
165 final json = {
166 'subscribed': true,
167 'member': true,
168 };
169
170 final viewer = CommunityViewerState.fromJson(json);
171
172 expect(viewer.subscribed, true);
173 expect(viewer.member, true);
174 });
175
176 test('should parse with false values', () {
177 final json = {
178 'subscribed': false,
179 'member': false,
180 };
181
182 final viewer = CommunityViewerState.fromJson(json);
183
184 expect(viewer.subscribed, false);
185 expect(viewer.member, false);
186 });
187
188 test('should handle null values', () {
189 final json = {
190 'subscribed': null,
191 'member': null,
192 };
193
194 final viewer = CommunityViewerState.fromJson(json);
195
196 expect(viewer.subscribed, null);
197 expect(viewer.member, null);
198 });
199
200 test('should handle missing fields', () {
201 final json = <String, dynamic>{};
202
203 final viewer = CommunityViewerState.fromJson(json);
204
205 expect(viewer.subscribed, null);
206 expect(viewer.member, null);
207 });
208 });
209
210 group('CreatePostResponse', () {
211 test('should parse valid JSON', () {
212 final json = {
213 'uri': 'at://did:plc:test/social.coves.community.post/123',
214 'cid': 'bafyreicid123',
215 };
216
217 final response = CreatePostResponse.fromJson(json);
218
219 expect(response.uri, 'at://did:plc:test/social.coves.community.post/123');
220 expect(response.cid, 'bafyreicid123');
221 });
222
223 test('should be const constructible', () {
224 const response = CreatePostResponse(
225 uri: 'at://did:plc:test/post/123',
226 cid: 'cid123',
227 );
228
229 expect(response.uri, 'at://did:plc:test/post/123');
230 expect(response.cid, 'cid123');
231 });
232 });
233
234 group('ExternalEmbedInput', () {
235 test('should serialize complete JSON', () {
236 const embed = ExternalEmbedInput(
237 uri: 'https://example.com/article',
238 title: 'Article Title',
239 description: 'Article description',
240 thumb: 'https://example.com/thumb.jpg',
241 );
242
243 final json = embed.toJson();
244
245 expect(json['uri'], 'https://example.com/article');
246 expect(json['title'], 'Article Title');
247 expect(json['description'], 'Article description');
248 expect(json['thumb'], 'https://example.com/thumb.jpg');
249 });
250
251 test('should serialize minimal JSON with only required fields', () {
252 const embed = ExternalEmbedInput(
253 uri: 'https://example.com/article',
254 );
255
256 final json = embed.toJson();
257
258 expect(json['uri'], 'https://example.com/article');
259 expect(json.containsKey('title'), false);
260 expect(json.containsKey('description'), false);
261 expect(json.containsKey('thumb'), false);
262 });
263
264 test('should be const constructible', () {
265 const embed = ExternalEmbedInput(
266 uri: 'https://example.com',
267 title: 'Test',
268 );
269
270 expect(embed.uri, 'https://example.com');
271 expect(embed.title, 'Test');
272 });
273 });
274
275 group('SelfLabels', () {
276 test('should serialize to JSON', () {
277 const labels = SelfLabels(
278 values: [
279 SelfLabel(val: 'nsfw'),
280 SelfLabel(val: 'spoiler'),
281 ],
282 );
283
284 final json = labels.toJson();
285
286 expect(json['values'], isA<List>());
287 expect((json['values'] as List).length, 2);
288 expect((json['values'] as List)[0]['val'], 'nsfw');
289 expect((json['values'] as List)[1]['val'], 'spoiler');
290 });
291
292 test('should be const constructible', () {
293 const labels = SelfLabels(
294 values: [SelfLabel(val: 'nsfw')],
295 );
296
297 expect(labels.values.length, 1);
298 expect(labels.values[0].val, 'nsfw');
299 });
300 });
301
302 group('SelfLabel', () {
303 test('should serialize to JSON', () {
304 const label = SelfLabel(val: 'nsfw');
305
306 final json = label.toJson();
307
308 expect(json['val'], 'nsfw');
309 });
310
311 test('should be const constructible', () {
312 const label = SelfLabel(val: 'spoiler');
313
314 expect(label.val, 'spoiler');
315 });
316 });
317
318 group('CreatePostRequest', () {
319 test('should serialize complete request', () {
320 final request = CreatePostRequest(
321 community: 'did:plc:community1',
322 title: 'Test Post',
323 content: 'Post content here',
324 embed: const ExternalEmbedInput(
325 uri: 'https://example.com',
326 title: 'Link Title',
327 ),
328 langs: ['en', 'es'],
329 labels: const SelfLabels(values: [SelfLabel(val: 'nsfw')]),
330 );
331
332 final json = request.toJson();
333
334 expect(json['community'], 'did:plc:community1');
335 expect(json['title'], 'Test Post');
336 expect(json['content'], 'Post content here');
337 expect(json['embed'], isA<Map>());
338 expect(json['langs'], ['en', 'es']);
339 expect(json['labels'], isA<Map>());
340 });
341
342 test('should serialize minimal request with only required fields', () {
343 final request = CreatePostRequest(
344 community: 'did:plc:community1',
345 );
346
347 final json = request.toJson();
348
349 expect(json['community'], 'did:plc:community1');
350 expect(json.containsKey('title'), false);
351 expect(json.containsKey('content'), false);
352 expect(json.containsKey('embed'), false);
353 expect(json.containsKey('langs'), false);
354 expect(json.containsKey('labels'), false);
355 });
356
357 test('should not include empty langs array', () {
358 final request = CreatePostRequest(
359 community: 'did:plc:community1',
360 langs: [],
361 );
362
363 final json = request.toJson();
364
365 expect(json.containsKey('langs'), false);
366 });
367 });
368}