From c6f8d2eb9d009db77a5a14b409914e24321b5202 Mon Sep 17 00:00:00 2001 From: Andrew Bulat Date: Tue, 19 Nov 2024 03:16:01 +0000 Subject: [PATCH 1/2] Add LiveObjects plugin test to the `package` tests Test LiveObjects plugin can be imported and provided to the Ably client, and that TypeScript types for LiveObjects work as expected. --- test/package/browser/template/README.md | 4 +- test/package/browser/template/package.json | 2 +- .../server/resources/index-liveobjects.html | 11 +++++ .../package/browser/template/server/server.ts | 2 +- .../browser/template/src/index-liveobjects.ts | 43 +++++++++++++++++++ test/package/browser/template/src/sandbox.ts | 8 +++- .../browser/template/test/lib/package.test.ts | 1 + 7 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 test/package/browser/template/server/resources/index-liveobjects.html create mode 100644 test/package/browser/template/src/index-liveobjects.ts diff --git a/test/package/browser/template/README.md b/test/package/browser/template/README.md index 8bf44061be..38f2e248d2 100644 --- a/test/package/browser/template/README.md +++ b/test/package/browser/template/README.md @@ -8,6 +8,7 @@ This directory is intended to be used for testing the following aspects of the a It contains three files, each of which import ably-js in different manners, and provide a way to briefly exercise its functionality: - `src/index-default.ts` imports the default ably-js package (`import { Realtime } from 'ably'`). +- `src/index-liveobjects.ts` imports the LiveObjects ably-js plugin (`import LiveObjects from 'ably/liveobjects'`). - `src/index-modular.ts` imports the tree-shakable ably-js package (`import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modular'`). - `src/ReactApp.tsx` imports React hooks from the ably-js package (`import { useChannel } from 'ably/react'`). @@ -25,6 +26,7 @@ This directory exposes three package scripts that are to be used for testing: - `build`: Uses esbuild to create: 1. a bundle containing `src/index-default.ts` and ably-js; - 2. a bundle containing `src/index-modular.ts` and ably-js. + 2. a bundle containing `src/index-liveobjects.ts` and ably-js. + 3. a bundle containing `src/index-modular.ts` and ably-js. - `test`: Using the bundles created by `build` and playwright components setup, tests that the code that exercises ably-js’s functionality is working correctly in a browser. - `typecheck`: Type-checks the code that imports ably-js. diff --git a/test/package/browser/template/package.json b/test/package/browser/template/package.json index a05aa04977..f2c023b6e6 100644 --- a/test/package/browser/template/package.json +++ b/test/package/browser/template/package.json @@ -4,7 +4,7 @@ "description": "", "main": "index.js", "scripts": { - "build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist", + "build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-liveobjects.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist", "typecheck": "tsc --project src -noEmit", "test-support:server": "ts-node server/server.ts", "test": "npm run test:lib && npm run test:hooks", diff --git a/test/package/browser/template/server/resources/index-liveobjects.html b/test/package/browser/template/server/resources/index-liveobjects.html new file mode 100644 index 0000000000..b7f284af5a --- /dev/null +++ b/test/package/browser/template/server/resources/index-liveobjects.html @@ -0,0 +1,11 @@ + + + + + Ably NPM package test (LiveObjects plugin export) + + + + + + diff --git a/test/package/browser/template/server/server.ts b/test/package/browser/template/server/server.ts index 2409fc30c5..faa1399f70 100644 --- a/test/package/browser/template/server/server.ts +++ b/test/package/browser/template/server/server.ts @@ -5,7 +5,7 @@ async function startWebServer(listenPort: number) { const server = express(); server.get('/', (req, res) => res.send('OK')); server.use(express.static(path.join(__dirname, '/resources'))); - for (const filename of ['index-default.js', 'index-modular.js']) { + for (const filename of ['index-default.js', 'index-liveobjects.js', 'index-modular.js']) { server.use(`/${filename}`, express.static(path.join(__dirname, '..', 'dist', filename))); } diff --git a/test/package/browser/template/src/index-liveobjects.ts b/test/package/browser/template/src/index-liveobjects.ts new file mode 100644 index 0000000000..9334aadf42 --- /dev/null +++ b/test/package/browser/template/src/index-liveobjects.ts @@ -0,0 +1,43 @@ +import * as Ably from 'ably'; +import LiveObjects from 'ably/liveobjects'; +import { createSandboxAblyAPIKey } from './sandbox'; + +globalThis.testAblyPackage = async function () { + const key = await createSandboxAblyAPIKey({ featureFlags: ['enableChannelState'] }); + + const realtime = new Ably.Realtime({ key, environment: 'sandbox', plugins: { LiveObjects } }); + + const channel = realtime.channels.get('channel', { modes: ['STATE_SUBSCRIBE', 'STATE_PUBLISH'] }); + // check liveObjects can be accessed + const liveObjects = channel.liveObjects; + await channel.attach(); + // root should be a LiveMap object + const root: Ably.LiveMap = await liveObjects.getRoot(); + + // check root is recognized as LiveMap TypeScript type + root.get('someKey'); + root.size(); + + // check LiveMap subscription callback has correct TypeScript types + const { unsubscribe } = root.subscribe(({ update }) => { + switch (update.someKey) { + case 'removed': + case 'updated': + break; + default: + // check all possible types are exhausted + const shouldExhaustAllTypes: never = update.someKey; + } + }); + unsubscribe(); + + // check LiveCounter types also behave as expected + const counter = root.get('randomKey') as Ably.LiveCounter | undefined; + // use nullish coalescing as we didn't actually create a counter object on the root, + // so the next calls would fail. we only need to check that TypeScript types work + const value: number = counter?.value(); + const counterSubscribeResponse = counter?.subscribe(({ update }) => { + const shouldBeANumber: number = update.inc; + }); + counterSubscribeResponse?.unsubscribe(); +}; diff --git a/test/package/browser/template/src/sandbox.ts b/test/package/browser/template/src/sandbox.ts index 100ab22f00..54c5f2e64a 100644 --- a/test/package/browser/template/src/sandbox.ts +++ b/test/package/browser/template/src/sandbox.ts @@ -1,10 +1,14 @@ import testAppSetup from '../../../../common/ably-common/test-resources/test-app-setup.json'; -export async function createSandboxAblyAPIKey() { +export async function createSandboxAblyAPIKey(withOptions?: object) { + const postData = { + ...testAppSetup.post_apps, + ...(withOptions ?? {}), + }; const response = await fetch('https://sandbox-rest.ably.io/apps', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(testAppSetup.post_apps), + body: JSON.stringify(postData), }); if (!response.ok) { diff --git a/test/package/browser/template/test/lib/package.test.ts b/test/package/browser/template/test/lib/package.test.ts index fc73006f3d..8554dd762b 100644 --- a/test/package/browser/template/test/lib/package.test.ts +++ b/test/package/browser/template/test/lib/package.test.ts @@ -3,6 +3,7 @@ import { test, expect } from '@playwright/test'; test.describe('NPM package', () => { for (const scenario of [ { name: 'default export', path: '/index-default.html' }, + { name: 'LiveObjects plugin export', path: '/index-liveobjects.html' }, { name: 'modular export', path: '/index-modular.html' }, ]) { test.describe(scenario.name, () => { From d59e16710f51421ccf2dba7f53956eccb1d1283c Mon Sep 17 00:00:00 2001 From: Andrew Bulat Date: Thu, 28 Nov 2024 04:54:08 +0000 Subject: [PATCH 2/2] Fix incorrect `moduleResolution` in `tsconfig.json` for package tests `moduleResolution` must be set to `node` as `resolveJsonModule: true` cannot be used otherwise. --- test/package/browser/template/src/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/package/browser/template/src/tsconfig.json b/test/package/browser/template/src/tsconfig.json index e280baa6de..b206a63995 100644 --- a/test/package/browser/template/src/tsconfig.json +++ b/test/package/browser/template/src/tsconfig.json @@ -4,7 +4,7 @@ "resolveJsonModule": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "bundler", + "moduleResolution": "node", "jsx": "react-jsx" } }