From 2be0ffae194c320472235173b8a18ab6c6ef78d0 Mon Sep 17 00:00:00 2001 From: Harley Adams Date: Mon, 29 Jul 2019 11:07:42 -0700 Subject: [PATCH] Add eachHttpClient test option to get basic coverage for new fetchhttpclient --- .../clients/ts/FunctionalTests/ts/Common.ts | 11 +- .../ts/FunctionalTests/ts/ConnectionTests.ts | 205 +++++++++--------- src/SignalR/clients/ts/signalr/src/index.ts | 2 + 3 files changed, 117 insertions(+), 101 deletions(-) diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts index 2bb33c1c11..15c03ef6d0 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts @@ -1,8 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -import { HttpTransportType, IHubProtocol, JsonHubProtocol } from "@microsoft/signalr"; +import { DefaultHttpClient, FetchHttpClient, HttpClient, HttpTransportType, IHubProtocol, JsonHubProtocol, XhrHttpClient } from "@microsoft/signalr"; import { MessagePackHubProtocol } from "@microsoft/signalr-protocol-msgpack"; +import { TestLogger } from "./TestLogger"; // On slower CI machines, these tests sometimes take longer than 5s jasmine.DEFAULT_TIMEOUT_INTERVAL = 20 * 1000; @@ -100,3 +101,11 @@ export function eachTransportAndProtocol(action: (transport: HttpTransportType, export function getGlobalObject(): any { return typeof window !== "undefined" ? window : global; } + +export function eachHttpClient(action: (transport: HttpClient) => void) { + const httpClients: HttpClient[] = [new FetchHttpClient(TestLogger.instance), new XhrHttpClient(TestLogger.instance), new DefaultHttpClient(TestLogger.instance)]; + + return httpClients.forEach((t) => { + return action(t); + }); +} diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts index 7760294123..9d60a38ff6 100644 --- a/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts +++ b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts @@ -5,7 +5,7 @@ // tslint:disable:no-floating-promises import { HttpTransportType, IHttpConnectionOptions, TransferFormat } from "@microsoft/signalr"; -import { eachTransport, ECHOENDPOINT_URL } from "./Common"; +import { eachHttpClient, eachTransport, ECHOENDPOINT_URL } from "./Common"; import { TestLogger } from "./TestLogger"; // We want to continue testing HttpConnection, but we don't export it anymore. So just pull it in directly from the source file. @@ -44,109 +44,114 @@ describe("connection", () => { }); eachTransport((transportType) => { - describe(`over ${HttpTransportType[transportType]}`, () => { - it("can send and receive messages", (done) => { - const message = "Hello World!"; - // the url should be resolved relative to the document.location.host - // and the leading '/' should be automatically added to the url - const connection = new HttpConnection(ECHOENDPOINT_URL, { - ...commonOptions, - transport: transportType, - }); + eachHttpClient((httpClient) => { + describe(`over ${HttpTransportType[transportType]}`, () => { + it("can send and receive messages", (done) => { + const message = "Hello World!"; + // the url should be resolved relative to the document.location.host + // and the leading '/' should be automatically added to the url + const connection = new HttpConnection(ECHOENDPOINT_URL, { + ...commonOptions, + httpClient, + transport: transportType, + }); - connection.onreceive = (data: any) => { - if (data === message) { - connection.stop(); - } - }; - - connection.onclose = (error: any) => { - expect(error).toBeUndefined(); - done(); - }; - - connection.start(TransferFormat.Text).then(() => { - connection.send(message); - }).catch((e: any) => { - fail(e); - done(); - }); - }); - - it("does not log content of messages sent or received by default", (done) => { - TestLogger.saveLogsAndReset(); - const message = "Hello World!"; - - // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is not set. - const connection = new HttpConnection(ECHOENDPOINT_URL, { - logger: TestLogger.instance, - transport: transportType, - }); - - connection.onreceive = (data: any) => { - if (data === message) { - connection.stop(); - } - }; - - // @ts-ignore: We don't use the error parameter intentionally. - connection.onclose = (error) => { - // Search the logs for the message content - expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); - // @ts-ignore: We don't use the _ or __ parameters intentionally. - for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { - expect(logMessage).not.toContain(message); - } - done(); - }; - - connection.start(TransferFormat.Text).then(() => { - connection.send(message); - }).catch((e) => { - fail(e); - done(); - }); - }); - - it("does log content of messages sent or received when enabled", (done) => { - TestLogger.saveLogsAndReset(); - const message = "Hello World!"; - - // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is set to true (even if commonOptions changes). - const connection = new HttpConnection(ECHOENDPOINT_URL, { - logMessageContent: true, - logger: TestLogger.instance, - transport: transportType, - }); - - connection.onreceive = (data: any) => { - if (data === message) { - connection.stop(); - } - }; - - // @ts-ignore: We don't use the error parameter intentionally. - connection.onclose = (error) => { - // Search the logs for the message content - let matches = 0; - expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); - // @ts-ignore: We don't use the _ or __ parameters intentionally. - for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { - if (logMessage.indexOf(message) !== -1) { - matches += 1; + connection.onreceive = (data: any) => { + if (data === message) { + connection.stop(); } - } + }; - // One match for send, one for receive. - expect(matches).toEqual(2); - done(); - }; + connection.onclose = (error: any) => { + expect(error).toBeUndefined(); + done(); + }; - connection.start(TransferFormat.Text).then(() => { - connection.send(message); - }).catch((e: any) => { - fail(e); - done(); + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e: any) => { + fail(e); + done(); + }); + }); + + it("does not log content of messages sent or received by default", (done) => { + TestLogger.saveLogsAndReset(); + const message = "Hello World!"; + + // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is not set. + const connection = new HttpConnection(ECHOENDPOINT_URL, { + httpClient, + logger: TestLogger.instance, + transport: transportType, + }); + + connection.onreceive = (data: any) => { + if (data === message) { + connection.stop(); + } + }; + + // @ts-ignore: We don't use the error parameter intentionally. + connection.onclose = (error) => { + // Search the logs for the message content + expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); + // @ts-ignore: We don't use the _ or __ parameters intentionally. + for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { + expect(logMessage).not.toContain(message); + } + done(); + }; + + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e) => { + fail(e); + done(); + }); + }); + + it("does log content of messages sent or received when enabled", (done) => { + TestLogger.saveLogsAndReset(); + const message = "Hello World!"; + + // DON'T use commonOptions because we want to specifically test the scenario where logMessageContent is set to true (even if commonOptions changes). + const connection = new HttpConnection(ECHOENDPOINT_URL, { + httpClient, + logMessageContent: true, + logger: TestLogger.instance, + transport: transportType, + }); + + connection.onreceive = (data: any) => { + if (data === message) { + connection.stop(); + } + }; + + // @ts-ignore: We don't use the error parameter intentionally. + connection.onclose = (error) => { + // Search the logs for the message content + let matches = 0; + expect(TestLogger.instance.currentLog.messages.length).toBeGreaterThan(0); + // @ts-ignore: We don't use the _ or __ parameters intentionally. + for (const [_, __, logMessage] of TestLogger.instance.currentLog.messages) { + if (logMessage.indexOf(message) !== -1) { + matches += 1; + } + } + + // One match for send, one for receive. + expect(matches).toEqual(2); + done(); + }; + + connection.start(TransferFormat.Text).then(() => { + connection.send(message); + }).catch((e: any) => { + fail(e); + done(); + }); }); }); }); diff --git a/src/SignalR/clients/ts/signalr/src/index.ts b/src/SignalR/clients/ts/signalr/src/index.ts index dc2086c661..8d93b7530f 100644 --- a/src/SignalR/clients/ts/signalr/src/index.ts +++ b/src/SignalR/clients/ts/signalr/src/index.ts @@ -10,6 +10,7 @@ export { AbortSignal } from "./AbortController"; export { AbortError, HttpError, TimeoutError } from "./Errors"; export { HttpClient, HttpRequest, HttpResponse } from "./HttpClient"; export { DefaultHttpClient } from "./DefaultHttpClient"; +export { FetchHttpClient } from "./FetchHttpClient"; export { IHttpConnectionOptions } from "./IHttpConnectionOptions"; export { HubConnection, HubConnectionState } from "./HubConnection"; export { HubConnectionBuilder } from "./HubConnectionBuilder"; @@ -22,3 +23,4 @@ export { NullLogger } from "./Loggers"; export { JsonHubProtocol } from "./JsonHubProtocol"; export { Subject } from "./Subject"; export { IRetryPolicy, RetryContext } from "./IRetryPolicy"; +export { XhrHttpClient } from "./XhrHttpClient";