feat: Replace WebSocketSubscription2021 with WebSocketChannel2023

This commit is contained in:
Joachim Van Herwegen
2023-02-03 16:20:22 +01:00
parent cbbb10afa1
commit 702e8f5f59
21 changed files with 141 additions and 141 deletions

View File

@@ -14,17 +14,16 @@ import {
getPresetConfigPath,
getTestConfigPath,
getTestFolder,
instantiateFromConfig,
removeFolder,
instantiateFromConfig, removeFolder,
} from './Config';
import quad = DataFactory.quad;
import namedNode = DataFactory.namedNode;
const port = getPort('WebSocketSubscription2021');
const port = getPort('WebSocketChannel2023');
const baseUrl = `http://localhost:${port}/`;
const notificationType = NOTIFY.WebSocketSubscription2021;
const notificationType = NOTIFY.WebSocketChannel2023;
const rootFilePath = getTestFolder('WebSocketSubscription2021');
const rootFilePath = getTestFolder('WebSocketChannel2023');
const stores: [string, any][] = [
[ 'in-memory storage', {
configs: [ 'storage/backend/memory.json', 'util/resource-locker/memory.json' ],
@@ -37,7 +36,7 @@ const stores: [string, any][] = [
}],
];
describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', (name, { configs, teardown }): void => {
describe.each(stores)('A server supporting WebSocketChannel2023 using %s', (name, { configs, teardown }): void => {
let app: App;
let store: ResourceStore;
const webId = 'http://example.com/card/#me';
@@ -89,7 +88,7 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s',
// Find the notification channel for websockets
const subscriptions = quads.getObjects(storageDescriptionUrl, NOTIFY.terms.subscription, null);
const websocketSubscriptions = subscriptions.filter((channel): boolean => quads.has(
quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebSocketSubscription2021`)),
quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebSocketChannel2023`)),
));
expect(websocketSubscriptions).toHaveLength(1);
subscriptionUrl = websocketSubscriptions[0].value;
@@ -97,7 +96,7 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s',
it('supports subscribing.', async(): Promise<void> => {
const response = await subscribe(notificationType, webId, subscriptionUrl, topic);
webSocketUrl = (response as any).source;
webSocketUrl = (response as any).receiveFrom;
});
it('emits Created events.', async(): Promise<void> => {
@@ -167,7 +166,7 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s',
const channel = {
'@context': [ 'https://www.w3.org/ns/solid/notification/v1' ],
type: NOTIFY.WebSocketSubscription2021,
type: notificationType,
topic: restricted,
};
@@ -199,9 +198,9 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s',
});
expect(response.status).toBe(201);
const { source } = await subscribe(notificationType, webId, subscriptionUrl, topic, { state: 'abc' }) as any;
const { receiveFrom } = await subscribe(notificationType, webId, subscriptionUrl, topic, { state: 'abc' }) as any;
const socket = new WebSocket(source);
const socket = new WebSocket(receiveFrom);
const notificationPromise = new Promise<Buffer>((resolve): any => socket.on('message', resolve));
await new Promise<void>((resolve): any => socket.on('open', resolve));
@@ -213,10 +212,10 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s',
});
it('removes expired channels.', async(): Promise<void> => {
const { source } =
const { receiveFrom } =
await subscribe(notificationType, webId, subscriptionUrl, topic, { endAt: '1988-03-09T14:48:00.000Z' }) as any;
const socket = new WebSocket(source);
const socket = new WebSocket(receiveFrom);
const messagePromise = new Promise<Buffer>((resolve): any => socket.on('message', resolve));
await new Promise<void>((resolve): any => socket.on('close', resolve));
@@ -245,7 +244,8 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s',
const parser = new Parser({ baseIRI: subscriptionUrl });
const quads = new Store(parser.parse(await response.text()));
expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ NOTIFY.terms.WebSocketSubscription2021 ]);
expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ NOTIFY.terms.WebSocketChannel2023 ]);
expect(quads.getObjects(null, NOTIFY.terms.topic, null)).toEqual([ namedNode(topic) ]);
expect(quads.countQuads(null, NOTIFY.terms.receiveFrom, null, null)).toBe(1);
});
});

View File

