diff --git a/web/shared-worker/queries/messages-and-media-queries.test.js b/web/shared-worker/queries/messages-and-media-queries.test.js index e837b0aa7..170085746 100644 --- a/web/shared-worker/queries/messages-and-media-queries.test.js +++ b/web/shared-worker/queries/messages-and-media-queries.test.js @@ -1,182 +1,182 @@ // @flow import { getDatabaseModule } from '../db-module.js'; import { clearSensitiveData } from '../utils/db-utils.js'; const FILE_PATH = 'test.sqlite'; describe('Message and media store queries', () => { let queryExecutor; let dbModule; 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'); } queryExecutor.replaceMessageWeb({ id: '1', localID: { value: '', isNull: true }, thread: '1', user: '1', type: 0, futureType: { value: 0, isNull: true }, content: { value: '', isNull: true }, time: '0', }); queryExecutor.replaceMessageWeb({ id: '2', localID: { value: '', isNull: true }, thread: '1', user: '1', type: 0, futureType: { value: 0, isNull: true }, content: { value: '', isNull: true }, time: '0', }); queryExecutor.replaceMessageWeb({ id: '3', localID: { value: '', isNull: true }, thread: '2', user: '1', type: 0, futureType: { value: 5, isNull: false }, content: { value: '', isNull: true }, time: '0', }); queryExecutor.replaceMedia({ id: '1', container: '1', thread: '1', uri: '1', - type: '1', + type: 'photo', extras: '1', }); queryExecutor.replaceMedia({ id: '2', container: '1', thread: '1', uri: '1', - type: '1', + type: 'photo', extras: '1', }); queryExecutor.replaceMedia({ id: '3', container: '3', thread: '2', uri: '1', - type: '1', + type: 'photo', extras: '1', }); queryExecutor.replaceMedia({ id: '4', container: '3', thread: '2', uri: '1', - type: '1', + type: 'photo', extras: '1', }); }); afterEach(() => { clearSensitiveData(dbModule, FILE_PATH, queryExecutor); }); it('should return all messages with media', () => { const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages.length).toBe(3); expect(allMessages[0].medias.length).toBe(2); expect(allMessages[1].medias.length).toBe(0); expect(allMessages[2].medias.length).toBe(2); }); it('should remove all messages', () => { queryExecutor.removeAllMessages(); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages.length).toBe(0); }); it('should remove all media', () => { queryExecutor.removeAllMedia(); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages[0].medias.length).toBe(0); expect(allMessages[1].medias.length).toBe(0); expect(allMessages[2].medias.length).toBe(0); }); it('should remove all messages for threads', () => { queryExecutor.removeMessagesForThreads(['1']); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages.length).toBe(1); }); it('should remove all messages with ids', () => { queryExecutor.removeMessages(['1']); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages.length).toBe(2); }); it('should remove all media for message', () => { queryExecutor.removeMediaForMessage('1'); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages[0].medias.length).toBe(0); expect(allMessages[1].medias.length).toBe(0); expect(allMessages[2].medias.length).toBe(2); }); it('should remove all media for messages', () => { queryExecutor.removeMediaForMessages(['3']); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages[0].medias.length).toBe(2); expect(allMessages[1].medias.length).toBe(0); expect(allMessages[2].medias.length).toBe(0); }); it('should remove all media for threads', () => { queryExecutor.removeMediaForThreads(['2']); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages[0].medias.length).toBe(2); expect(allMessages[1].medias.length).toBe(0); expect(allMessages[2].medias.length).toBe(0); }); it('should rekey media containers', () => { queryExecutor.rekeyMediaContainers('1', '3'); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages[0].medias.length).toBe(0); expect(allMessages[1].medias.length).toBe(0); expect(allMessages[2].medias.length).toBe(4); }); it('should rekey message', () => { queryExecutor.rekeyMessage('3', '2'); const allMessages = queryExecutor.getAllMessagesWeb(); expect(allMessages.length).toBe(2); const rekeyedMessage = allMessages.find( messageWithMedia => messageWithMedia.message.id === '2', ); expect(rekeyedMessage?.message.thread).toBe('2'); }); it('should correctly handle nullable integer', () => { const allMessages = queryExecutor.getAllMessagesWeb(); const messageWithNullFutureType = allMessages.find( messageWithMedia => messageWithMedia.message.id === '1', ); const messageWithNonNullIFutureType = allMessages.find( messageWithMedia => messageWithMedia.message.id === '3', ); expect(messageWithNullFutureType?.message.futureType.isNull).toBe(true); expect(messageWithNonNullIFutureType?.message.futureType.isNull).toBe( false, ); expect(messageWithNonNullIFutureType?.message.futureType.value).toBe(5); }); }); diff --git a/web/shared-worker/types/sqlite-query-executor.js b/web/shared-worker/types/sqlite-query-executor.js index 9549147fb..4611a9d8c 100644 --- a/web/shared-worker/types/sqlite-query-executor.js +++ b/web/shared-worker/types/sqlite-query-executor.js @@ -1,170 +1,170 @@ // @flow import type { ClientDBAuxUserInfo } from 'lib/ops/aux-user-store-ops.js'; import type { ClientDBCommunityInfo } from 'lib/ops/community-store-ops.js'; import type { ClientDBIntegrityThreadHash } from 'lib/ops/integrity-store-ops.js'; import type { ClientDBKeyserverInfo } from 'lib/ops/keyserver-store-ops.js'; import type { ClientDBReport } from 'lib/ops/report-store-ops.js'; import type { ClientDBSyncedMetadataEntry } from 'lib/ops/synced-metadata-store-ops.js'; import type { ClientDBUserInfo } from 'lib/ops/user-store-ops.js'; import type { ClientDBDraftInfo } from 'lib/types/draft-types.js'; import { type WebClientDBThreadInfo, type NullableString, type NullableInt, } from './entities.js'; type WebMessage = { +id: string, +localID: NullableString, +thread: string, +user: string, +type: number, +futureType: NullableInt, +content: NullableString, +time: string, }; type Media = { +id: string, +container: string, +thread: string, +uri: string, - +type: string, + +type: 'photo' | 'video', +extras: string, }; export type OlmPersistSession = { +targetUserID: string, +sessionData: string, }; export type ClientMessageToDevice = { +messageID: string, +deviceID: string, +userID: string, +timestamp: string, +plaintext: string, +ciphertext: string, }; declare export class SQLiteQueryExecutor { constructor(sqliteFilePath: string): void; updateDraft(key: string, text: string): void; moveDraft(oldKey: string, newKey: string): boolean; getAllDrafts(): ClientDBDraftInfo[]; removeAllDrafts(): void; removeDrafts(ids: $ReadOnlyArray): void; getAllMessagesWeb(): $ReadOnlyArray<{ +message: WebMessage, +medias: $ReadOnlyArray, }>; removeAllMessages(): void; removeMessages(ids: $ReadOnlyArray): void; removeMessagesForThreads(threadIDs: $ReadOnlyArray): void; replaceMessageWeb(message: WebMessage): void; rekeyMessage(from: string, to: string): void; removeAllMedia(): void; removeMediaForThreads(threadIDs: $ReadOnlyArray): void; removeMediaForMessages(msgIDs: $ReadOnlyArray): void; removeMediaForMessage(msgID: string): void; replaceMedia(media: Media): void; rekeyMediaContainers(from: string, to: string): void; replaceMessageStoreThreads( threads: $ReadOnlyArray<{ +id: string, +startReached: number }>, ): void; removeMessageStoreThreads($ReadOnlyArray): void; getAllMessageStoreThreads(): $ReadOnlyArray<{ +id: string, +startReached: number, }>; removeAllMessageStoreThreads(): void; setMetadata(entryName: string, data: string): void; clearMetadata(entryName: string): void; getMetadata(entryName: string): string; replaceReport(report: ClientDBReport): void; removeReports(ids: $ReadOnlyArray): void; removeAllReports(): void; getAllReports(): ClientDBReport[]; setPersistStorageItem(key: string, item: string): void; removePersistStorageItem(key: string): void; getPersistStorageItem(key: string): string; replaceUser(userInfo: ClientDBUserInfo): void; removeUsers(ids: $ReadOnlyArray): void; removeAllUsers(): void; getAllUsers(): ClientDBUserInfo[]; replaceThreadWeb(thread: WebClientDBThreadInfo): void; removeThreads(ids: $ReadOnlyArray): void; removeAllThreads(): void; getAllThreadsWeb(): WebClientDBThreadInfo[]; replaceKeyserver(keyserverInfo: ClientDBKeyserverInfo): void; removeKeyservers(ids: $ReadOnlyArray): void; removeAllKeyservers(): void; getAllKeyservers(): ClientDBKeyserverInfo[]; replaceCommunity(communityInfo: ClientDBCommunityInfo): void; removeCommunities(ids: $ReadOnlyArray): void; removeAllCommunities(): void; getAllCommunities(): ClientDBCommunityInfo[]; replaceIntegrityThreadHashes( threadHashes: $ReadOnlyArray, ): void; removeIntegrityThreadHashes(ids: $ReadOnlyArray): void; removeAllIntegrityThreadHashes(): void; getAllIntegrityThreadHashes(): ClientDBIntegrityThreadHash[]; replaceSyncedMetadataEntry( syncedMetadataEntry: ClientDBSyncedMetadataEntry, ): void; removeSyncedMetadata(names: $ReadOnlyArray): void; removeAllSyncedMetadata(): void; getAllSyncedMetadata(): ClientDBSyncedMetadataEntry[]; replaceAuxUserInfo(auxUserInfo: ClientDBAuxUserInfo): void; removeAuxUserInfos(ids: $ReadOnlyArray): void; removeAllAuxUserInfos(): void; getAllAuxUserInfos(): ClientDBAuxUserInfo[]; beginTransaction(): void; commitTransaction(): void; rollbackTransaction(): void; getContentAccountID(): number; getNotifsAccountID(): number; getOlmPersistAccountDataWeb(accountID: number): NullableString; getOlmPersistSessionsData(): $ReadOnlyArray; storeOlmPersistAccount(accountID: number, accountData: string): void; storeOlmPersistSession(session: OlmPersistSession): void; restoreFromMainCompaction( mainCompactionPath: string, mainCompactionEncryptionKey: string, ): void; restoreFromBackupLog(backupLog: Uint8Array): void; addMessagesToDevice(messages: $ReadOnlyArray): void; removeMessagesToDeviceOlderThan( lastConfirmedMessage: ClientMessageToDevice, ): void; removeAllMessagesForDevice(deviceID: string): void; getAllMessagesToDevice( deviceID: string, ): $ReadOnlyArray; // method is provided to manually signal that a C++ object // is no longer needed and can be deleted delete(): void; } export type SQLiteQueryExecutorType = typeof SQLiteQueryExecutor;