mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-27 10:32:58 +02:00
146 lines
4.4 KiB
TypeScript
146 lines
4.4 KiB
TypeScript
import { afterAllTests, beforeAllDb, beforeEachDb, createFolder, createUserAndSession, db, dbSlave, expectThrow, getDatabaseClientType, models, packageRootDir, updateFolder } from './utils/testing/testUtils';
|
|
import { connectDb, disconnectDb, reconnectDb, sqliteSyncSlave } from './db';
|
|
import { ChangeType, Event } from './services/database/types';
|
|
import { DatabaseConfig, DatabaseConfigClient } from './utils/types';
|
|
import { createDb } from './tools/dbTools';
|
|
import { msleep } from './utils/time';
|
|
|
|
const eventId1 = '4f405391-bd72-4a4f-809f-344fc6cd4b31';
|
|
const eventId2 = '4f405391-bd72-4a4f-809f-344fc6cd4b32';
|
|
|
|
const event1: Event = {
|
|
id: eventId1,
|
|
type: 1,
|
|
name: 'test',
|
|
created_time: Date.now(),
|
|
};
|
|
|
|
const event2 = {
|
|
...event1,
|
|
id: eventId2,
|
|
};
|
|
|
|
const beforeTest = async (envValues: Record<string, string> = null) => {
|
|
await beforeAllDb('db.replication', envValues ? { envValues } : null);
|
|
await beforeEachDb();
|
|
};
|
|
|
|
const afterTest = async () => {
|
|
await afterAllTests();
|
|
};
|
|
|
|
describe('db.replication', () => {
|
|
|
|
it('should reconnect a database', async () => {
|
|
if (getDatabaseClientType() === DatabaseConfigClient.PostgreSQL) return;
|
|
|
|
await beforeTest();
|
|
|
|
await disconnectDb(db());
|
|
await expectThrow(async () => db().insert(event1).into('events'));
|
|
|
|
await reconnectDb(db());
|
|
await db().insert(event1).into('events');
|
|
|
|
{
|
|
const results = await db().select('*').from('events');
|
|
expect(results.length).toBe(1);
|
|
expect(results[0].id).toBe(eventId1);
|
|
}
|
|
|
|
await reconnectDb(db());
|
|
await db().insert(event2).into('events');
|
|
|
|
{
|
|
const results = await db().select('*').from('events');
|
|
expect(results.length).toBe(2);
|
|
expect([results[0].id, results[1].id].sort()).toEqual([eventId1, eventId2]);
|
|
}
|
|
|
|
await afterTest();
|
|
});
|
|
|
|
it('should manually sync an SQLite slave instance', async () => {
|
|
if (getDatabaseClientType() === DatabaseConfigClient.PostgreSQL) return;
|
|
|
|
const masterConfig: DatabaseConfig = {
|
|
client: DatabaseConfigClient.SQLite,
|
|
name: `${packageRootDir}/db-master-test.sqlite`,
|
|
};
|
|
|
|
const slaveConfig: DatabaseConfig = {
|
|
client: DatabaseConfigClient.SQLite,
|
|
name: `${packageRootDir}/db-slave-test.sqlite`,
|
|
};
|
|
|
|
await createDb(masterConfig, { dropIfExists: true });
|
|
await createDb(slaveConfig, { dropIfExists: true });
|
|
|
|
const master = await connectDb(masterConfig);
|
|
const slave = await connectDb(slaveConfig);
|
|
|
|
await master.insert(event1).into('events');
|
|
|
|
expect((await master.select('*').from('events')).length).toBe(1);
|
|
expect((await slave.select('*').from('events')).length).toBe(0);
|
|
|
|
await sqliteSyncSlave(master, slave);
|
|
|
|
expect((await master.select('*').from('events')).length).toBe(1);
|
|
expect((await slave.select('*').from('events')).length).toBe(1);
|
|
|
|
await disconnectDb(master);
|
|
await disconnectDb(slave);
|
|
});
|
|
|
|
test('should track changes - using replication', async () => {
|
|
if (getDatabaseClientType() === DatabaseConfigClient.PostgreSQL) return;
|
|
|
|
await beforeTest({ DB_USE_SLAVE: '1' });
|
|
|
|
const { session, user } = await createUserAndSession(1, true);
|
|
const changeModel = models().change();
|
|
|
|
const folder = {
|
|
id: '000000000000000000000000000000F1',
|
|
title: 'title 1',
|
|
};
|
|
|
|
const folderItem = await createFolder(session.id, folder);
|
|
await msleep(1);
|
|
|
|
let result = await changeModel.delta(user.id);
|
|
|
|
// We get nothing because the slave has not been synced yet
|
|
expect(result.items.length).toBe(0);
|
|
|
|
// But we still get the item because it doesn't use the slave database
|
|
expect((await models().item().loadAsJoplinItem(folderItem.id)).title).toBe('title 1');
|
|
|
|
// After sync, we should get the change
|
|
await sqliteSyncSlave(db(), dbSlave());
|
|
result = await changeModel.delta(user.id);
|
|
expect(result.items.length).toBe(1);
|
|
expect(result.items[0].type).toBe(ChangeType.Create);
|
|
|
|
await updateFolder(session.id, { ...folder, title: 'title 2' });
|
|
result = await changeModel.delta(user.id, { cursor: result.cursor });
|
|
|
|
// Nothing because it hasn't been synced yet
|
|
expect(result.items.length).toBe(0);
|
|
|
|
// But we get the latest item if requesting it directly
|
|
expect((await models().item().loadAsJoplinItem(folderItem.id)).title).toBe('title 2');
|
|
|
|
// After sync, we should get the change
|
|
await sqliteSyncSlave(db(), dbSlave());
|
|
result = await changeModel.delta(user.id, { cursor: result.cursor });
|
|
|
|
expect(result.items.length).toBe(1);
|
|
expect(result.items[0].type).toBe(ChangeType.Update);
|
|
|
|
await afterTest();
|
|
});
|
|
|
|
});
|