Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3358203
D12851.id42702.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D12851.id42702.diff
View Options
diff --git a/web/shared-worker/queries/message-search.test.js b/web/shared-worker/queries/message-search.test.js
new file mode 100644
--- /dev/null
+++ b/web/shared-worker/queries/message-search.test.js
@@ -0,0 +1,323 @@
+// @flow
+
+import { messageTypes } from 'lib/types/message-types-enum.js';
+
+import { getDatabaseModule } from '../db-module.js';
+import { type WebMessage } from '../types/sqlite-query-executor.js';
+import { clearSensitiveData } from '../utils/db-utils.js';
+
+const FILE_PATH = 'test.sqlite';
+
+describe('Message search queries', () => {
+ let queryExecutor;
+ let dbModule;
+ const threadID = '100';
+ const userID = '111';
+ const futureType = { value: 0, isNull: true };
+ const localID = { value: '', isNull: true };
+
+ beforeAll(async () => {
+ dbModule = getDatabaseModule();
+ });
+
+ beforeEach(() => {
+ if (!dbModule) {
+ throw new Error('Database module is missing');
+ }
+ queryExecutor = new dbModule.SQLiteQueryExecutor(FILE_PATH);
+ if (!queryExecutor) {
+ throw new Error('SQLiteQueryExecutor is missing');
+ }
+ });
+
+ afterEach(() => {
+ clearSensitiveData(dbModule, FILE_PATH, queryExecutor);
+ });
+
+ it('should find messages matching provided query', () => {
+ const text = 'test text';
+ const id = '1';
+ const message: WebMessage = {
+ id,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: '123',
+ };
+ queryExecutor.replaceMessageWeb(message);
+ queryExecutor.updateMessageSearchIndex(id, id, text);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(message);
+ });
+
+ it('should find all messages matching provided query', () => {
+ const text1 = 'test text';
+ const id1 = '1';
+ queryExecutor.replaceMessageWeb({
+ id: id1,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text1, isNull: false },
+ time: '1',
+ });
+ queryExecutor.updateMessageSearchIndex(id1, id1, text1);
+
+ const text2 = 'I am test';
+ const id2 = '2';
+ queryExecutor.replaceMessageWeb({
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text2, isNull: false },
+ time: '1',
+ });
+ queryExecutor.updateMessageSearchIndex(id2, id2, text2);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+ expect(result.length).toBe(2);
+ });
+
+ it('should ignore messages not matching provided query', () => {
+ const text1 = 'test text';
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text1, isNull: false },
+ time: '123',
+ };
+ queryExecutor.replaceMessageWeb(matchingMessage);
+ queryExecutor.updateMessageSearchIndex(id1, id1, text1);
+
+ const text2 = 'I am text';
+ const id2 = '2';
+ queryExecutor.replaceMessageWeb({
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text2, isNull: false },
+ time: '1',
+ });
+ queryExecutor.updateMessageSearchIndex(id2, id2, text2);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it('should match message edits', () => {
+ const text1 = 'I am text';
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text1, isNull: false },
+ time: '1',
+ };
+ queryExecutor.replaceMessageWeb(matchingMessage);
+ queryExecutor.updateMessageSearchIndex(id1, id1, text1);
+
+ const text2 = 'I am test';
+ const id2 = '2';
+ queryExecutor.replaceMessageWeb({
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.EDIT_MESSAGE,
+ futureType,
+ content: {
+ value: JSON.stringify({ targetMessageID: id1 }),
+ isNull: false,
+ },
+ time: '5',
+ });
+ queryExecutor.updateMessageSearchIndex(id1, id2, text2);
+ const result = queryExecutor.searchMessages('test', threadID, null, null);
+
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it('should return only messages with time equal or smaller than timestampCursor', () => {
+ const timeOlderThanSearchedFor = '1';
+ const timeSearchedFor = '1000';
+ const timeNewerThanSearchedFor = '2000';
+
+ const text = 'test';
+
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: timeOlderThanSearchedFor,
+ };
+ queryExecutor.replaceMessageWeb(matchingMessage);
+ queryExecutor.updateMessageSearchIndex(id1, id1, text);
+
+ const id2 = '2';
+ queryExecutor.replaceMessageWeb({
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: timeNewerThanSearchedFor,
+ });
+ queryExecutor.updateMessageSearchIndex(id2, id2, text);
+ const result = queryExecutor.searchMessages(
+ text,
+ threadID,
+ timeSearchedFor,
+ '0',
+ );
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it('should correctly return messages with regards to messageIDCursor', () => {
+ const text = 'test';
+ const time = '1';
+
+ const id1 = '1';
+ const matchingMessage: WebMessage = {
+ id: id1,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time,
+ };
+ queryExecutor.replaceMessageWeb(matchingMessage);
+ queryExecutor.updateMessageSearchIndex(id1, id1, text);
+
+ const id2 = '2';
+ queryExecutor.replaceMessageWeb({
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time,
+ });
+ queryExecutor.updateMessageSearchIndex(id2, id2, text);
+
+ const result = queryExecutor.searchMessages(text, threadID, time, id2);
+ expect(result.length).toBe(1);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it('should prioritize timestampCursor over messageIDCursor', () => {
+ const text = 'text';
+
+ const greaterID = '600';
+ const smallerID = '2';
+ const intBetweenIDs = '100';
+
+ const olderTimestamp = '1';
+ const youngerTimestamp = '1000';
+ const timeBetweenTimestamps = '500';
+
+ const matchingMessage: WebMessage = {
+ id: greaterID,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: olderTimestamp,
+ };
+ queryExecutor.replaceMessageWeb(matchingMessage);
+ queryExecutor.updateMessageSearchIndex(greaterID, greaterID, text);
+
+ queryExecutor.replaceMessageWeb({
+ id: smallerID,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: youngerTimestamp,
+ });
+ queryExecutor.updateMessageSearchIndex(smallerID, smallerID, text);
+ const result = queryExecutor.searchMessages(
+ text,
+ threadID,
+ timeBetweenTimestamps,
+ intBetweenIDs,
+ );
+
+ expect(result.length).toBe(1);
+ expect(result[0].message.id).toBe(greaterID);
+ expect(result[0].message).toStrictEqual(matchingMessage);
+ });
+
+ it('should return messages in correct order', () => {
+ const text = 'test';
+
+ const id1 = '1';
+ const secondMessage: WebMessage = {
+ id: id1,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: '1',
+ };
+ queryExecutor.replaceMessageWeb(secondMessage);
+ queryExecutor.updateMessageSearchIndex(id1, id1, text);
+
+ const id2 = '2';
+ const firstMessage: WebMessage = {
+ id: id2,
+ localID,
+ thread: threadID,
+ user: userID,
+ type: messageTypes.TEXT,
+ futureType,
+ content: { value: text, isNull: false },
+ time: '2',
+ };
+ queryExecutor.replaceMessageWeb(firstMessage);
+ queryExecutor.updateMessageSearchIndex(id2, id2, text);
+
+ const result = queryExecutor.searchMessages(text, threadID, null, null);
+ expect(result.length).toBe(2);
+ expect(result[0].message).toStrictEqual(firstMessage);
+ expect(result[1].message).toStrictEqual(secondMessage);
+ });
+});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 25, 3:38 AM (21 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2574103
Default Alt Text
D12851.id42702.diff (9 KB)
Attached To
Mode
D12851: [SQLite] implement tests for messages search
Attached
Detach File
Event Timeline
Log In to Comment