2021-12-08 19:52:46 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import { assert } from 'chai';
|
2023-08-10 16:43:33 +00:00
|
|
|
import { v4 as generateUuid } from 'uuid';
|
2021-12-08 19:52:46 +00:00
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
import { DataReader, DataWriter } from '../../sql/Client';
|
2023-08-10 16:43:33 +00:00
|
|
|
import { generateAci } from '../../types/ServiceId';
|
2021-12-08 19:52:46 +00:00
|
|
|
|
|
|
|
import type { MessageAttributesType } from '../../model-types.d';
|
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
const { _getAllMessages, getAllStories } = DataReader;
|
|
|
|
const { removeAll, saveMessages } = DataWriter;
|
2021-12-08 19:52:46 +00:00
|
|
|
|
|
|
|
describe('sql/stories', () => {
|
|
|
|
beforeEach(async () => {
|
|
|
|
await removeAll();
|
|
|
|
});
|
|
|
|
|
2022-10-22 06:26:16 +00:00
|
|
|
describe('getAllStories', () => {
|
2021-12-08 19:52:46 +00:00
|
|
|
it('returns N most recent stories overall, or in converation, or by author', async () => {
|
2021-12-10 22:51:54 +00:00
|
|
|
assert.lengthOf(await _getAllMessages(), 0);
|
2021-12-08 19:52:46 +00:00
|
|
|
|
|
|
|
const now = Date.now();
|
2023-08-10 16:43:33 +00:00
|
|
|
const conversationId = generateUuid();
|
2023-08-16 20:54:39 +00:00
|
|
|
const sourceServiceId = generateAci();
|
2023-08-10 16:43:33 +00:00
|
|
|
const ourAci = generateAci();
|
2021-12-08 19:52:46 +00:00
|
|
|
|
|
|
|
const story1: MessageAttributesType = {
|
2023-08-10 16:43:33 +00:00
|
|
|
id: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
body: 'story 1',
|
|
|
|
type: 'story',
|
|
|
|
conversationId,
|
|
|
|
sent_at: now - 20,
|
|
|
|
received_at: now - 20,
|
|
|
|
timestamp: now - 20,
|
2023-08-16 20:54:39 +00:00
|
|
|
sourceServiceId: generateAci(),
|
2021-12-08 19:52:46 +00:00
|
|
|
};
|
|
|
|
const story2: MessageAttributesType = {
|
2023-08-10 16:43:33 +00:00
|
|
|
id: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
body: 'story 2',
|
|
|
|
type: 'story',
|
2023-08-10 16:43:33 +00:00
|
|
|
conversationId: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
sent_at: now - 10,
|
|
|
|
received_at: now - 10,
|
|
|
|
timestamp: now - 10,
|
2023-08-16 20:54:39 +00:00
|
|
|
sourceServiceId,
|
2021-12-08 19:52:46 +00:00
|
|
|
};
|
|
|
|
const story3: MessageAttributesType = {
|
2023-08-10 16:43:33 +00:00
|
|
|
id: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
body: 'message 3',
|
|
|
|
type: 'incoming',
|
2023-08-10 16:43:33 +00:00
|
|
|
conversationId: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
2023-08-16 20:54:39 +00:00
|
|
|
sourceServiceId,
|
2021-12-08 19:52:46 +00:00
|
|
|
};
|
|
|
|
const story4: MessageAttributesType = {
|
2023-08-10 16:43:33 +00:00
|
|
|
id: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
body: 'story 4',
|
|
|
|
type: 'story',
|
|
|
|
conversationId,
|
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
2023-08-16 20:54:39 +00:00
|
|
|
sourceServiceId: generateAci(),
|
2021-12-08 19:52:46 +00:00
|
|
|
};
|
|
|
|
const story5: MessageAttributesType = {
|
2023-08-10 16:43:33 +00:00
|
|
|
id: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
body: 'story 5',
|
|
|
|
type: 'story',
|
2023-08-10 16:43:33 +00:00
|
|
|
conversationId: generateUuid(),
|
2021-12-08 19:52:46 +00:00
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
2023-08-16 20:54:39 +00:00
|
|
|
sourceServiceId,
|
2021-12-08 19:52:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
await saveMessages([story1, story2, story3, story4, story5], {
|
|
|
|
forceSave: true,
|
2023-08-10 16:43:33 +00:00
|
|
|
ourAci,
|
2021-12-08 19:52:46 +00:00
|
|
|
});
|
|
|
|
|
2021-12-10 22:51:54 +00:00
|
|
|
assert.lengthOf(await _getAllMessages(), 5);
|
2021-12-08 19:52:46 +00:00
|
|
|
|
2022-10-22 06:26:16 +00:00
|
|
|
const stories = await getAllStories({});
|
2021-12-08 19:52:46 +00:00
|
|
|
assert.lengthOf(stories, 4, 'expect four total stories');
|
|
|
|
|
2022-03-29 01:10:08 +00:00
|
|
|
// They are in ASC order
|
2021-12-08 19:52:46 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
stories[0].id,
|
2022-03-29 01:10:08 +00:00
|
|
|
story1.id,
|
2021-12-08 19:52:46 +00:00
|
|
|
'stories first should be story5'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
stories[3].id,
|
2022-03-29 01:10:08 +00:00
|
|
|
story5.id,
|
2021-12-08 19:52:46 +00:00
|
|
|
'stories last should be story1'
|
|
|
|
);
|
|
|
|
|
2022-10-22 06:26:16 +00:00
|
|
|
const storiesInConversation = await getAllStories({
|
2021-12-08 19:52:46 +00:00
|
|
|
conversationId,
|
|
|
|
});
|
|
|
|
assert.lengthOf(
|
|
|
|
storiesInConversation,
|
|
|
|
2,
|
|
|
|
'expect two stories in conversaton'
|
|
|
|
);
|
|
|
|
|
2022-03-29 01:10:08 +00:00
|
|
|
// They are in ASC order
|
2021-12-08 19:52:46 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
storiesInConversation[0].id,
|
2022-03-29 01:10:08 +00:00
|
|
|
story1.id,
|
2021-12-08 19:52:46 +00:00
|
|
|
'storiesInConversation first should be story4'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
storiesInConversation[1].id,
|
2022-03-29 01:10:08 +00:00
|
|
|
story4.id,
|
2021-12-08 19:52:46 +00:00
|
|
|
'storiesInConversation last should be story1'
|
|
|
|
);
|
|
|
|
|
2022-10-22 06:26:16 +00:00
|
|
|
const storiesByAuthor = await getAllStories({
|
2023-08-16 20:54:39 +00:00
|
|
|
sourceServiceId,
|
2021-12-08 19:52:46 +00:00
|
|
|
});
|
|
|
|
assert.lengthOf(storiesByAuthor, 2, 'expect two stories by author');
|
|
|
|
|
2022-03-29 01:10:08 +00:00
|
|
|
// They are in ASC order
|
2021-12-08 19:52:46 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
storiesByAuthor[0].id,
|
2022-03-29 01:10:08 +00:00
|
|
|
story2.id,
|
2021-12-08 19:52:46 +00:00
|
|
|
'storiesByAuthor first should be story5'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
storiesByAuthor[1].id,
|
2022-03-29 01:10:08 +00:00
|
|
|
story5.id,
|
2021-12-08 19:52:46 +00:00
|
|
|
'storiesByAuthor last should be story2'
|
|
|
|
);
|
|
|
|
});
|
2024-07-30 18:29:35 +00:00
|
|
|
|
|
|
|
it('populates hasReplies and hasRepliesFromSelf', async () => {
|
|
|
|
assert.lengthOf(await _getAllMessages(), 0);
|
|
|
|
|
|
|
|
const now = Date.now();
|
|
|
|
const conversationId = generateUuid();
|
|
|
|
const sourceServiceId = generateAci();
|
|
|
|
const ourAci = generateAci();
|
|
|
|
const storyId1 = generateUuid();
|
|
|
|
const storyId2 = generateUuid();
|
|
|
|
|
|
|
|
const story1: MessageAttributesType = {
|
|
|
|
id: storyId1,
|
|
|
|
body: 'story 1',
|
|
|
|
type: 'story',
|
|
|
|
conversationId,
|
|
|
|
sent_at: now - 20,
|
|
|
|
received_at: now - 20,
|
|
|
|
timestamp: now - 20,
|
|
|
|
sourceServiceId: generateAci(),
|
|
|
|
};
|
|
|
|
const story2: MessageAttributesType = {
|
|
|
|
id: storyId2,
|
|
|
|
body: 'story 2',
|
|
|
|
type: 'story',
|
|
|
|
conversationId: generateUuid(),
|
|
|
|
sent_at: now - 10,
|
|
|
|
received_at: now - 10,
|
|
|
|
timestamp: now - 10,
|
|
|
|
sourceServiceId,
|
|
|
|
};
|
|
|
|
const story3: MessageAttributesType = {
|
|
|
|
id: generateUuid(),
|
|
|
|
body: 'story 3',
|
|
|
|
type: 'story',
|
|
|
|
conversationId: generateUuid(),
|
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
|
|
|
sourceServiceId,
|
|
|
|
};
|
|
|
|
const replyTo1: MessageAttributesType = {
|
|
|
|
id: generateUuid(),
|
|
|
|
body: 'message 3',
|
|
|
|
type: 'incoming',
|
|
|
|
storyId: storyId1,
|
|
|
|
conversationId: generateUuid(),
|
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
|
|
|
sourceServiceId,
|
|
|
|
};
|
|
|
|
const replyFromSelfTo1: MessageAttributesType = {
|
|
|
|
id: generateUuid(),
|
|
|
|
body: 'story 4',
|
|
|
|
type: 'outgoing',
|
|
|
|
storyId: storyId1,
|
|
|
|
conversationId,
|
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
|
|
|
sourceServiceId: generateAci(),
|
|
|
|
};
|
|
|
|
const replyTo2: MessageAttributesType = {
|
|
|
|
id: generateUuid(),
|
|
|
|
body: 'story 5',
|
|
|
|
type: 'incoming',
|
|
|
|
storyId: storyId2,
|
|
|
|
conversationId: generateUuid(),
|
|
|
|
sent_at: now,
|
|
|
|
received_at: now,
|
|
|
|
timestamp: now,
|
|
|
|
sourceServiceId,
|
|
|
|
};
|
|
|
|
|
|
|
|
await saveMessages(
|
|
|
|
[story1, story2, story3, replyTo1, replyFromSelfTo1, replyTo2],
|
|
|
|
{
|
|
|
|
forceSave: true,
|
|
|
|
ourAci,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.lengthOf(await _getAllMessages(), 6);
|
|
|
|
|
|
|
|
const stories = await getAllStories({});
|
|
|
|
assert.lengthOf(stories, 3, 'expect three total stories');
|
|
|
|
|
|
|
|
// They are in ASC order
|
|
|
|
assert.strictEqual(
|
|
|
|
stories[0].id,
|
|
|
|
story1.id,
|
|
|
|
'stories first should be story1'
|
|
|
|
);
|
|
|
|
assert.strictEqual(
|
|
|
|
stories[2].id,
|
|
|
|
story3.id,
|
|
|
|
'stories last should be story3'
|
|
|
|
);
|
|
|
|
|
|
|
|
assert.strictEqual(stories[0].hasReplies, true);
|
|
|
|
assert.strictEqual(stories[0].hasRepliesFromSelf, true);
|
|
|
|
|
|
|
|
assert.strictEqual(stories[1].hasReplies, true);
|
|
|
|
assert.strictEqual(stories[1].hasRepliesFromSelf, false);
|
|
|
|
|
|
|
|
assert.strictEqual(stories[2].hasReplies, false);
|
|
|
|
assert.strictEqual(stories[2].hasRepliesFromSelf, false);
|
|
|
|
});
|
2021-12-08 19:52:46 +00:00
|
|
|
});
|
|
|
|
});
|