shrub/pkg/npm/http-api/test/default.test.ts

181 lines
4.4 KiB
TypeScript
Raw Normal View History

2021-01-27 08:45:18 +03:00
import Urbit from '../src';
2021-07-20 08:21:32 +03:00
import 'jest';
2021-01-27 08:45:18 +03:00
function fakeSSE(messages = [], timeout = 0) {
const ourMessages = [...messages];
const enc = new TextEncoder();
return new ReadableStream({
start(controller) {
const interval = setInterval(() => {
let message = ':\n';
if (ourMessages.length > 0) {
message = ourMessages.shift();
}
controller.enqueue(enc.encode(message));
}, 50);
if (timeout > 0) {
setTimeout(() => {
controller.close();
2021-07-26 03:04:26 +03:00
clearInterval(interval);
interval;
}, timeout);
}
},
});
}
const ship = '~sampel-palnet';
let eventId = 0;
function event(data: any) {
return `id:${eventId++}\ndata:${JSON.stringify(data)}\n\n`;
}
function fact(id: number, data: any) {
return event({
response: 'diff',
id,
json: data,
});
}
function ack(id: number, err = false) {
const res = err ? { err: 'Error' } : { ok: true };
return event({ id, response: 'poke', ...res });
}
const fakeFetch = (body) => () =>
Promise.resolve({
ok: true,
body: body(),
});
const wait = (ms: number) => new Promise((res) => setTimeout(res, ms));
process.on('unhandledRejection', (error) => {
console.error(error);
});
describe('Initialisation', () => {
let airlock: Urbit;
let fetchSpy;
beforeEach(() => {
airlock = new Urbit('', '+code');
});
afterEach(() => {
fetchSpy.mockReset();
});
it('should poke & connect upon a 200', async () => {
airlock.onOpen = jest.fn();
fetchSpy = jest.spyOn(window, 'fetch');
fetchSpy
.mockImplementationOnce(() =>
Promise.resolve({ ok: true, body: fakeSSE() })
)
.mockImplementationOnce(() =>
2021-07-20 08:21:32 +03:00
Promise.resolve({ ok: true, body: fakeSSE([ack(1)]) })
);
await airlock.eventSource();
expect(airlock.onOpen).toHaveBeenCalled();
}, 500);
it('should handle failures', async () => {
fetchSpy = jest.spyOn(window, 'fetch');
2021-07-26 03:04:26 +03:00
airlock.onRetry = jest.fn();
airlock.onOpen = jest.fn();
fetchSpy
2021-07-20 08:21:32 +03:00
.mockImplementationOnce(() =>
Promise.resolve({ ok: true, body: fakeSSE() })
)
.mockImplementationOnce(() =>
2021-07-26 03:04:26 +03:00
Promise.resolve({ ok: true, body: fakeSSE([], 100) })
);
2021-07-20 08:21:32 +03:00
airlock.onError = jest.fn();
try {
2021-07-26 03:04:26 +03:00
airlock.eventSource();
await wait(200);
} catch (e) {
2021-07-26 03:04:26 +03:00
expect(airlock.onRetry).toHaveBeenCalled();
}
2021-07-26 03:04:26 +03:00
}, 300);
});
describe('subscription', () => {
let airlock: Urbit;
let fetchSpy: jest.SpyInstance;
beforeEach(() => {
eventId = 1;
});
afterEach(() => {
fetchSpy.mockReset();
});
it('should subscribe', async () => {
fetchSpy = jest.spyOn(window, 'fetch');
airlock = new Urbit('', '+code');
airlock.onOpen = jest.fn();
const params = {
app: 'app',
path: '/path',
err: jest.fn(),
event: jest.fn(),
quit: jest.fn(),
};
const firstEv = 'one';
const secondEv = 'two';
const events = (id) => [fact(id, firstEv), fact(id, secondEv)];
fetchSpy.mockImplementation(fakeFetch(() => fakeSSE(events(1))));
await airlock.subscribe(params);
await wait(600);
expect(airlock.onOpen).toBeCalled();
2022-05-26 17:26:10 +03:00
expect(params.event).toHaveBeenNthCalledWith(1, firstEv, 'json');
expect(params.event).toHaveBeenNthCalledWith(2, secondEv, 'json');
}, 800);
it('should poke', async () => {
fetchSpy = jest.spyOn(window, 'fetch');
airlock = new Urbit('', '+code');
airlock.onOpen = jest.fn();
fetchSpy.mockImplementation(fakeFetch(() => fakeSSE([ack(1)])));
const params = {
app: 'app',
mark: 'mark',
json: { poke: 1 },
onSuccess: jest.fn(),
onError: jest.fn(),
};
await airlock.poke(params);
await wait(300);
expect(params.onSuccess).toHaveBeenCalled();
}, 800);
it('should nack poke', async () => {
fetchSpy = jest.spyOn(window, 'fetch');
airlock = new Urbit('', '+code');
airlock.onOpen = jest.fn();
2021-07-26 03:04:26 +03:00
fetchSpy
.mockImplementationOnce(() =>
Promise.resolve({ ok: true, body: fakeSSE() })
)
.mockImplementationOnce(() =>
Promise.resolve({ ok: false, body: fakeSSE([ack(1, true)]) })
);
2021-07-26 03:04:26 +03:00
const params = {
app: 'app',
mark: 'mark',
json: { poke: 1 },
onSuccess: jest.fn(),
onError: jest.fn(),
};
try {
await airlock.poke(params);
await wait(300);
} catch (e) {
2021-07-26 03:04:26 +03:00
expect(true).toBe(true);
}
2021-01-27 08:45:18 +03:00
});
});