mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-25 10:58:19 +01:00
Poll notifications and read syncs
This commit is contained in:
135
ts/test-node/sql/migration_1520_test.node.ts
Normal file
135
ts/test-node/sql/migration_1520_test.node.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright 2025 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import type { WritableDB } from '../../sql/Interface.std.js';
|
||||
import { sql } from '../../sql/util.std.js';
|
||||
import {
|
||||
createDB,
|
||||
updateToVersion,
|
||||
insertData,
|
||||
explain,
|
||||
} from './helpers.node.js';
|
||||
|
||||
describe('SQL/updateToSchemaVersion1520', () => {
|
||||
let db: WritableDB;
|
||||
|
||||
afterEach(() => {
|
||||
db.close();
|
||||
});
|
||||
|
||||
describe('hasUnreadPollVotes column', () => {
|
||||
it('adds hasUnreadPollVotes column with default value 0', () => {
|
||||
db = createDB();
|
||||
updateToVersion(db, 1510);
|
||||
|
||||
const messages = [
|
||||
{
|
||||
id: 'msg1',
|
||||
conversationId: 'conv1',
|
||||
type: 'outgoing',
|
||||
received_at: 1000,
|
||||
sent_at: 1000,
|
||||
timestamp: 1000,
|
||||
json: JSON.stringify({
|
||||
poll: { question: 'Test?' },
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
insertData(db, 'messages', messages);
|
||||
updateToVersion(db, 1520);
|
||||
|
||||
const result = db
|
||||
.prepare("SELECT hasUnreadPollVotes FROM messages WHERE id = 'msg1'")
|
||||
.get<{ hasUnreadPollVotes: number }>();
|
||||
|
||||
assert.strictEqual(result?.hasUnreadPollVotes, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('messages_unread_poll_votes index', () => {
|
||||
it('creates messages_unread_poll_votes index', () => {
|
||||
db = createDB();
|
||||
updateToVersion(db, 1520);
|
||||
|
||||
const indexes = db
|
||||
.prepare(
|
||||
`
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type = 'index' AND name = 'messages_unread_poll_votes'
|
||||
`
|
||||
)
|
||||
.all();
|
||||
|
||||
assert.lengthOf(indexes, 1, 'index should exist');
|
||||
});
|
||||
|
||||
it('uses index for getUnreadPollVotesAndMarkRead UPDATE query', () => {
|
||||
db = createDB();
|
||||
updateToVersion(db, 1520);
|
||||
|
||||
const details = explain(
|
||||
db,
|
||||
sql`
|
||||
UPDATE messages
|
||||
INDEXED BY messages_unread_poll_votes
|
||||
SET hasUnreadPollVotes = 0
|
||||
WHERE
|
||||
conversationId = ${'test-conv'} AND
|
||||
hasUnreadPollVotes = 1 AND
|
||||
received_at <= ${5000} AND
|
||||
type IS 'outgoing'
|
||||
RETURNING id, conversationId, sent_at AS targetTimestamp, type;
|
||||
`
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
details,
|
||||
'SEARCH messages USING COVERING INDEX messages_unread_poll_votes (conversationId=? AND received_at<?)'
|
||||
);
|
||||
});
|
||||
|
||||
it('uses index when hasUnreadPollVotes = 1', () => {
|
||||
db = createDB();
|
||||
updateToVersion(db, 1520);
|
||||
|
||||
const detailsWithIndex = explain(
|
||||
db,
|
||||
sql`
|
||||
SELECT id FROM messages
|
||||
WHERE
|
||||
conversationId = ${'test-conv'} AND
|
||||
hasUnreadPollVotes = 1 AND
|
||||
type IS 'outgoing' AND
|
||||
received_at <= ${5000};
|
||||
`
|
||||
);
|
||||
|
||||
assert.include(
|
||||
detailsWithIndex,
|
||||
'messages_unread_poll_votes',
|
||||
'should use partial index when hasUnreadPollVotes = 1'
|
||||
);
|
||||
});
|
||||
|
||||
it('index includes all required columns and conditions', () => {
|
||||
db = createDB();
|
||||
updateToVersion(db, 1520);
|
||||
|
||||
const indexInfo = db
|
||||
.prepare(
|
||||
`
|
||||
SELECT sql FROM sqlite_master
|
||||
WHERE type = 'index' AND name = 'messages_unread_poll_votes'
|
||||
`
|
||||
)
|
||||
.get() as { sql: string };
|
||||
|
||||
assert.include(indexInfo.sql, 'conversationId');
|
||||
assert.include(indexInfo.sql, 'received_at');
|
||||
assert.include(indexInfo.sql, 'WHERE hasUnreadPollVotes = 1');
|
||||
assert.include(indexInfo.sql, "type IS 'outgoing'");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user