72 lines
1.8 KiB
TypeScript
72 lines
1.8 KiB
TypeScript
// Copyright 2025 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import { assert } from 'chai';
|
|
import { v1 as getGuid } from 'uuid';
|
|
|
|
import { sql } from '../../sql/util';
|
|
import {
|
|
updateToVersion,
|
|
createDB,
|
|
explain,
|
|
insertData,
|
|
getTableData,
|
|
} from './helpers';
|
|
|
|
import type { WritableDB } from '../../sql/Interface';
|
|
|
|
describe('SQL/updateToSchemaVersion1380', () => {
|
|
let db: WritableDB;
|
|
beforeEach(() => {
|
|
db = createDB();
|
|
updateToVersion(db, 1380);
|
|
});
|
|
|
|
afterEach(() => {
|
|
db.close();
|
|
});
|
|
|
|
it('creates new donationReceipts table', () => {
|
|
const [query] = sql`SELECT * FROM donationReceipts`;
|
|
db.prepare(query).run();
|
|
});
|
|
|
|
it('throws if same id is used for an insert', () => {
|
|
// Note: this kinda looks like a receipt, but the json field is weird because
|
|
// insertData and getTableData both have special handling for JSON fields.
|
|
const receipt = {
|
|
id: getGuid(),
|
|
currencyType: 'USD',
|
|
paymentAmount: 500, // $5.00
|
|
paymentType: 'CARD',
|
|
paymentDetailJson: {
|
|
lastFourDigits: '1111',
|
|
},
|
|
timestamp: Date.now(),
|
|
};
|
|
|
|
insertData(db, 'donationReceipts', [receipt]);
|
|
|
|
assert.deepStrictEqual(getTableData(db, 'donationReceipts'), [receipt]);
|
|
|
|
assert.throws(
|
|
() => insertData(db, 'donationReceipts', [receipt]),
|
|
/UNIQUE constraint/
|
|
);
|
|
});
|
|
|
|
it('creates an index to make order by timestamp efficient', () => {
|
|
const template = sql`
|
|
SELECT * FROM donationReceipts
|
|
ORDER BY timestamp DESC
|
|
LIMIT 5
|
|
`;
|
|
|
|
const details = explain(db, template);
|
|
assert.include(details, 'USING INDEX donationReceipts_byTimestamp');
|
|
assert.notInclude(details, 'TEMP B-TREE');
|
|
// TODO: are we actually okay with a SCAN?
|
|
// assert.notInclude(details, 'SCAN');
|
|
});
|
|
});
|