chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { PersonalDataServer } from '@pdsjs/core';
import { describe, expect, test, vi } from 'vitest';
/**
* @param {Array<import('../src/ports.js').ExtensionFactory>} extensions
* @param {(at: number) => void} [scheduleWakeup]
* @param {(work: Promise<unknown>) => void} [waitUntil]
*/
function server(extensions, scheduleWakeup, waitUntil) {
return new PersonalDataServer({
actorStorage: /** @type {any} */ ({}),
sharedStorage: /** @type {any} */ ({}),
blobs: /** @type {any} */ ({}),
jwtSecret: 'test-secret',
hostname: 'pds.example.com',
password: 'pw',
extensions,
scheduleWakeup,
waitUntil,
});
}
describe('extension ticks', () => {
test('answers the earliest time any extension asks to run again', async () => {
const pds = server([
() => ({ name: 'a', tick: async () => 3000 }),
() => ({ name: 'b', tick: async () => 1000 }),
() => ({ name: 'c', tick: async () => null }),
() => ({ name: 'd' }),
]);
expect(await pds.runExtensionTicks()).toBe(1000);
});
test('answers null when nothing is due', async () => {
const pds = server([() => ({ name: 'a', tick: async () => null })]);
expect(await pds.runExtensionTicks()).toBeNull();
});
test('runs the others when one tick fails', async () => {
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
const ran = vi.fn(async () => 5);
const pds = server([
() => ({
name: 'broken',
tick: async () => {
throw new Error('boom');
},
}),
() => ({ name: 'fine', tick: ran }),
]);
expect(await pds.runExtensionTicks()).toBe(5);
expect(ran).toHaveBeenCalled();
error.mockRestore();
});
test('passes a wakeup request through to the platform', async () => {
/** @type {number[]} */
const asked = [];
/** @type {import('../src/ports.js').ExtensionHost|undefined} */
let host;
server(
[
(h) => {
host = h;
return { name: 'a' };
},
],
(at) => {
asked.push(at);
},
);
await host?.scheduleWakeup(1234);
expect(asked).toEqual([1234]);
});
test('takes a wakeup request without a platform hook', async () => {
/** @type {import('../src/ports.js').ExtensionHost|undefined} */
let host;
server([
(h) => {
host = h;
return { name: 'a' };
},
]);
await expect(host?.scheduleWakeup(1234)).resolves.toBeUndefined();
});
test('hands background work to the platform, settled', async () => {
const error = vi.spyOn(console, 'error').mockImplementation(() => {});
/** @type {Promise<unknown>[]} */
const kept = [];
/** @type {import('../src/ports.js').ExtensionHost|undefined} */
let host;
server(
[
(h) => {
host = h;
return { name: 'a' };
},
],
undefined,
(work) => {
kept.push(work);
},
);
host?.background(Promise.reject(new Error('boom')));
expect(kept).toHaveLength(1);
await expect(kept[0]).resolves.toBeUndefined();
expect(error).toHaveBeenCalledWith(
'Background work failed:',
expect.any(Error),
);
error.mockRestore();
});
test('runs background work without a platform hook', async () => {
/** @type {import('../src/ports.js').ExtensionHost|undefined} */
let host;
server([
(h) => {
host = h;
return { name: 'a' };
},
]);
const ran = vi.fn();
host?.background(Promise.resolve().then(ran));
await Promise.resolve();
await Promise.resolve();
expect(ran).toHaveBeenCalled();
});
});