@@ -27,9 +27,9 @@ describe('A KeyValueChannelStorage', (): void => {
beforeEach(async(): Promise<void> => {
resetAllMocks();
channel = {
id: `WebSocketSubscription2021:${v4()}:http://example.com/foo`,
id: `WebSocketChannel2023:${v4()}:http://example.com/foo`,
topic,
type: 'WebSocketSubscription2021',
type: 'WebSocketChannel2023',
};
internalMap = new Map();

View File

@@ -3,12 +3,12 @@ import type { WebSocket } from 'ws';
import { BasicRepresentation } from '../../../../../src/http/representation/BasicRepresentation';
import type { NotificationChannel } from '../../../../../src/server/notifications/NotificationChannel';
import {
WebSocket2021Emitter,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter';
WebSocket2023Emitter,
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Emitter';
import type { SetMultiMap } from '../../../../../src/util/map/SetMultiMap';
import { WrappedSetMultiMap } from '../../../../../src/util/map/WrappedSetMultiMap';
describe('A WebSocket2021Emitter', (): void => {
describe('A WebSocket2023Emitter', (): void => {
const channel: NotificationChannel = {
id: 'id',
topic: 'http://example.com/foo',
@@ -17,7 +17,7 @@ describe('A WebSocket2021Emitter', (): void => {
let webSocket: jest.Mocked<WebSocket>;
let socketMap: SetMultiMap<string, WebSocket>;
let emitter: WebSocket2021Emitter;
let emitter: WebSocket2023Emitter;
beforeEach(async(): Promise<void> => {
webSocket = new EventEmitter() as any;
@@ -26,7 +26,7 @@ describe('A WebSocket2021Emitter', (): void => {
socketMap = new WrappedSetMultiMap();
emitter = new WebSocket2021Emitter(socketMap);
emitter = new WebSocket2023Emitter(socketMap);
});
it('emits notifications to the stored WebSockets.', async(): Promise<void> => {

View File

@@ -10,11 +10,11 @@ import type {
NotificationChannelStorage,
} from '../../../../../src/server/notifications/NotificationChannelStorage';
import type {
WebSocket2021Handler,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Handler';
WebSocket2023Handler,
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Handler';
import {
WebSocket2021Listener,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Listener';
WebSocket2023Listener,
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Listener';
import { flushPromises } from '../../../../util/Util';
jest.mock('ws', (): any => ({
@@ -26,7 +26,7 @@ jest.mock('ws', (): any => ({
})),
}));
describe('A WebSocket2021Listener', (): void => {
describe('A WebSocket2023Listener', (): void => {
const channel: NotificationChannel = {
id: 'id',
topic: 'http://example.com/foo',
@@ -37,9 +37,9 @@ describe('A WebSocket2021Listener', (): void => {
let webSocket: WebSocket;
let upgradeRequest: HttpRequest;
let storage: jest.Mocked<NotificationChannelStorage>;
let handler: jest.Mocked<WebSocket2021Handler>;
let handler: jest.Mocked<WebSocket2023Handler>;
const route = new AbsolutePathInteractionRoute('http://example.com/foo');
let listener: WebSocket2021Listener;
let listener: WebSocket2023Listener;
beforeEach(async(): Promise<void> => {
server = new EventEmitter() as any;
@@ -57,7 +57,7 @@ describe('A WebSocket2021Listener', (): void => {
handleSafe: jest.fn(),
} as any;
listener = new WebSocket2021Listener(storage, handler, route);
listener = new WebSocket2023Listener(storage, handler, route);
await listener.handle(server);
});

View File

@@ -6,13 +6,13 @@ import type {
} from '../../../../../src/server/notifications/NotificationChannelStorage';
import {
WebSocket2021Storer,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Storer';
WebSocket2023Storer,
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Storer';
import type { SetMultiMap } from '../../../../../src/util/map/SetMultiMap';
import { WrappedSetMultiMap } from '../../../../../src/util/map/WrappedSetMultiMap';
import { flushPromises } from '../../../../util/Util';
describe('A WebSocket2021Storer', (): void => {
describe('A WebSocket2023Storer', (): void => {
const channel: NotificationChannel = {
id: 'id',
topic: 'http://example.com/foo',
@@ -21,7 +21,7 @@ describe('A WebSocket2021Storer', (): void => {
let webSocket: jest.Mocked<WebSocket>;
let storage: jest.Mocked<NotificationChannelStorage>;
let socketMap: SetMultiMap<string, WebSocket>;
let storer: WebSocket2021Storer;
let storer: WebSocket2023Storer;
beforeEach(async(): Promise<void> => {
webSocket = new EventEmitter() as any;
@@ -33,7 +33,7 @@ describe('A WebSocket2021Storer', (): void => {
socketMap = new WrappedSetMultiMap();
storer = new WebSocket2021Storer(storage, socketMap);
storer = new WebSocket2023Storer(storage, socketMap);
});
it('stores WebSockets.', async(): Promise<void> => {
@@ -60,7 +60,7 @@ describe('A WebSocket2021Storer', (): void => {
jest.useFakeTimers();
// Need to create class after fake timers have been enabled
storer = new WebSocket2021Storer(storage, socketMap);
storer = new WebSocket2023Storer(storage, socketMap);
const webSocket2: jest.Mocked<WebSocket> = new EventEmitter() as any;
webSocket2.close = jest.fn();

View File

@@ -1,9 +1,9 @@
import type { IncomingMessage } from 'http';
import {
generateWebSocketUrl, parseWebSocketRequest,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Util';
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Util';
describe('WebSocket2021Util', (): void => {
describe('WebSocket2023Util', (): void => {
describe('#generateWebSocketUrl', (): void => {
it('generates a WebSocket link with a query parameter.', async(): Promise<void> => {
expect(generateWebSocketUrl('http://example.com/', '123456')).toBe('ws://example.com/?auth=123456');

View File

@@ -6,14 +6,14 @@ import type { NotificationChannel } from '../../../../../src/server/notification
import {
generateWebSocketUrl,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Util';
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Util';
import type {
WebSocketSubscription2021Channel,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021';
WebSocketChannel2023,
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type';
import {
isWebSocket2021Channel,
WebSocketSubscription2021,
} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021';
isWebSocket2023Channel,
WebSocketChannel2023Type,
} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type';
import { NOTIFY, RDF } from '../../../../../src/util/Vocabularies';
import quad = DataFactory.quad;
import blankNode = DataFactory.blankNode;
@@ -21,35 +21,35 @@ import namedNode = DataFactory.namedNode;
jest.mock('uuid', (): any => ({ v4: (): string => '4c9b88c1-7502-4107-bb79-2a3a590c7aa3' }));
describe('A WebSocketSubscription2021', (): void => {
describe('A WebSocketChannel2023', (): void => {
let data: Store;
let channel: WebSocketSubscription2021Channel;
let channel: WebSocketChannel2023;
const subject = blankNode();
const topic = 'https://storage.example/resource';
const route = new AbsolutePathInteractionRoute('http://example.com/foo');
let channelType: WebSocketSubscription2021;
let channelType: WebSocketChannel2023Type;
beforeEach(async(): Promise<void> => {
data = new Store();
data.addQuad(quad(subject, RDF.terms.type, NOTIFY.terms.WebSocketSubscription2021));
data.addQuad(quad(subject, RDF.terms.type, NOTIFY.terms.WebSocketChannel2023));
data.addQuad(quad(subject, NOTIFY.terms.topic, namedNode(topic)));
const id = 'http://example.com/foo/4c9b88c1-7502-4107-bb79-2a3a590c7aa3';
channel = {
id,
type: NOTIFY.WebSocketSubscription2021,
type: NOTIFY.WebSocketChannel2023,
topic,
source: generateWebSocketUrl(route.getPath(), id),
receiveFrom: generateWebSocketUrl(route.getPath(), id),
};
channelType = new WebSocketSubscription2021(route);
channelType = new WebSocketChannel2023Type(route);
});
it('exposes a utility function to verify if a channel is a websocket channel.', async(): Promise<void> => {
expect(isWebSocket2021Channel(channel)).toBe(true);
expect(isWebSocket2023Channel(channel)).toBe(true);
(channel as NotificationChannel).type = 'something else';
expect(isWebSocket2021Channel(channel)).toBe(false);
expect(isWebSocket2023Channel(channel)).toBe(false);
});
it('correctly parses notification channel bodies.', async(): Promise<void> => {

View File

@@ -31,7 +31,7 @@ const portNames = [
'Subdomains',
'WebHookSubscription2021',
'WebHookSubscription2021-client',
'WebSocketSubscription2021',
'WebSocketChannel2023',
// Unit
'BaseServerFactory',