Skip to content

Commit 7e798bb

Browse files
chrisbobbegnprice
authored andcommitted
api: Add add-reaction and remove-reaction routes
1 parent 8aedecc commit 7e798bb

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

lib/api/route/messages.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,31 @@ class UploadFileResult {
263263

264264
Map<String, dynamic> toJson() => _$UploadFileResultToJson(this);
265265
}
266+
267+
/// https://zulip.com/api/add-reaction
268+
Future<void> addReaction(ApiConnection connection, {
269+
required int messageId,
270+
required ReactionType reactionType,
271+
required String emojiCode,
272+
required String emojiName,
273+
}) {
274+
return connection.post('addReaction', (_) {}, 'messages/$messageId/reactions', {
275+
'emoji_name': RawParameter(emojiName),
276+
'emoji_code': RawParameter(emojiCode),
277+
'reaction_type': RawParameter(reactionType.toJson()),
278+
});
279+
}
280+
281+
/// https://zulip.com/api/remove-reaction
282+
Future<void> removeReaction(ApiConnection connection, {
283+
required int messageId,
284+
required ReactionType reactionType,
285+
required String emojiCode,
286+
required String emojiName,
287+
}) {
288+
return connection.delete('removeReaction', (_) {}, 'messages/$messageId/reactions', {
289+
'emoji_name': RawParameter(emojiName),
290+
'emoji_code': RawParameter(emojiCode),
291+
'reaction_type': RawParameter(reactionType.toJson()),
292+
});
293+
}

test/api/route/messages_test.dart

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,106 @@ void main() {
334334
});
335335
});
336336
});
337+
338+
group('addReaction', () {
339+
Future<void> checkAddReaction(FakeApiConnection connection, {
340+
required int messageId,
341+
required Reaction reaction,
342+
required String expectedReactionType,
343+
}) async {
344+
connection.prepare(json: {});
345+
await addReaction(connection,
346+
messageId: messageId,
347+
reactionType: reaction.reactionType,
348+
emojiCode: reaction.emojiCode,
349+
emojiName: reaction.emojiName,
350+
);
351+
check(connection.lastRequest).isNotNull().isA<http.Request>()
352+
..method.equals('POST')
353+
..url.path.equals('/api/v1/messages/$messageId/reactions')
354+
..bodyFields.deepEquals({
355+
'reaction_type': expectedReactionType,
356+
'emoji_code': reaction.emojiCode,
357+
'emoji_name': reaction.emojiName,
358+
});
359+
}
360+
361+
test('unicode emoji', () {
362+
return FakeApiConnection.with_((connection) async {
363+
await checkAddReaction(connection,
364+
messageId: eg.streamMessage().id,
365+
reaction: eg.unicodeEmojiReaction,
366+
expectedReactionType: 'unicode_emoji');
367+
});
368+
});
369+
370+
test('realm emoji', () {
371+
return FakeApiConnection.with_((connection) async {
372+
await checkAddReaction(connection,
373+
messageId: eg.streamMessage().id,
374+
reaction: eg.realmEmojiReaction,
375+
expectedReactionType: 'realm_emoji');
376+
});
377+
});
378+
379+
test('Zulip extra emoji', () {
380+
return FakeApiConnection.with_((connection) async {
381+
await checkAddReaction(connection,
382+
messageId: eg.streamMessage().id,
383+
reaction: eg.zulipExtraEmojiReaction,
384+
expectedReactionType: 'zulip_extra_emoji');
385+
});
386+
});
387+
});
388+
389+
group('removeReaction', () {
390+
Future<void> checkRemoveReaction(FakeApiConnection connection, {
391+
required int messageId,
392+
required Reaction reaction,
393+
required String expectedReactionType,
394+
}) async {
395+
connection.prepare(json: {});
396+
await removeReaction(connection,
397+
messageId: messageId,
398+
reactionType: reaction.reactionType,
399+
emojiCode: reaction.emojiCode,
400+
emojiName: reaction.emojiName,
401+
);
402+
check(connection.lastRequest).isNotNull().isA<http.Request>()
403+
..method.equals('DELETE')
404+
..url.path.equals('/api/v1/messages/$messageId/reactions')
405+
..bodyFields.deepEquals({
406+
'reaction_type': expectedReactionType,
407+
'emoji_code': reaction.emojiCode,
408+
'emoji_name': reaction.emojiName,
409+
});
410+
}
411+
412+
test('unicode emoji', () {
413+
return FakeApiConnection.with_((connection) async {
414+
await checkRemoveReaction(connection,
415+
messageId: eg.streamMessage().id,
416+
reaction: eg.unicodeEmojiReaction,
417+
expectedReactionType: 'unicode_emoji');
418+
});
419+
});
420+
421+
test('realm emoji', () {
422+
return FakeApiConnection.with_((connection) async {
423+
await checkRemoveReaction(connection,
424+
messageId: eg.streamMessage().id,
425+
reaction: eg.realmEmojiReaction,
426+
expectedReactionType: 'realm_emoji');
427+
});
428+
});
429+
430+
test('Zulip extra emoji', () {
431+
return FakeApiConnection.with_((connection) async {
432+
await checkRemoveReaction(connection,
433+
messageId: eg.streamMessage().id,
434+
reaction: eg.zulipExtraEmojiReaction,
435+
expectedReactionType: 'zulip_extra_emoji');
436+
});
437+
});
438+
});
337439
}

test/example_data.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,20 @@ Reaction unicodeEmojiReaction = Reaction(
197197
userId: selfUser.userId,
198198
);
199199

200+
Reaction realmEmojiReaction = Reaction(
201+
emojiName: 'twocents',
202+
emojiCode: '181',
203+
reactionType: ReactionType.realmEmoji,
204+
userId: selfUser.userId,
205+
);
206+
207+
Reaction zulipExtraEmojiReaction = Reaction(
208+
emojiName: 'zulip',
209+
emojiCode: 'zulip',
210+
reactionType: ReactionType.zulipExtraEmoji,
211+
userId: selfUser.userId,
212+
);
213+
200214
// TODO example data for many more types
201215

202216
InitialSnapshot initialSnapshot({

0 commit comments

Comments
 (0)