mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-24 18:38:15 +01:00
Deduplicate incoming attachments on disk
This commit is contained in:
139
ts/test-node/sql/migration_1650_test.node.ts
Normal file
139
ts/test-node/sql/migration_1650_test.node.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2026 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import type { WritableDB } from '../../sql/Interface.std.js';
|
||||
import {
|
||||
createDB,
|
||||
explain,
|
||||
getTableData,
|
||||
insertData,
|
||||
updateToVersion,
|
||||
} from './helpers.node.js';
|
||||
import { sql } from '../../sql/util.std.js';
|
||||
|
||||
describe('SQL/updateToSchemaVersion1650', () => {
|
||||
let db: WritableDB;
|
||||
|
||||
beforeEach(() => {
|
||||
db = createDB();
|
||||
updateToVersion(db, 1650);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
db.close();
|
||||
});
|
||||
|
||||
it('uses indexes for isAttachmentSafeToDelete', () => {
|
||||
const details = explain(
|
||||
db,
|
||||
sql`SELECT EXISTS (
|
||||
SELECT 1 FROM attachments_protected_from_deletion
|
||||
WHERE path = 'thepath'
|
||||
UNION ALL
|
||||
SELECT 1 FROM message_attachments
|
||||
WHERE
|
||||
path = 'thepath' OR
|
||||
thumbnailPath = 'thepath' OR
|
||||
screenshotPath = 'thepath'
|
||||
);`
|
||||
);
|
||||
|
||||
assert.isTrue(
|
||||
details.includes(
|
||||
'USING COVERING INDEX sqlite_autoindex_attachments_protected_from_deletion'
|
||||
)
|
||||
);
|
||||
assert.isTrue(details.includes('MULTI-INDEX OR'));
|
||||
assert.isTrue(
|
||||
details.includes('USING INDEX message_attachments_path (path=?)')
|
||||
);
|
||||
assert.isTrue(
|
||||
details.includes(
|
||||
'USING INDEX message_attachments_thumbnailPath (thumbnailPath=?)'
|
||||
)
|
||||
);
|
||||
assert.isTrue(
|
||||
details.includes(
|
||||
'USING INDEX message_attachments_screenshotPath (screenshotPath=?)'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('removes protected path when attachment is inserted or updated', () => {
|
||||
insertData(db, 'messages', [
|
||||
{
|
||||
id: 'messageId',
|
||||
conversationId: 'convoId',
|
||||
},
|
||||
]);
|
||||
|
||||
// Protect some paths
|
||||
insertData(db, 'attachments_protected_from_deletion', [
|
||||
{
|
||||
path: 'protected1',
|
||||
},
|
||||
{
|
||||
path: 'protected2',
|
||||
},
|
||||
{
|
||||
path: 'protected3',
|
||||
},
|
||||
{
|
||||
path: 'protected4',
|
||||
},
|
||||
{
|
||||
path: 'protected5',
|
||||
},
|
||||
{
|
||||
path: 'protected6',
|
||||
},
|
||||
{
|
||||
path: 'protected7',
|
||||
},
|
||||
]);
|
||||
|
||||
// Insert an attachment that uses a protected =path
|
||||
insertData(db, 'message_attachments', [
|
||||
{
|
||||
messageId: 'messageId',
|
||||
editHistoryIndex: -1,
|
||||
orderInMessage: 0,
|
||||
attachmentType: 'attachment',
|
||||
receivedAt: 42,
|
||||
sentAt: 42,
|
||||
size: 128,
|
||||
contentType: 'image/png',
|
||||
conversationId: 'convoId',
|
||||
path: 'protected1',
|
||||
thumbnailPath: 'protected2',
|
||||
screenshotPath: 'protected3',
|
||||
},
|
||||
]);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
getTableData(db, 'attachments_protected_from_deletion'),
|
||||
[
|
||||
{ path: 'protected4' },
|
||||
{ path: 'protected5' },
|
||||
{ path: 'protected6' },
|
||||
{ path: 'protected7' },
|
||||
]
|
||||
);
|
||||
|
||||
// Updates also remove protection
|
||||
db.prepare(
|
||||
`UPDATE message_attachments SET
|
||||
path='protected4',
|
||||
screenshotPath='protected5',
|
||||
thumbnailPath='protected6';
|
||||
`
|
||||
).run();
|
||||
|
||||
assert.deepStrictEqual(
|
||||
getTableData(db, 'attachments_protected_from_deletion'),
|
||||
[{ path: 'protected7' }]
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user