Many fixes
This commit is contained in:
@@ -1,35 +1,38 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { RouteDefinition, RouteModule } from '../source/routes/types.ts';
|
||||
import { ApplicationRouter } from '../source/services/router.ts';
|
||||
import { Broadcaster } from '../source/services/broadcaster.ts';
|
||||
import { Logger } from '../source/utils/logger.ts';
|
||||
import { TestConnection } from './helpers/test-connection.ts';
|
||||
|
||||
const moduleWith = (routes: RouteDefinition[]): RouteModule => {
|
||||
return {
|
||||
async getRoutes(): Promise<RouteDefinition[]> {
|
||||
return routes;
|
||||
},
|
||||
};
|
||||
};
|
||||
import { createControlledRequest } from './helpers/controlled-request.ts';
|
||||
import { createMockAuth, toRoutes } from './helpers/misc.ts';
|
||||
|
||||
const expectPending = async (promise: Promise<void>): Promise<void> => {
|
||||
const settled = vi.fn();
|
||||
void promise.then(settled);
|
||||
await Promise.resolve();
|
||||
expect(settled).not.toHaveBeenCalled();
|
||||
};
|
||||
/**
|
||||
* A mock of the AuthSecp256k1 service
|
||||
*/
|
||||
const auth = createMockAuth();
|
||||
|
||||
describe('long-lived subscription dispatch', (): void => {
|
||||
it('allows duplicate subscribe and unsubscribe requests while the original request waits', async (): Promise<void> => {
|
||||
const broadcaster = new Broadcaster(new Logger('subscription-flow-test'));
|
||||
const router = await ApplicationRouter.create([
|
||||
moduleWith([
|
||||
const router = await ApplicationRouter.create({
|
||||
auth,
|
||||
},
|
||||
[
|
||||
toRoutes([
|
||||
{
|
||||
url: '/items/subscribe',
|
||||
handler: async (stream): Promise<void> => {
|
||||
const { signalStarted, released } = stream.body as {
|
||||
signalStarted: () => void;
|
||||
released: Promise<void>;
|
||||
};
|
||||
|
||||
signalStarted();
|
||||
|
||||
await broadcaster.subscribe(stream, [ 'items' ]);
|
||||
await released;
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -43,17 +46,24 @@ describe('long-lived subscription dispatch', (): void => {
|
||||
]);
|
||||
const connection = new TestConnection(true, true);
|
||||
|
||||
const original = router.dispatch({ path: '/items/subscribe', requestId: 'subscribe-1' }, connection);
|
||||
const original = createControlledRequest({ router, connection, path: '/items/subscribe', requestId: 'subscribe-1' });
|
||||
await vi.waitFor(() => expect(connection.closeCallbacks).toHaveLength(1));
|
||||
await expectPending(original);
|
||||
await original.started;
|
||||
|
||||
// This request uses a different ApplicationRouteStream over the same
|
||||
// connection. Since the topic already exists, its dispatch completes.
|
||||
await router.dispatch({ path: '/items/subscribe', requestId: 'subscribe-2' }, connection);
|
||||
await expectPending(original);
|
||||
const second = createControlledRequest({ router, connection, path: '/items/subscribe', requestId: 'subscribe-2' });
|
||||
second.release();
|
||||
await second.request;
|
||||
|
||||
await router.dispatch({ path: '/items/unsubscribe', requestId: 'unsubscribe-1' }, connection);
|
||||
await original;
|
||||
// Unsubscribe the original request stream
|
||||
const third = createControlledRequest({ router, connection, path: '/items/unsubscribe', requestId: 'unsubscribe-1' });
|
||||
third.release();
|
||||
await third.request;
|
||||
|
||||
// Release the original request stream
|
||||
original.release();
|
||||
await original.request;
|
||||
|
||||
expect(connection.messages).toEqual([
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user