Files
upstream-hocuspocus/tests/server/onConnect.ts
upstream-mirror e0c588ca1c
Some checks failed
build / lint (22) (push) Failing after 17s
build / test (22) (push) Failing after 8s
build / lint (23) (push) Failing after 2s
build / build (22) (push) Has been skipped
build / build (23) (push) Has been skipped
build / test (23) (push) Failing after 4s
docsearch / docsearch (push) Failing after 1s
snapshot of https://github.com/ueberdosis/hocuspocus.git @ cf3cfa355b4d3bb61c6b6c80071f71783e32470e (2026-09-15)
2026-09-15 17:21:35 +05:00

331 lines
7.0 KiB
TypeScript

import type { HocuspocusProvider } from "@hocuspocus/provider";
import test from "ava";
import { newHocuspocus, newHocuspocusProvider, sleep } from "../utils/index.ts";
test("executes the onConnect callback", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect() {
t.pass();
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("refuses connection when an error is thrown", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect() {
throw new Error();
},
});
newHocuspocusProvider(t, server, {
onAuthenticationFailed() {
t.pass();
resolve("done");
},
});
});
});
test("executes the onConnect callback from an extension", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t);
class CustomExtension {
async onConnect() {
t.pass();
resolve("done");
}
}
server.configure({
extensions: [new CustomExtension()],
});
newHocuspocusProvider(t, server);
});
});
test("has the document name", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ documentName }) {
t.is(documentName, "hocuspocus-test");
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("sets the provider to readOnly", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ connectionConfig }) {
connectionConfig.readOnly = true;
},
});
newHocuspocusProvider(t, server, {
onSynced() {
for (const connection of server.documents.get("hocuspocus-test")?.connections.keys() ?? []) {
t.is(connection.readOnly, true);
}
resolve("done");
},
});
});
});
const weirdDocumentNames = [
"not-weird",
"äöü",
"<>{}|^ß",
"with space",
"with/slash",
"with\backslash",
"a-very-long-document-name-which-should-not-make-any-problems-at-all",
"🌟",
":",
"—",
"漢",
"triple space",
"*",
];
weirdDocumentNames.forEach((weirdDocumentName) => {
test(`encodes weird document names: "${weirdDocumentName}"`, async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ documentName }) {
t.is(documentName, weirdDocumentName);
resolve("done");
},
});
newHocuspocusProvider(t, server, {
name: weirdDocumentName,
});
});
});
});
test("rejects empty document name via WebSocket", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t);
newHocuspocusProvider(t, server, {
name: "",
onAuthenticationFailed() {
t.is(server.getDocumentsCount(), 0);
t.pass();
resolve("done");
},
});
});
});
test("rejects whitespace-only document name via WebSocket", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t);
newHocuspocusProvider(t, server, {
name: " ",
onAuthenticationFailed() {
t.is(server.getDocumentsCount(), 0);
t.pass();
resolve("done");
},
});
});
});
test("stops when the onConnect hook throws an Error", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
onConnect() {
throw new Error();
},
// MUST NOT BE CALLED
async onLoadDocument() {
t.fail(
"WARNING: When onConnect fails onLoadDocument must not be called.",
);
},
});
newHocuspocusProvider(t, server, {
onAuthenticationFailed() {
t.pass();
resolve("done");
},
});
});
});
test("stops when the onConnect hook returns a rejecting promise", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
onConnect() {
return Promise.reject();
},
// MUST NOT BE CALLED
async onLoadDocument() {
t.fail(
"WARNING: When onConnect fails onLoadDocument must not be called.",
);
},
});
newHocuspocusProvider(t, server, {
onAuthenticationFailed() {
t.pass();
resolve("done");
},
});
});
});
test("has the request headers", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ requestHeaders }) {
t.is(requestHeaders.get("connection") !== null, true);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("has the whole request", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ request }) {
t.is(new URL(request.url).pathname, "/");
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("has the socketId", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ socketId }) {
t.is(socketId !== undefined, true);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("has the server instance", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ instance }) {
t.is(instance, server);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("defaults to readOnly = false", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ connectionConfig }) {
t.is(connectionConfig.readOnly, false);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("cleans up correctly when provider disconnects during onLoadDocument", async (t) => {
await new Promise(async (resolve) => {
// eslint-disable-next-line prefer-const
let provider: HocuspocusProvider;
const server = await newHocuspocus(t, {
onLoadDocument: async () => {
provider.configuration.websocketProvider.disconnect();
provider.disconnect();
// pretent we loaded data from async source
await sleep(100);
},
});
provider = newHocuspocusProvider(t, server, {
name: "super-unique-name",
async onDisconnect() {
await sleep(100);
t.is(
server.documents.get("super-unique-name"),
undefined,
"no documents",
);
resolve("done");
},
});
});
});
test("the connections count is correct", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async connected() {
t.is(server.getConnectionsCount(), 1);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("has connection.readOnly", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ connectionConfig }) {
t.is(connectionConfig.readOnly, false);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});
test("has the request", async (t) => {
await new Promise(async (resolve) => {
const server = await newHocuspocus(t, {
async onConnect({ request }) {
t.truthy(request.url);
resolve("done");
},
});
newHocuspocusProvider(t, server);
});
});