signal-desktop/ts/test-node/util/countUnreadStats_test.ts

200 lines
6.6 KiB
TypeScript
Raw Normal View History

// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { assert } from 'chai';
2025-09-29 15:34:24 -07:00
import { v4 as generateUuid } from 'uuid';
import { countConversationUnreadStats } from '../../util/countUnreadStats.js';
2025-09-29 15:34:24 -07:00
import type {
UnreadStats,
ConversationPropsForUnreadStats,
} from '../../util/countUnreadStats.js';
2025-09-29 15:34:24 -07:00
function getFutureMutedTimestamp() {
return Date.now() + 12345;
}
2025-09-29 15:34:24 -07:00
function getPastMutedTimestamp() {
return Date.now() - 1000;
}
2025-09-29 15:34:24 -07:00
function mockChat(
props: Partial<ConversationPropsForUnreadStats>
): ConversationPropsForUnreadStats {
return {
id: generateUuid(),
type: 'direct',
activeAt: Date.now(),
isArchived: false,
markedUnread: false,
unreadCount: 0,
unreadMentionsCount: 0,
muteExpiresAt: undefined,
left: false,
...props,
};
}
2025-09-29 15:34:24 -07:00
function mockStats(props: Partial<UnreadStats>): UnreadStats {
return {
unreadCount: 0,
unreadMentionsCount: 0,
readChatsMarkedUnreadCount: 0,
...props,
};
}
2025-09-29 15:34:24 -07:00
describe('countUnreadStats', () => {
describe('countConversationUnreadStats', () => {
it('returns 0 if the conversation is archived', () => {
const isArchived = true;
const archivedConversations = [
mockChat({ isArchived, markedUnread: false, unreadCount: 0 }),
mockChat({ isArchived, markedUnread: false, unreadCount: 123 }),
mockChat({ isArchived, markedUnread: true, unreadCount: 0 }),
mockChat({ isArchived, markedUnread: true, unreadCount: undefined }),
mockChat({ isArchived, markedUnread: undefined, unreadCount: 0 }),
];
for (const conversation of archivedConversations) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: true }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: false }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
}
2025-09-29 15:34:24 -07:00
});
2025-09-29 15:34:24 -07:00
it("returns 0 if the conversation is muted and the user doesn't want to include those in the result", () => {
const muteExpiresAt = getFutureMutedTimestamp();
const mutedConversations = [
mockChat({ muteExpiresAt, markedUnread: false, unreadCount: 0 }),
mockChat({ muteExpiresAt, markedUnread: false, unreadCount: 9 }),
mockChat({ muteExpiresAt, markedUnread: true, unreadCount: 0 }),
mockChat({ muteExpiresAt, markedUnread: true, unreadCount: undefined }),
];
for (const conversation of mutedConversations) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: false }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
}
});
it('returns the unread count if nonzero (and not archived)', () => {
const conversationsWithUnreadCount = [
mockChat({ unreadCount: 9, markedUnread: false }),
mockChat({ unreadCount: 9, markedUnread: true }),
mockChat({ unreadCount: 9, muteExpiresAt: getPastMutedTimestamp() }),
];
for (const conversation of conversationsWithUnreadCount) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: false }),
mockStats({ unreadCount: 9 })
);
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: true }),
mockStats({ unreadCount: 9 })
);
}
const mutedWithUnreads = mockChat({
unreadCount: 123,
muteExpiresAt: getFutureMutedTimestamp(),
});
assert.deepStrictEqual(
2025-09-29 15:34:24 -07:00
countConversationUnreadStats(mutedWithUnreads, { includeMuted: true }),
mockStats({ unreadCount: 123 })
);
2025-09-29 15:34:24 -07:00
});
2025-09-29 15:34:24 -07:00
it('returns markedUnread:true if the conversation is marked unread', () => {
const conversationsMarkedUnread = [
mockChat({ markedUnread: true }),
mockChat({
markedUnread: true,
2025-09-29 15:34:24 -07:00
muteExpiresAt: getPastMutedTimestamp(),
}),
];
for (const conversation of conversationsMarkedUnread) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: false }),
mockStats({ readChatsMarkedUnreadCount: 1 })
);
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: true }),
mockStats({ readChatsMarkedUnreadCount: 1 })
);
}
2025-09-29 15:34:24 -07:00
const mutedConversationsMarkedUnread = [
mockChat({
markedUnread: true,
muteExpiresAt: getFutureMutedTimestamp(),
}),
mockChat({
markedUnread: true,
muteExpiresAt: getFutureMutedTimestamp(),
unreadCount: 0,
2025-09-29 15:34:24 -07:00
}),
];
for (const conversation of mutedConversationsMarkedUnread) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: true }),
mockStats({ readChatsMarkedUnreadCount: 1 })
);
}
});
2025-09-29 15:34:24 -07:00
it('returns 0 if the conversation is read', () => {
const readConversations = [
mockChat({ markedUnread: false, unreadCount: undefined }),
mockChat({ markedUnread: false, unreadCount: 0 }),
mockChat({
markedUnread: false,
2025-09-29 15:34:24 -07:00
muteExpiresAt: getFutureMutedTimestamp(),
}),
mockChat({
markedUnread: false,
2025-09-29 15:34:24 -07:00
muteExpiresAt: getPastMutedTimestamp(),
}),
];
for (const conversation of readConversations) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: false }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: true }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
}
});
it('returns 0 if the conversation has falsey activeAt', () => {
const readConversations = [
mockChat({ activeAt: undefined, unreadCount: 2 }),
mockChat({
activeAt: 0,
unreadCount: 2,
muteExpiresAt: getPastMutedTimestamp(),
}),
];
for (const conversation of readConversations) {
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: false }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
assert.deepStrictEqual(
countConversationUnreadStats(conversation, { includeMuted: true }),
mockStats({ unreadCount: 0, readChatsMarkedUnreadCount: 0 })
);
}
});
});
});