66 lines
2.3 KiB
TypeScript
66 lines
2.3 KiB
TypeScript
|
|
import { describe, test, expect } from 'bun:test';
|
||
|
|
import { MemoryPrekeyStore } from '../src/memory-store.js';
|
||
|
|
|
||
|
|
function rand(n: number): Uint8Array {
|
||
|
|
const buf = new Uint8Array(n);
|
||
|
|
globalThis.crypto.getRandomValues(buf);
|
||
|
|
return buf;
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('PrekeyStore cleanup API', () => {
|
||
|
|
test('touchIdentity updates last activity', async () => {
|
||
|
|
const store = new MemoryPrekeyStore();
|
||
|
|
await store.saveIdentity('alice', rand(32), rand(32));
|
||
|
|
await store.touchIdentity('alice');
|
||
|
|
// Verify identity is still there
|
||
|
|
expect(await store.getIdentity('alice')).not.toBeNull();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('purgeStaleIdentities removes old addresses', async () => {
|
||
|
|
const store = new MemoryPrekeyStore();
|
||
|
|
|
||
|
|
// Alice was active long ago
|
||
|
|
await store.saveIdentity('alice', rand(32), rand(32));
|
||
|
|
await store.saveSignedPreKey('alice', 1, rand(32), rand(64));
|
||
|
|
await store.saveOneTimePreKeys('alice', [{ keyId: 100, publicKey: rand(32) }]);
|
||
|
|
// Manually set alice's activity to 1 day ago
|
||
|
|
await store.touchIdentity('alice');
|
||
|
|
(store as any).lastActivity.set('alice', Date.now() - 2 * 24 * 60 * 60 * 1000);
|
||
|
|
|
||
|
|
// Bob is fresh
|
||
|
|
await store.saveIdentity('bob', rand(32), rand(32));
|
||
|
|
await store.touchIdentity('bob');
|
||
|
|
|
||
|
|
// Purge anything older than 1 day
|
||
|
|
const count = await store.purgeStaleIdentities(24 * 60 * 60 * 1000);
|
||
|
|
expect(count).toBe(1);
|
||
|
|
|
||
|
|
// Alice is gone
|
||
|
|
expect(await store.getIdentity('alice')).toBeNull();
|
||
|
|
expect(await store.getSignedPreKey('alice')).toBeNull();
|
||
|
|
expect(await store.getOneTimePreKeyCount('alice')).toBe(0);
|
||
|
|
|
||
|
|
// Bob is still there
|
||
|
|
expect(await store.getIdentity('bob')).not.toBeNull();
|
||
|
|
});
|
||
|
|
|
||
|
|
test('purge returns 0 when nothing is stale', async () => {
|
||
|
|
const store = new MemoryPrekeyStore();
|
||
|
|
await store.saveIdentity('alice', rand(32), rand(32));
|
||
|
|
await store.touchIdentity('alice');
|
||
|
|
|
||
|
|
const count = await store.purgeStaleIdentities(60 * 60 * 1000); // 1 hour
|
||
|
|
expect(count).toBe(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('untouched identities are considered stale', async () => {
|
||
|
|
const store = new MemoryPrekeyStore();
|
||
|
|
// Save without touching — simulates an ancient identity from before cleanup API
|
||
|
|
await store.saveIdentity('ancient', rand(32), rand(32));
|
||
|
|
|
||
|
|
const count = await store.purgeStaleIdentities(1000);
|
||
|
|
expect(count).toBe(1);
|
||
|
|
expect(await store.getIdentity('ancient')).toBeNull();
|
||
|
|
});
|
||
|
|
});
|