test(persistence): add tests for message dao
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -72,7 +72,7 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
/// [Messages.channelCid] with [cid]
|
||||
Future<List<Message>> getThreadMessages(String cid) async =>
|
||||
Future.wait(await (select(messages).join([
|
||||
leftOuterJoin(users, messages.userId.equalsExp(_users.id)),
|
||||
leftOuterJoin(_users, messages.userId.equalsExp(_users.id)),
|
||||
leftOuterJoin(_pinnedByUsers,
|
||||
messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||
])
|
||||
@@ -89,10 +89,11 @@ class MessageDao extends DatabaseAccessor<MoorChatDatabase>
|
||||
PaginationParams options,
|
||||
}) async {
|
||||
final msgList = await Future.wait(await (select(messages).join([
|
||||
innerJoin(_users, messages.userId.equalsExp(_users.id)),
|
||||
innerJoin(
|
||||
leftOuterJoin(_users, messages.userId.equalsExp(_users.id)),
|
||||
leftOuterJoin(
|
||||
_pinnedByUsers, messages.pinnedByUserId.equalsExp(_pinnedByUsers.id)),
|
||||
])
|
||||
..where(isNotNull(messages.parentId))
|
||||
..where(messages.parentId.equals(parentId))
|
||||
..orderBy([OrderingTerm.asc(messages.createdAt)]))
|
||||
.map(_messageFromJoinRow)
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:stream_chat/stream_chat.dart';
|
||||
import 'package:stream_chat_persistence/src/dao/dao.dart';
|
||||
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
MessageDao messageDao;
|
||||
MoorChatDatabase database;
|
||||
|
||||
setUp(() {
|
||||
database = MoorChatDatabase.testable('testUserId');
|
||||
messageDao = database.messageDao;
|
||||
});
|
||||
|
||||
Future<List<Message>> _prepareTestData(
|
||||
String cid, {
|
||||
bool threads = false,
|
||||
int count = 3,
|
||||
}) async {
|
||||
final messages = List.generate(
|
||||
count,
|
||||
(index) => Message(
|
||||
id: 'testMessageId$cid$index',
|
||||
type: 'testType',
|
||||
user: User(id: 'testUserId$index'),
|
||||
createdAt: DateTime.now(),
|
||||
shadowed: math.Random().nextBool(),
|
||||
showInChannel: math.Random().nextBool(),
|
||||
replyCount: index,
|
||||
updatedAt: DateTime.now(),
|
||||
extraData: {'extra_test_field': 'extraTestData'},
|
||||
text: 'Dummy text #$index',
|
||||
pinned: math.Random().nextBool(),
|
||||
pinnedAt: DateTime.now(),
|
||||
pinnedBy: User(id: 'testUserId$index'),
|
||||
),
|
||||
);
|
||||
final threadMessages = List.generate(
|
||||
count,
|
||||
(index) => Message(
|
||||
id: 'testThreadMessageId$cid$index',
|
||||
type: 'testType',
|
||||
user: User(id: 'testUserId$index'),
|
||||
parentId: messages[index].id,
|
||||
createdAt: DateTime.now(),
|
||||
shadowed: math.Random().nextBool(),
|
||||
showInChannel: math.Random().nextBool(),
|
||||
replyCount: index,
|
||||
updatedAt: DateTime.now(),
|
||||
extraData: {'extra_test_field': 'extraTestData'},
|
||||
text: 'Dummy text #$index',
|
||||
pinned: math.Random().nextBool(),
|
||||
pinnedAt: DateTime.now(),
|
||||
pinnedBy: User(id: 'testUserId$index'),
|
||||
),
|
||||
);
|
||||
final allMessages = [...messages, if (threads) ...threadMessages];
|
||||
await messageDao.updateMessages(cid, allMessages);
|
||||
return allMessages;
|
||||
}
|
||||
|
||||
test('deleteMessageByIds', () async {
|
||||
const cid = 'testCid';
|
||||
|
||||
// Preparing test data
|
||||
final insertedMessages = await _prepareTestData(cid);
|
||||
|
||||
// Fetched message list should match the test message list length
|
||||
final messages = await messageDao.getMessagesByCid(cid);
|
||||
expect(messages.length, insertedMessages.length);
|
||||
|
||||
// Deleting 2 messages from DB
|
||||
await messageDao.deleteMessageByIds(
|
||||
['testMessageId${cid}0', 'testMessageId${cid}1'],
|
||||
);
|
||||
|
||||
// New fetched messages length should 2 less than the
|
||||
// previous fetched messages
|
||||
final newMessages = await messageDao.getMessagesByCid(cid);
|
||||
expect(newMessages.length, messages.length - 2);
|
||||
});
|
||||
|
||||
group('deleteMessageByCids', () {
|
||||
const cid1 = 'testCid1';
|
||||
const cid2 = 'testCid2';
|
||||
|
||||
test('should delete all the messages of first channel', () async {
|
||||
// Preparing test data
|
||||
final cid1InsertedMessages = await _prepareTestData(cid1);
|
||||
final cid2InsertedMessages = await _prepareTestData(cid2);
|
||||
|
||||
// Fetched message list should match the test message list length
|
||||
final cid1Messages = await messageDao.getMessagesByCid(cid1);
|
||||
final cid2Messages = await messageDao.getMessagesByCid(cid2);
|
||||
expect(cid1Messages.length, cid1InsertedMessages.length);
|
||||
expect(cid2Messages.length, cid2InsertedMessages.length);
|
||||
|
||||
// Deleting all the messages of cid1
|
||||
await messageDao.deleteMessageByCids([cid1]);
|
||||
|
||||
// Fetched messages length of only cid1 should be empty
|
||||
final cid1FetchedMessages = await messageDao.getMessagesByCid(cid1);
|
||||
final cid2FetchedMessages = await messageDao.getMessagesByCid(cid2);
|
||||
expect(cid1FetchedMessages, isEmpty);
|
||||
expect(cid2FetchedMessages, isNotEmpty);
|
||||
});
|
||||
|
||||
test('should delete all the messages of both channel', () async {
|
||||
// Preparing test data
|
||||
final cid1InsertedMessages = await _prepareTestData(cid1);
|
||||
final cid2InsertedMessages = await _prepareTestData(cid2);
|
||||
|
||||
// Fetched message list should match the test message list length
|
||||
final cid1Messages = await messageDao.getMessagesByCid(cid1);
|
||||
final cid2Messages = await messageDao.getMessagesByCid(cid2);
|
||||
expect(cid1Messages.length, cid1InsertedMessages.length);
|
||||
expect(cid2Messages.length, cid2InsertedMessages.length);
|
||||
|
||||
// Deleting all the messages of cid1
|
||||
await messageDao.deleteMessageByCids([cid1, cid2]);
|
||||
|
||||
// Fetched messages length of both cid1 and cid2 should be empty
|
||||
final cid1FetchedMessages = await messageDao.getMessagesByCid(cid1);
|
||||
final cid2FetchedMessages = await messageDao.getMessagesByCid(cid2);
|
||||
expect(cid1FetchedMessages, isEmpty);
|
||||
expect(cid2FetchedMessages, isEmpty);
|
||||
});
|
||||
});
|
||||
|
||||
test('getMessageById', () async {
|
||||
const cid = 'testCid';
|
||||
const id = 'testMessageId${cid}0';
|
||||
|
||||
// Should be null initially
|
||||
final message = await messageDao.getMessageById(id);
|
||||
expect(message, isNull);
|
||||
|
||||
// Adding test message with the cid and id
|
||||
final insertedMessages = await _prepareTestData(cid, count: 1);
|
||||
expect(insertedMessages.first.id, id);
|
||||
|
||||
// Fetched message id should match the inserted message id
|
||||
final fetchedMessage = await messageDao.getMessageById(id);
|
||||
expect(fetchedMessage.id, insertedMessages.first.id);
|
||||
});
|
||||
|
||||
test('getThreadMessages', () async {
|
||||
const cid = 'testCid';
|
||||
|
||||
// Messages should be empty initially
|
||||
final messages = await messageDao.getThreadMessages(cid);
|
||||
expect(messages, isEmpty);
|
||||
|
||||
// Preparing test data
|
||||
final insertedMessages = await _prepareTestData(cid, threads: true);
|
||||
expect(insertedMessages, isNotEmpty);
|
||||
|
||||
// Should fetch all the thread messages of cid
|
||||
final threadMessages = await messageDao.getThreadMessages(cid);
|
||||
expect(threadMessages, isNotEmpty);
|
||||
for (final message in threadMessages) {
|
||||
expect(message.parentId, isNotNull);
|
||||
}
|
||||
});
|
||||
|
||||
test('getThreadMessagesByParentId', () async {
|
||||
const cid = 'testCid';
|
||||
const parentId = 'testMessageId${cid}0';
|
||||
|
||||
// Messages should be empty initially
|
||||
final messages = await messageDao.getThreadMessagesByParentId(parentId);
|
||||
expect(messages, isEmpty);
|
||||
|
||||
// Preparing test data
|
||||
final insertedMessages = await _prepareTestData(cid, threads: true);
|
||||
expect(insertedMessages, isNotEmpty);
|
||||
|
||||
// Should fetch all the thread messages of parentId
|
||||
final threadMessages =
|
||||
await messageDao.getThreadMessagesByParentId(parentId);
|
||||
expect(threadMessages.length, 1);
|
||||
expect(threadMessages.first.parentId, parentId);
|
||||
});
|
||||
|
||||
test('getMessagesByCid', () async {
|
||||
const cid = 'testCid';
|
||||
|
||||
// Should be empty initially
|
||||
final messages = await messageDao.getMessagesByCid(cid);
|
||||
expect(messages, isEmpty);
|
||||
|
||||
// Preparing test data
|
||||
final insertedMessages = await _prepareTestData(cid);
|
||||
expect(insertedMessages, isNotEmpty);
|
||||
|
||||
// Fetched message should match the inserted messages
|
||||
final fetchedMessages = await messageDao.getMessagesByCid(cid);
|
||||
expect(fetchedMessages.length, insertedMessages.length);
|
||||
for (var i = 0; i < fetchedMessages.length; i++) {
|
||||
final fetchedMessage = fetchedMessages[i];
|
||||
final insertedMessage = insertedMessages[i];
|
||||
expect(fetchedMessage.id, insertedMessage.id);
|
||||
}
|
||||
});
|
||||
|
||||
test('updateMessages', () async {
|
||||
const cid = 'testCid';
|
||||
|
||||
// Preparing test data
|
||||
final insertedMessages = await _prepareTestData(cid);
|
||||
expect(insertedMessages, isNotEmpty);
|
||||
|
||||
// Modifying one of the message and also adding one new
|
||||
final copyMessage = insertedMessages.first.copyWith(showInChannel: false);
|
||||
final newMessage = Message(
|
||||
id: 'testMessageId${cid}4',
|
||||
type: 'testType',
|
||||
user: User(id: 'testUserId4'),
|
||||
createdAt: DateTime.now(),
|
||||
shadowed: math.Random().nextBool(),
|
||||
showInChannel: math.Random().nextBool(),
|
||||
replyCount: 4,
|
||||
updatedAt: DateTime.now(),
|
||||
extraData: {'extra_test_field': 'extraTestData'},
|
||||
text: 'Dummy text #4',
|
||||
pinned: math.Random().nextBool(),
|
||||
pinnedAt: DateTime.now(),
|
||||
pinnedBy: User(id: 'testUserId4'),
|
||||
);
|
||||
|
||||
await messageDao.updateMessages(cid, [copyMessage, newMessage]);
|
||||
|
||||
// Fetched messages length should be one more than inserted message.
|
||||
// copyMessage `showInChannel` modified field should be false.
|
||||
// Fetched messages should contain the newMessage.
|
||||
final fetchedMessages = await messageDao.getMessagesByCid(cid);
|
||||
expect(fetchedMessages.length, insertedMessages.length + 1);
|
||||
expect(
|
||||
fetchedMessages.firstWhere((it) => it.id == copyMessage.id).showInChannel,
|
||||
false,
|
||||
);
|
||||
expect(
|
||||
fetchedMessages.map((it) => it.id).contains('testMessageId${cid}4'),
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await database.disconnect();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user