summaryrefslogtreecommitdiff
path: root/cli/tests/testdata/run/websocketstream_test.ts
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2022-09-19 09:32:21 -0500
committerGitHub <noreply@github.com>2022-09-19 10:32:21 -0400
commit1464b756a4ef091ef97d1bf7340188ab5fe5492a (patch)
tree2eff346ccf5782c501460aec63a5028742066fa6 /cli/tests/testdata/run/websocketstream_test.ts
parent8d50c09c0db4e9b0644263cde3f7ff990ec75259 (diff)
refactor: move out test files from root testdata directory into sub directories (#15949)
Diffstat (limited to 'cli/tests/testdata/run/websocketstream_test.ts')
-rw-r--r--cli/tests/testdata/run/websocketstream_test.ts335
1 files changed, 335 insertions, 0 deletions
diff --git a/cli/tests/testdata/run/websocketstream_test.ts b/cli/tests/testdata/run/websocketstream_test.ts
new file mode 100644
index 000000000..74d8e5d9a
--- /dev/null
+++ b/cli/tests/testdata/run/websocketstream_test.ts
@@ -0,0 +1,335 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+
+import {
+ assert,
+ assertEquals,
+ assertNotEquals,
+ assertRejects,
+ assertThrows,
+ unreachable,
+} from "../../../../test_util/std/testing/asserts.ts";
+
+Deno.test("fragment", () => {
+ assertThrows(() => new WebSocketStream("ws://localhost:4242/#"));
+ assertThrows(() => new WebSocketStream("ws://localhost:4242/#foo"));
+});
+
+Deno.test("duplicate protocols", () => {
+ assertThrows(() =>
+ new WebSocketStream("ws://localhost:4242", {
+ protocols: ["foo", "foo"],
+ })
+ );
+});
+
+Deno.test("connect & close custom valid code", async () => {
+ const ws = new WebSocketStream("ws://localhost:4242");
+ await ws.connection;
+ ws.close({ code: 1000 });
+ await ws.closed;
+});
+
+Deno.test("connect & close custom invalid reason", async () => {
+ const ws = new WebSocketStream("ws://localhost:4242");
+ await ws.connection;
+ assertThrows(() => ws.close({ code: 1000, reason: "".padEnd(124, "o") }));
+ ws.close();
+ await ws.closed;
+});
+
+Deno.test("echo string", async () => {
+ const ws = new WebSocketStream("ws://localhost:4242");
+ const { readable, writable } = await ws.connection;
+ await writable.getWriter().write("foo");
+ const res = await readable.getReader().read();
+ assertEquals(res.value, "foo");
+ ws.close();
+ await ws.closed;
+});
+
+Deno.test("echo string tls", async () => {
+ const ws = new WebSocketStream("wss://localhost:4243");
+ const { readable, writable } = await ws.connection;
+ await writable.getWriter().write("foo");
+ const res = await readable.getReader().read();
+ assertEquals(res.value, "foo");
+ ws.close();
+ await ws.closed;
+});
+
+Deno.test("websocket error", async () => {
+ const ws = new WebSocketStream("wss://localhost:4242");
+ await Promise.all([
+ assertRejects(
+ () => ws.connection,
+ Deno.errors.UnexpectedEof,
+ "tls handshake eof",
+ ),
+ assertRejects(
+ () => ws.closed,
+ Deno.errors.UnexpectedEof,
+ "tls handshake eof",
+ ),
+ ]);
+});
+
+Deno.test("echo uint8array", async () => {
+ const ws = new WebSocketStream("ws://localhost:4242");
+ const { readable, writable } = await ws.connection;
+ const uint = new Uint8Array([102, 111, 111]);
+ await writable.getWriter().write(uint);
+ const res = await readable.getReader().read();
+ assertEquals(res.value, uint);
+ ws.close();
+ await ws.closed;
+});
+
+Deno.test("aborting immediately throws an AbortError", async () => {
+ const controller = new AbortController();
+ const wss = new WebSocketStream("ws://localhost:4242", {
+ signal: controller.signal,
+ });
+ controller.abort();
+ await assertRejects(
+ () => wss.connection,
+ (error: Error) => {
+ assert(error instanceof DOMException);
+ assertEquals(error.name, "AbortError");
+ },
+ );
+ await assertRejects(
+ () => wss.closed,
+ (error: Error) => {
+ assert(error instanceof DOMException);
+ assertEquals(error.name, "AbortError");
+ },
+ );
+});
+
+Deno.test("aborting immediately with a reason throws that reason", async () => {
+ const controller = new AbortController();
+ const wss = new WebSocketStream("ws://localhost:4242", {
+ signal: controller.signal,
+ });
+ const abortReason = new Error();
+ controller.abort(abortReason);
+ await assertRejects(
+ () => wss.connection,
+ (error: Error) => assertEquals(error, abortReason),
+ );
+ await assertRejects(
+ () => wss.closed,
+ (error: Error) => assertEquals(error, abortReason),
+ );
+});
+
+Deno.test("aborting immediately with a primitive as reason throws that primitive", async () => {
+ const controller = new AbortController();
+ const wss = new WebSocketStream("ws://localhost:4242", {
+ signal: controller.signal,
+ });
+ controller.abort("Some string");
+ await wss.connection.then(
+ () => unreachable(),
+ (e) => assertEquals(e, "Some string"),
+ );
+ await wss.closed.then(
+ () => unreachable(),
+ (e) => assertEquals(e, "Some string"),
+ );
+});
+
+Deno.test("headers", async () => {
+ const listener = Deno.listen({ port: 4512 });
+ const promise = (async () => {
+ const conn = await listener.accept();
+ const httpConn = Deno.serveHttp(conn);
+ const { request, respondWith } = (await httpConn.nextRequest())!;
+ assertEquals(request.headers.get("x-some-header"), "foo");
+ const { response, socket } = Deno.upgradeWebSocket(request);
+ socket.onopen = () => socket.close();
+ const p = new Promise<void>((resolve) => {
+ socket.onopen = () => socket.close();
+ socket.onclose = () => resolve();
+ });
+ await respondWith(response);
+ await p;
+ })();
+
+ const ws = new WebSocketStream("ws://localhost:4512", {
+ headers: [["x-some-header", "foo"]],
+ });
+ await ws.connection;
+ await promise;
+ await ws.closed;
+ listener.close();
+});
+
+Deno.test("forbidden headers", async () => {
+ const forbiddenHeaders = [
+ "sec-websocket-accept",
+ "sec-websocket-extensions",
+ "sec-websocket-key",
+ "sec-websocket-protocol",
+ "sec-websocket-version",
+ "upgrade",
+ "connection",
+ ];
+
+ const listener = Deno.listen({ port: 4512 });
+ const promise = (async () => {
+ const conn = await listener.accept();
+ const httpConn = Deno.serveHttp(conn);
+ const { request, respondWith } = (await httpConn.nextRequest())!;
+ for (const [key] of request.headers) {
+ assertNotEquals(key, "foo");
+ }
+ const { response, socket } = Deno.upgradeWebSocket(request);
+ const p = new Promise<void>((resolve) => {
+ socket.onopen = () => socket.close();
+ socket.onclose = () => resolve();
+ });
+ await respondWith(response);
+ await p;
+ })();
+
+ const ws = new WebSocketStream("ws://localhost:4512", {
+ headers: forbiddenHeaders.map((header) => [header, "foo"]),
+ });
+ await ws.connection;
+ await promise;
+ await ws.closed;
+ listener.close();
+});
+
+Deno.test("sync close with empty stream", async () => {
+ const listener = Deno.listen({ port: 4512 });
+ const promise = (async () => {
+ const conn = await listener.accept();
+ const httpConn = Deno.serveHttp(conn);
+ const { request, respondWith } = (await httpConn.nextRequest())!;
+ const { response, socket } = Deno.upgradeWebSocket(request);
+ const p = new Promise<void>((resolve) => {
+ socket.onopen = () => {
+ socket.send("first message");
+ socket.send("second message");
+ };
+ socket.onclose = () => resolve();
+ });
+ await respondWith(response);
+ await p;
+ })();
+
+ const ws = new WebSocketStream("ws://localhost:4512");
+ const { readable } = await ws.connection;
+ const reader = readable.getReader();
+ const firstMessage = await reader.read();
+ assertEquals(firstMessage.value, "first message");
+ const secondMessage = await reader.read();
+ assertEquals(secondMessage.value, "second message");
+ ws.close({ code: 1000 });
+ await ws.closed;
+ await promise;
+ listener.close();
+});
+
+Deno.test("sync close with unread messages in stream", async () => {
+ const listener = Deno.listen({ port: 4512 });
+ const promise = (async () => {
+ const conn = await listener.accept();
+ const httpConn = Deno.serveHttp(conn);
+ const { request, respondWith } = (await httpConn.nextRequest())!;
+ const { response, socket } = Deno.upgradeWebSocket(request);
+ const p = new Promise<void>((resolve) => {
+ socket.onopen = () => {
+ socket.send("first message");
+ socket.send("second message");
+ socket.send("third message");
+ socket.send("fourth message");
+ };
+ socket.onclose = () => resolve();
+ });
+ await respondWith(response);
+ await p;
+ })();
+
+ const ws = new WebSocketStream("ws://localhost:4512");
+ const { readable } = await ws.connection;
+ const reader = readable.getReader();
+ const firstMessage = await reader.read();
+ assertEquals(firstMessage.value, "first message");
+ const secondMessage = await reader.read();
+ assertEquals(secondMessage.value, "second message");
+ ws.close({ code: 1000 });
+ await ws.closed;
+ await promise;
+ listener.close();
+});
+
+Deno.test("async close with empty stream", async () => {
+ const listener = Deno.listen({ port: 4512 });
+ const promise = (async () => {
+ const conn = await listener.accept();
+ const httpConn = Deno.serveHttp(conn);
+ const { request, respondWith } = (await httpConn.nextRequest())!;
+ const { response, socket } = Deno.upgradeWebSocket(request);
+ const p = new Promise<void>((resolve) => {
+ socket.onopen = () => {
+ socket.send("first message");
+ socket.send("second message");
+ };
+ socket.onclose = () => resolve();
+ });
+ await respondWith(response);
+ await p;
+ })();
+
+ const ws = new WebSocketStream("ws://localhost:4512");
+ const { readable } = await ws.connection;
+ const reader = readable.getReader();
+ const firstMessage = await reader.read();
+ assertEquals(firstMessage.value, "first message");
+ const secondMessage = await reader.read();
+ assertEquals(secondMessage.value, "second message");
+ setTimeout(() => {
+ ws.close({ code: 1000 });
+ }, 0);
+ await ws.closed;
+ await promise;
+ listener.close();
+});
+
+Deno.test("async close with unread messages in stream", async () => {
+ const listener = Deno.listen({ port: 4512 });
+ const promise = (async () => {
+ const conn = await listener.accept();
+ const httpConn = Deno.serveHttp(conn);
+ const { request, respondWith } = (await httpConn.nextRequest())!;
+ const { response, socket } = Deno.upgradeWebSocket(request);
+ const p = new Promise<void>((resolve) => {
+ socket.onopen = () => {
+ socket.send("first message");
+ socket.send("second message");
+ socket.send("third message");
+ socket.send("fourth message");
+ };
+ socket.onclose = () => resolve();
+ });
+ await respondWith(response);
+ await p;
+ })();
+
+ const ws = new WebSocketStream("ws://localhost:4512");
+ const { readable } = await ws.connection;
+ const reader = readable.getReader();
+ const firstMessage = await reader.read();
+ assertEquals(firstMessage.value, "first message");
+ const secondMessage = await reader.read();
+ assertEquals(secondMessage.value, "second message");
+ setTimeout(() => {
+ ws.close({ code: 1000 });
+ }, 0);
+ await ws.closed;
+ await promise;
+ listener.close();
+});