From c8e891b58901b4f8a3a24e5befdd6838bc1338f2 Mon Sep 17 00:00:00 2001 From: Sonny Piers Date: Mon, 5 Jan 2026 19:30:28 +0100 Subject: [PATCH] Stop using jsx in tests --- Makefile | 4 +- babel.config.cjs | 38 +++--- eslint.config.js | 11 +- jest.config.cjs | 1 + package-lock.json | 50 ++----- package.json | 10 +- packages/client-core/test/Client.js | 10 +- packages/client-core/test/fast.js | 70 +++++----- packages/connection/test/_closeStream.js | 1 + packages/connection/test/disconnect.js | 5 +- packages/connection/test/onElement.js | 5 +- packages/connection/test/parserError.js | 1 + packages/connection/test/socketClose.js | 1 + packages/connection/test/stop.js | 1 + packages/connection/test/streamError.js | 1 + packages/iq/test/callee.js | 163 +++++++++++++---------- packages/iq/test/caller.js | 75 ++++------- packages/jid/test/index.js | 2 + packages/middleware/test/Context.js | 26 ++-- packages/middleware/test/middleware.js | 8 +- packages/websocket/test/test.js | 1 + server/index.js | 59 ++------ browser.test.js => test/browser.js | 6 +- 23 files changed, 255 insertions(+), 294 deletions(-) rename browser.test.js => test/browser.js (87%) diff --git a/Makefile b/Makefile index 550810425..7114fd4eb 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ test: cd packages/xmpp.js/ && npm run prepublish npm install make bundle - npx jest + npm run test make lint make bundlesize @@ -40,7 +40,7 @@ e2e: cd server && prosodyctl --config prosody.cfg.lua install mod_sasl2_sm > /dev/null cd server && prosodyctl --config prosody.cfg.lua install mod_sasl2_fast > /dev/null npm run e2e - node --test browser.test.js + node --test test/browser.js clean: make stop diff --git a/babel.config.cjs b/babel.config.cjs index 170c70d9c..10865cf5d 100644 --- a/babel.config.cjs +++ b/babel.config.cjs @@ -4,25 +4,25 @@ module.exports = function config(api) { const isTest = api.env("test"); if (isTest) { - return { - plugins: [ - [ - "@babel/plugin-transform-react-jsx", - { - pragma: "xml", - throwIfNamespace: false, - }, - ], - [ - "babel-plugin-jsx-pragmatic", - { - module: "@xmpp/xml", - import: "xml", - }, - ], - "@babel/plugin-transform-modules-commonjs", - ], - }; + return {}; + // return { + // plugins: [ + // [ + // "@babel/plugin-transform-react-jsx", + // { + // pragma: "xml", + // throwIfNamespace: false, + // }, + // ], + // [ + // "babel-plugin-jsx-pragmatic", + // { + // module: "@xmpp/xml", + // import: "xml", + // }, + // ], + // ], + // }; } return { diff --git a/eslint.config.js b/eslint.config.js index 47bb843c1..62947d702 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -25,11 +25,11 @@ export default [ ...globals.builtin, ...globals["shared-node-browser"], }, - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, + // parserOptions: { + // ecmaFeatures: { + // jsx: false, + // }, + // }, sourceType: "module", }, @@ -128,6 +128,7 @@ export default [ "@xmpp/websocket", "selfsigned", "@xmpp/events", + "@jest/globals", ], }, ], diff --git a/jest.config.cjs b/jest.config.cjs index 9d54cccce..c53f728fc 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -12,4 +12,5 @@ module.exports = { "/packages/test/", ], setupFilesAfterEnv: ["jest-extended/all"], + transform: {}, }; diff --git a/package-lock.json b/package-lock.json index 7a4b66b09..00950310f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,14 @@ ], "devDependencies": { "@babel/core": "^7.28.5", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-runtime": "^7.28.5", "@babel/preset-env": "^7.28.5", "@babel/runtime": "^7.28.4", + "@jest/globals": "^30.2.0", "@rollup/plugin-babel": "^6.1.0", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^0.4.4", - "babel-jest": "^30.2.0", - "babel-plugin-jsx-pragmatic": "^1.0.2", "bytes": "^3.1.2", "eslint": "^9.39.1", "eslint-config-prettier": "^10.1.8", @@ -37,6 +34,7 @@ "lerna": "^9.0.3", "lint-staged": "^16.2.7", "prettier": "^3.7.4", + "promise-port": "^1.0.1", "rollup": "^4.53.3", "selfsigned": "^5.2.0" }, @@ -1499,26 +1497,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", @@ -6776,16 +6754,6 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/babel-plugin-jsx-pragmatic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jsx-pragmatic/-/babel-plugin-jsx-pragmatic-1.0.2.tgz", - "integrity": "sha512-+qeGXSbHZwinZzO6R3wP+6XDKup83Pgg2B3TQt2zwfDdgC7NqT9Kd3ws7iqk53zAO/8iOIRU6VUyUzt2LDE3Eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-syntax-jsx": "^6.0.0" - } - }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", @@ -6828,13 +6796,6 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==", - "dev": true, - "license": "MIT" - }, "node_modules/babel-preset-current-node-syntax": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", @@ -15757,6 +15718,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/promise-port": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-port/-/promise-port-1.0.1.tgz", + "integrity": "sha512-C3OxFrV+hH+ZTru48dHjI6qRCq+4eTbLVTu80/ig03Nvs703rzQbo+dHrI5tp/cDckSTfPNULottEwVKZje0zQ==", + "dev": true, + "license": "ISC" + }, "node_modules/promise-retry": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", diff --git a/package.json b/package.json index 2b0eea771..7a6526834 100644 --- a/package.json +++ b/package.json @@ -3,17 +3,14 @@ "type": "module", "devDependencies": { "@babel/core": "^7.28.5", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-runtime": "^7.28.5", "@babel/preset-env": "^7.28.5", "@babel/runtime": "^7.28.4", + "@jest/globals": "^30.2.0", "@rollup/plugin-babel": "^6.1.0", "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^0.4.4", - "babel-jest": "^30.2.0", - "babel-plugin-jsx-pragmatic": "^1.0.2", "bytes": "^3.1.2", "eslint": "^9.39.1", "eslint-config-prettier": "^10.1.8", @@ -31,12 +28,13 @@ "lerna": "^9.0.3", "lint-staged": "^16.2.7", "prettier": "^3.7.4", + "promise-port": "^1.0.1", "rollup": "^4.53.3", "selfsigned": "^5.2.0" }, "scripts": { - "test": "node ./node_modules/.bin/jest --forceExit", - "e2e": "NODE_TLS_REJECT_UNAUTHORIZED=0 node ./node_modules/.bin/jest --forceExit --runInBand --config e2e.config.cjs", + "test": "node --experimental-vm-modules ./node_modules/.bin/jest --forceExit", + "e2e": "NODE_TLS_REJECT_UNAUTHORIZED=0 node --experimental-vm-modules ./node_modules/.bin/jest --forceExit --runInBand --config e2e.config.cjs", "preversion": "make bundle" }, "engines": { diff --git a/packages/client-core/test/Client.js b/packages/client-core/test/Client.js index 312700cd2..ace656a0d 100644 --- a/packages/client-core/test/Client.js +++ b/packages/client-core/test/Client.js @@ -1,4 +1,4 @@ -import { JID } from "@xmpp/test"; +import { JID, xml } from "@xmpp/test"; import Client from "../lib/Client.js"; @@ -36,17 +36,17 @@ test("header", () => { entity.jid = null; entity.isSecure = () => false; - expect(entity.header()).toEqual(); + expect(entity.header(xml("foo"))).toEqual(xml("foo")); entity.jid = null; entity.isSecure = () => true; - expect(entity.header()).toEqual(); + expect(entity.header(xml("foo"))).toEqual(xml("foo")); entity.jid = new JID("foo@bar/example"); entity.isSecure = () => false; - expect(entity.header()).toEqual(); + expect(entity.header(xml("foo"))).toEqual(xml("foo")); entity.jid = new JID("foo@bar/example"); entity.isSecure = () => true; - expect(entity.header()).toEqual(); + expect(entity.header(xml("foo"))).toEqual(xml("foo", { from: "foo@bar" })); }); diff --git a/packages/client-core/test/fast.js b/packages/client-core/test/fast.js index 7ad4cc5be..fb2ab4dbe 100644 --- a/packages/client-core/test/fast.js +++ b/packages/client-core/test/fast.js @@ -1,5 +1,6 @@ +import { jest } from "@jest/globals"; import { tick } from "@xmpp/events"; -import { mockClient } from "@xmpp/test"; +import { mockClient, xml } from "@xmpp/test"; import { datetime } from "@xmpp/time"; import { Element } from "@xmpp/xml"; @@ -11,16 +12,17 @@ test("requests and saves token if server advertises fast", async () => { const spy_saveToken = jest.spyOn(fast, "saveToken"); entity.mockInput( - - - PLAIN - - - {mechanism} - - - - , + // prettier-ignore + xml('features', { xmlns: "http://etherx.jabber.org/streams" }, + xml('authentication', { xmlns: "urn:xmpp:sasl:2" }, + xml('mechanism', {}, "PLAIN"), + xml('inline', {}, + xml('fast', { xmlns: "urn:xmpp:fast:0" }, + xml('mechanism', {}, mechanism) + ) + ) + ) + ), ); const authenticate = await entity.catchOutgoing(); @@ -37,12 +39,11 @@ test("requests and saves token if server advertises fast", async () => { expect(spy_saveToken).not.toHaveBeenCalled(); entity.mockInput( - - - - username@localhost/rOYwkWIywtnF - - , + // prettier-ignore + xml('success', { xmlns: "urn:xmpp:sasl:2" }, + xml('token', { expiry, xmlns: "urn:xmpp:fast:0" , token}), + xml('authorization-identifier', {}, "username@localhost/rOYwkWIywtnF") + ), ); expect(spy_saveToken).toHaveBeenCalledWith({ token, expiry, mechanism }); @@ -64,16 +65,17 @@ async function setupFast() { }; entity.mockInput( - - - PLAIN - - - {mechanism} - - - - , + // prettier-ignore + xml('features', { xmlns: "http://etherx.jabber.org/streams" }, + xml('authentication', { xmlns: "urn:xmpp:sasl:2" }, + xml('mechanism', {}, "PLAIN"), + xml('inline', {}, + xml('fast', { xmlns: "urn:xmpp:fast:0" }, + xml('mechanism', {}, mechanism) + ) + ) + ) + ), ); expect(fast.mechanism).toBe(mechanism); @@ -94,9 +96,10 @@ test("deletes the token if server replies with not-authorized", async () => { expect(spy_deleteToken).not.toHaveBeenCalled(); entity.mockInput( - - - , + // prettier-ignore + xml("failure", { xmlns: "urn:xmpp:sasl:2" }, + xml("not-authorized", { xmlns: "urn:ietf:params:xml:ns:xmpp-sasl" }), + ), ); await tick(); expect(spy_deleteToken).toHaveBeenCalled(); @@ -109,9 +112,10 @@ test("deletes the token if server replies with credentials-expired", async () => // credentials-expired expect(spy_deleteToken).not.toHaveBeenCalled(); entity.mockInput( - - - , + // prettier-ignore + xml("failure", { xmlns: "urn:xmpp:sasl:2" }, + xml("credentials-expired", { xmlns: "urn:ietf:params:xml:ns:xmpp-sasl" }), + ), ); await tick(); expect(spy_deleteToken).toHaveBeenCalled(); diff --git a/packages/connection/test/_closeStream.js b/packages/connection/test/_closeStream.js index 14ba98421..b5abffa7e 100644 --- a/packages/connection/test/_closeStream.js +++ b/packages/connection/test/_closeStream.js @@ -1,3 +1,4 @@ +import { jest } from "@jest/globals"; import { EventEmitter, promise, TimeoutError } from "@xmpp/events"; import { xml } from "@xmpp/test"; diff --git a/packages/connection/test/disconnect.js b/packages/connection/test/disconnect.js index 4c50d3493..535c8b40b 100644 --- a/packages/connection/test/disconnect.js +++ b/packages/connection/test/disconnect.js @@ -1,3 +1,6 @@ +import { jest } from "@jest/globals"; +import { xml } from "@xmpp/test"; + import Connection from "../index.js"; test("disconnect", async () => { @@ -69,7 +72,7 @@ test("disconnect with _closeStream and _closeSocket rejections", async () => { test("resolves if socket property is undefined", async () => { const conn = new Connection(); - conn.footerElement = () => ; + conn.footerElement = () => xml("foo"); conn.socket = undefined; await conn.disconnect(); expect().pass(); diff --git a/packages/connection/test/onElement.js b/packages/connection/test/onElement.js index 9f9d79479..739d9e93c 100644 --- a/packages/connection/test/onElement.js +++ b/packages/connection/test/onElement.js @@ -1,10 +1,11 @@ -import xml from "@xmpp/xml"; +import { jest } from "@jest/globals"; +import { xml } from "@xmpp/test"; import Connection from "../index.js"; test("#_onElement", (done) => { expect.assertions(2); - const foo = ; + const foo = xml("foo"); const conn = new Connection(); conn.on("element", (el) => { expect(el).toBe(foo); diff --git a/packages/connection/test/parserError.js b/packages/connection/test/parserError.js index 878c24707..1240da2a8 100644 --- a/packages/connection/test/parserError.js +++ b/packages/connection/test/parserError.js @@ -1,3 +1,4 @@ +import { jest } from "@jest/globals"; import { EventEmitter } from "@xmpp/events"; import Connection from "../index.js"; diff --git a/packages/connection/test/socketClose.js b/packages/connection/test/socketClose.js index f096f5b86..907b6ea13 100644 --- a/packages/connection/test/socketClose.js +++ b/packages/connection/test/socketClose.js @@ -1,3 +1,4 @@ +import { jest } from "@jest/globals"; import { EventEmitter } from "@xmpp/events"; import Connection from "../index.js"; diff --git a/packages/connection/test/stop.js b/packages/connection/test/stop.js index d33f9c221..215086979 100644 --- a/packages/connection/test/stop.js +++ b/packages/connection/test/stop.js @@ -1,3 +1,4 @@ +import { jest } from "@jest/globals"; import { EventEmitter } from "@xmpp/events"; import Connection from "../index.js"; diff --git a/packages/connection/test/streamError.js b/packages/connection/test/streamError.js index dfad6b39e..5b6815d47 100644 --- a/packages/connection/test/streamError.js +++ b/packages/connection/test/streamError.js @@ -1,3 +1,4 @@ +import { jest } from "@jest/globals"; import xml from "@xmpp/xml"; import Connection from "../index.js"; diff --git a/packages/iq/test/callee.js b/packages/iq/test/callee.js index 8378d5394..319884890 100644 --- a/packages/iq/test/callee.js +++ b/packages/iq/test/callee.js @@ -1,4 +1,10 @@ -import { mockClient, promiseSend, mockInput, promiseError } from "@xmpp/test"; +import { + mockClient, + promiseSend, + mockInput, + promiseError, + xml, +} from "@xmpp/test"; test("empty result when the handler returns true", async () => { const xmpp = mockClient(); @@ -8,12 +14,15 @@ test("empty result when the handler returns true", async () => { mockInput( xmpp, - - - , + // prettier-ignore + xml('iq', {type: "get", id: "123"}, + xml('foo', { xmlns: "bar" }) + ), ); - expect(await promiseSend(xmpp)).toEqual(); + expect(await promiseSend(xmpp)).toEqual( + xml("iq", { id: "123", type: "result" }), + ); }); test("iqs with text children are valid", async () => { @@ -24,14 +33,17 @@ test("iqs with text children are valid", async () => { mockInput( xmpp, - - {"\n"} - - {"foo"} - , + // prettier-ignore + xml('iq', { type: "get", id: "123" }, + "\n", + xml("foo", { xmlns: "bar" }), + "foo", + ), ); - expect(await promiseSend(xmpp)).toEqual(); + expect(await promiseSend(xmpp)).toEqual( + xml("iq", { id: "123", type: "result" }), + ); }); test("iqs with multiple element children are invalid", async () => { @@ -42,19 +54,21 @@ test("iqs with multiple element children are invalid", async () => { mockInput( xmpp, - - - - , + // prettier-ignore + xml('iq', {type: "get", id: "123"}, + xml("foo", {xmlns: "bar"}), + xml("foo", {xmlns: "bar"}) + ), ); expect(await promiseSend(xmpp)).toEqual( - - - - - - , + // prettier-ignore + xml('iq', {id: "123", type: "error"}, + xml("foo", {xmlns: "bar"}), + xml("error", {type: "modify"}, + xml("bad-request", {xmlns: "urn:ietf:params:xml:ns:xmpp-stanzas"}) + ) + ), ); }); @@ -63,20 +77,22 @@ test("non empty result when the handler returns an xml.Element", async () => { const { iqCallee } = xmpp; iqCallee.get("bar", "foo", () => { - return ; + return xml("hello"); }); mockInput( xmpp, - - - , + // prettier-ignore + xml('iq', {type: "get", id: "123"}, + xml("foo", { xmlns: "bar" }) + ), ); expect(await promiseSend(xmpp)).toEqual( - - - , + // prettier-ignore + xml('iq', { id: "123", type: "result" }, + xml('hello') + ), ); }); @@ -84,18 +100,20 @@ test("service unavailable error reply when there are no handler", async () => { const xmpp = mockClient(); xmpp.mockInput( - - - , + // prettier-ignore + xml('iq', { type: "get", id: "123" }, + xml('foo', {xmlns: "bar"}) + ), ); expect(await promiseSend(xmpp)).toEqual( - - - - - - , + // prettier-ignore + xml('iq', {id: "123", type: "error"}, + xml('foo', {xmlns: "bar"}), + xml("error", {type: "cancel"}, + xml('service-unavailable', {xmlns: "urn:ietf:params:xml:ns:xmpp-stanzas"}) + ) + ), ); }); @@ -113,19 +131,21 @@ test("internal server error reply when handler throws an error", async () => { mockInput( xmpp, - - - , + // prettier-ignore + xml('iq', { type: "get", id: "123" }, + xml('foo', {xmlns: "bar"}) + ), ); expect(await errorPromise).toBe(error); expect(await outputPromise).toEqual( - - - - - - , + // prettier-ignore + xml('iq', {id: "123", type: "error"}, + xml('foo', {xmlns: "bar"}), + xml('error', {type: "cancel"}, + xml('internal-server-error', {xmlns: "urn:ietf:params:xml:ns:xmpp-stanzas"}) + ) + ), ); }); @@ -143,19 +163,26 @@ test("internal server error reply when handler rejects with an error", async () mockInput( xmpp, - - - , + // prettier-ignore + xml('iq', { type: "set", id: "123" }, + xml('foo', {xmlns: "bar"}) + ), ); expect(await errorPromise).toBe(error); expect(await outputPromise).toEqual( - - - - - - , + xml( + "iq", + { id: "123", type: "error" }, + xml("foo", { xmlns: "bar" }), + xml( + "error", + { type: "cancel" }, + xml("internal-server-error", { + xmlns: "urn:ietf:params:xml:ns:xmpp-stanzas", + }), + ), + ), ); }); @@ -165,11 +192,11 @@ test("stanza error reply when handler returns an error element", async () => { const outputPromise = promiseSend(xmpp); - const errorElement = ( - - - - ); + const errorElement = + // prettier-ignore + xml('error', {type: "foo"}, + xml('bar', {xmlns: "urn:ietf:params:xml:ns:xmpp-stanzas"}) + ); iqCallee.set("bar", "foo", () => { return errorElement; @@ -177,15 +204,17 @@ test("stanza error reply when handler returns an error element", async () => { mockInput( xmpp, - - - , + // prettier-ignore + xml('iq', {type: "set", id: "123"}, + xml('foo', {xmlns: "bar"}) + ), ); expect(await outputPromise).toEqual( - - - {errorElement} - , + // prettier-ignore + xml('iq', {id: "123", type: "error"}, + xml("foo", {xmlns: "bar"}), + errorElement + ), ); }); diff --git a/packages/iq/test/caller.js b/packages/iq/test/caller.js index ace185313..1130926d1 100644 --- a/packages/iq/test/caller.js +++ b/packages/iq/test/caller.js @@ -1,4 +1,4 @@ -import { mockClient, mockInput } from "@xmpp/test"; +import { mockClient, mockInput, xml } from "@xmpp/test"; import StanzaError from "@xmpp/middleware/lib/StanzaError.js"; test("#request", (done) => { @@ -6,20 +6,12 @@ test("#request", (done) => { const { iqCaller } = xmpp; xmpp.send = (el) => { - expect(el).toEqual( - - - , - ); + expect(el).toEqual(xml("iq", { type: "get", id: "foobar" }, xml("foo"))); done(); return Promise.resolve(); }; - iqCaller.request( - - - , - ); + iqCaller.request(xml("iq", { type: "get", id: "foobar" }, xml("foo"))); }); test("removes the handler if sending failed", async () => { @@ -32,11 +24,7 @@ test("removes the handler if sending failed", async () => { return Promise.reject(error); }; - const promise = iqCaller.request( - - - , - ); + const promise = iqCaller.request(xml("iq", { type: "get" }, xml("foo"))); expect(iqCaller.handlers.size).toBe(1); @@ -54,9 +42,9 @@ test("resolves with with the stanza for result reply", async () => { const id = "foo"; - const promiseRequest = iqCaller.request(); + const promiseRequest = iqCaller.request(xml("iq", { type: "get", id })); - const reply = ; + const reply = xml("iq", { type: "result", id }); mockInput(xmpp, reply); expect(await promiseRequest).toEqual(reply); @@ -69,18 +57,14 @@ test("rejects with a StanzaError for error reply", async () => { const id = "foo"; - const promiseRequest = iqCaller.request(); + const promiseRequest = iqCaller.request(xml("iq", { type: "get", id })); - const errorElement = ( - - - - ); - const stanzaElement = ( - - {errorElement} - + const errorElement = xml( + "error", + { type: "modify" }, + xml("service-unavailable"), ); + const stanzaElement = xml("iq", { type: "error", id }, errorElement); mockInput(xmpp, stanzaElement); try { @@ -94,12 +78,7 @@ test("rejects with a TimeoutError if no answer is received within timeout", asyn const xmpp = mockClient(); const { iqCaller } = xmpp; - const promise = iqCaller.request( - - - , - 1, - ); + const promise = iqCaller.request(xml("iq", { type: "get" }, xml("foo")), 1); expect(iqCaller.handlers.size).toBe(1); @@ -115,16 +94,16 @@ test("#get", async () => { const xmpp = mockClient(); const { iqCaller } = xmpp; - const requestChild = ; + const requestChild = xml("foo", { xmlns: "foo:bar" }); const promiseGet = iqCaller.get(requestChild, "hello@there"); const { id } = requestChild.parent.attrs; - const replyChild = ; - const reply = ( - - {replyChild} - - ); + const replyChild = xml("foo", { xmlns: "foo:bar" }); + const reply = + // prettier-ignore + xml('iq', {type: "result", id, from: "hello@there"}, + replyChild + ); mockInput(xmpp, reply); expect(await promiseGet).toEqual(replyChild); @@ -134,16 +113,16 @@ test("#set", async () => { const xmpp = mockClient(); const { iqCaller } = xmpp; - const requestChild = ; + const requestChild = xml("foo", { xmlns: "foo:bar" }); const promiseSet = iqCaller.set(requestChild, "hello@there"); const { id } = requestChild.parent.attrs; - const replyChild = ; - const reply = ( - - {replyChild} - - ); + const replyChild = xml("foo", { xmlns: "foo:bar" }); + const reply = + // prettier-ignore + xml("iq", { type: "result", id, from: "hello@there" }, + replyChild, + ); mockInput(xmpp, reply); expect(await promiseSet).toEqual(replyChild); diff --git a/packages/jid/test/index.js b/packages/jid/test/index.js index 3fb814075..e767e57f8 100644 --- a/packages/jid/test/index.js +++ b/packages/jid/test/index.js @@ -1,3 +1,5 @@ +import { jest } from "@jest/globals"; + import jid, { equal, JID } from "../index.js"; test("equal calls equals on the first argument with the second argument", () => { diff --git a/packages/middleware/test/Context.js b/packages/middleware/test/Context.js index 01f4b655f..9e58c168c 100644 --- a/packages/middleware/test/Context.js +++ b/packages/middleware/test/Context.js @@ -1,3 +1,5 @@ +import { xml } from "@xmpp/test"; + import Context from "../lib/Context.js"; test("sets the entity property", () => { @@ -7,13 +9,13 @@ test("sets the entity property", () => { }); test("sets the stanza property", () => { - const stanza = ; + const stanza = xml("presence"); const ctx = new Context({}, stanza); expect(ctx.stanza).toBe(stanza); }); test("sets name, id and type properties", () => { - const stanza = ; + const stanza = xml("message", { id: "foobar", type: "whatever" }); const ctx = new Context({}, stanza); expect(ctx.name).toBe("message"); expect(ctx.id).toBe("foobar"); @@ -21,56 +23,56 @@ test("sets name, id and type properties", () => { }); test("id property defaults to empty string", () => { - const stanza = ; + const stanza = xml("message"); const ctx = new Context({}, stanza); expect(ctx.id).toBe(""); }); test("type property defaults to normal for message", () => { - const stanza = ; + const stanza = xml("message"); const ctx = new Context({}, stanza); expect(ctx.type).toBe("normal"); }); test("type property defaults to available for presence", () => { - const stanza = ; + const stanza = xml("presence"); const ctx = new Context({}, stanza); expect(ctx.type).toBe("available"); }); test("type property defaults to empty string for iq", () => { - const stanza = ; + const stanza = xml("iq"); const ctx = new Context({}, stanza); expect(ctx.type).toBe(""); }); test("type property defaults to empty string for nonzas", () => { - const stanza = ; + const stanza = xml("foobar"); const ctx = new Context({}, stanza); expect(ctx.type).toBe(""); }); test("to property is null", () => { - const ctx = new Context({}, ); + const ctx = new Context({}, xml("foobar")); expect(ctx.to).toBe(null); }); test("from property is null", () => { - const ctx = new Context({}, ); + const ctx = new Context({}, xml("foobar")); expect(ctx.from).toBe(null); }); test("local property is an empty string", () => { - const ctx = new Context({}, ); + const ctx = new Context({}, xml("foobar")); expect(ctx.local).toBe(""); }); test("domain property is an empty string", () => { - const ctx = new Context({}, ); + const ctx = new Context({}, xml("foobar")); expect(ctx.domain).toBe(""); }); test("resource property is an empty string", () => { - const ctx = new Context({}, ); + const ctx = new Context({}, xml("foobar")); expect(ctx.resource).toBe(""); }); diff --git a/packages/middleware/test/middleware.js b/packages/middleware/test/middleware.js index ef8dd9fb4..26594069c 100644 --- a/packages/middleware/test/middleware.js +++ b/packages/middleware/test/middleware.js @@ -1,4 +1,4 @@ -import { context, mockClient, mockInput, promiseError } from "@xmpp/test"; +import { context, mockClient, mockInput, promiseError, xml } from "@xmpp/test"; import IncomingContext from "../lib/IncomingContext.js"; import OutgoingContext from "../lib/OutgoingContext.js"; @@ -14,7 +14,7 @@ beforeEach(() => { test("use", (done) => { expect.assertions(4); - const stanza = ; + const stanza = xml("presence"); ctx.middleware.use((ctx, next) => { expect(ctx instanceof IncomingContext).toBe(true); expect(ctx.stanza).toEqual(stanza); @@ -27,7 +27,7 @@ test("use", (done) => { test("filter", (done) => { expect.assertions(3); - const stanza = ; + const stanza = xml("presence"); ctx.middleware.filter((ctx, next) => { expect(ctx instanceof OutgoingContext).toBe(true); expect(ctx.stanza).toEqual(stanza); @@ -49,7 +49,7 @@ test("emits an error event if a middleware throws", async () => { throw error; }); - mockInput(xmpp, ); + mockInput(xmpp, xml("presence", { id: "hello" })); const err = await willError; expect(err).toEqual(error); diff --git a/packages/websocket/test/test.js b/packages/websocket/test/test.js index 2ccf62f9b..9b04fcc52 100644 --- a/packages/websocket/test/test.js +++ b/packages/websocket/test/test.js @@ -1,3 +1,4 @@ +import { jest } from "@jest/globals"; import { EventEmitter } from "@xmpp/events"; import xml from "@xmpp/xml"; diff --git a/server/index.js b/server/index.js index 9484edce5..1eb570407 100644 --- a/server/index.js +++ b/server/index.js @@ -2,10 +2,8 @@ import { promisify } from "node:util"; import path from "node:path"; import fs from "node:fs/promises"; import child_process from "node:child_process"; -import net from "node:net"; -// eslint-disable-next-line n/no-extraneous-import -import { promise, delay } from "@xmpp/events"; +import { isPortOpen, promisePortOpen, promisePortClose } from "promise-port"; import { makeSelfSignedCertificate } from "../test/helpers.js"; @@ -19,33 +17,14 @@ const PID_PATH = path.join(DATA_PATH, "prosody.pid"); const PROSODY_PORT = 5347; const CFG_PATH = path.join(__dirname, "prosody.cfg.lua"); -function clean() { - return Promise.all( - ["prosody.err", "prosody.log", "prosody.pid"].map((file) => - fs.unlink(path.join(__dirname, file)), - ), - ).catch(() => {}); -} - -function isPortOpen() { - const sock = new net.Socket(); - sock.connect({ port: PROSODY_PORT }); - return promise(sock, "connect") - .then(() => { - sock.end(); - sock.destroy(); - return true; - }) - .catch(() => false); -} - -async function waitPortOpen() { - if (await isPortOpen()) { - return; - } - - await delay(1000); - return waitPortOpen(); +async function clean() { + try { + await Promise.all( + ["prosody.err", "prosody.log", "prosody.pid"].map((file) => + fs.unlink(path.join(__dirname, file)), + ), + ); + } catch {} } async function makeCertificate() { @@ -56,15 +35,6 @@ async function makeCertificate() { ]); } -async function waitPortClose() { - if (!(await isPortOpen())) { - return; - } - - await delay(1000); - return waitPortClose(); -} - async function kill(signal = "SIGTERM") { const pid = await getPid(); try { @@ -84,7 +54,7 @@ async function getPid() { } async function _start() { - const opening = waitPortOpen(); + const opening = promisePortOpen(PROSODY_PORT); makeCertificate(); @@ -100,17 +70,17 @@ async function _start() { } async function start() { - if (await isPortOpen()) return; + if (await isPortOpen(PROSODY_PORT)) return; await clean(); return _start(); } async function stop(signal) { - if (!(await isPortOpen())) { + if (!(await isPortOpen(PROSODY_PORT))) { return clean(); } - const closing = waitPortClose(); + const closing = promisePortClose(PROSODY_PORT); await kill(signal); return closing; } @@ -149,9 +119,6 @@ async function reset() { } export default { - isPortOpen, - waitPortClose, - waitPortOpen, getPid, start, stop, diff --git a/browser.test.js b/test/browser.js similarity index 87% rename from browser.test.js rename to test/browser.js index af4bb8905..4d213269e 100644 --- a/browser.test.js +++ b/test/browser.js @@ -3,9 +3,9 @@ import { readFileSync } from "node:fs"; import { JSDOM } from "jsdom"; -import { jid } from "./packages/client/index.js"; -import debug from "./packages/debug/index.js"; -import server from "./server/index.js"; +import { jid } from "../packages/client/index.js"; +import debug from "../packages/debug/index.js"; +import server from "../server/index.js"; const username = "client"; const password = "foobar";