From 084b1cf3a4579196f4afc51b5a935923b7ae97e7 Mon Sep 17 00:00:00 2001 From: Steven Zhang Date: Thu, 29 Oct 2026 15:02:34 -0400 Subject: [PATCH] chore: Make the React contract test WebSocket extend the shared base --- .../app/TestHarnessWebSocket.ts | 114 +++--------------- 1 file changed, 16 insertions(+), 98 deletions(-) diff --git a/packages/sdk/react/contract-tests/app/TestHarnessWebSocket.ts b/packages/sdk/react/contract-tests/app/TestHarnessWebSocket.ts index e8c72d5c18..92936a5d43 100644 --- a/packages/sdk/react/contract-tests/app/TestHarnessWebSocket.ts +++ b/packages/sdk/react/contract-tests/app/TestHarnessWebSocket.ts @@ -1,112 +1,30 @@ -import { CreateInstanceParams, makeLogger } from '@launchdarkly/js-contract-test-utils/client'; -import { LDLogger } from '@launchdarkly/react-sdk'; +import { + CreateInstanceParams, + TestHarnessWebSocket as BaseTestHarnessWebSocket, +} from '@launchdarkly/js-contract-test-utils/client'; import { CommandHandler } from './ClientEntity'; -export default class TestHarnessWebSocket { - private _ws?: WebSocket; - private _logger: LDLogger = makeLogger('TestHarnessWebSocket'); - +export default class TestHarnessWebSocket extends BaseTestHarnessWebSocket { constructor( - private readonly _url: string, + url: string, private readonly _commandHandlers: Map, private readonly _onCreateClient: (params: CreateInstanceParams) => Promise, private readonly _onDeleteClient: (id: string) => void, - ) {} - - connect() { - this._logger.info(`Connecting to web socket.`); - this._ws = new WebSocket(this._url, ['v1']); - this._ws.onopen = () => { - this._logger.info('Connected to websocket.'); - }; - this._ws.onclose = () => { - this._logger.info('Websocket closed. Attempting to reconnect in 1 second.'); - setTimeout(() => { - this.connect(); - }, 1000); - }; - this._ws.onerror = (err) => { - this._logger.info(`error:`, err); - }; - - this._ws.onmessage = async (msg) => { - this._logger.info('Test harness message', msg); - const data = JSON.parse(msg.data); - const resData: any = { reqId: data.reqId }; - - switch (data.command) { - case 'getCapabilities': - resData.capabilities = [ - 'client-side', - 'service-endpoints', - 'tags', - 'user-type', - 'inline-context-all', - 'anonymous-redaction', - 'strongly-typed', - 'client-prereq-events', - 'client-prereq-cycle-detection', - 'client-per-context-summaries', - 'track-hooks', - 'fdv1-fallback', - 'bootstrap', - ]; - break; - - case 'createClient': { - try { - const id = await this._onCreateClient(data.body); - resData.resourceUrl = `/clients/${id}`; - resData.status = 201; - } catch (e: any) { - resData.status = 500; - resData.error = e?.message ?? String(e); - } - break; - } - - case 'runCommand': { - const handler = this._commandHandlers.get(data.id); - if (handler) { - try { - const body = await handler(data.body); - resData.body = body; - resData.status = body ? 200 : 204; - } catch (e: any) { - if (e?.message === 'unsupported command') { - resData.status = 400; - resData.error = e.message; - } else { - resData.status = 500; - resData.error = e?.message ?? String(e); - } - } - } else { - resData.status = 404; - this._logger.warn(`Client did not exist: ${data.id}`); - } - break; - } - - case 'deleteClient': - this._onDeleteClient(data.id); - resData.status = 200; - break; - - default: - break; - } + ) { + super(url); + } - this.send(resData); - }; + protected createClient(params: CreateInstanceParams): Promise { + return this._onCreateClient(params); } - disconnect() { - this._ws?.close(); + protected getCommandHandler(id: string): CommandHandler | undefined { + return this._commandHandlers.get(id); } - send(data: unknown) { - this._ws?.send(JSON.stringify(data)); + protected deleteClient(id: string): boolean { + this._onDeleteClient(id); + return true; } }