Add VerifyLogger to JS tests (#2472)
This commit is contained in:
parent
7317762b29
commit
cb8264321d
|
|
@ -1,6 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
import { EOL } from "os";
|
||||||
|
import { ILogger, LogLevel } from "../src/ILogger";
|
||||||
import { HttpTransportType } from "../src/ITransport";
|
import { HttpTransportType } from "../src/ITransport";
|
||||||
|
|
||||||
export function eachTransport(action: (transport: HttpTransportType) => void) {
|
export function eachTransport(action: (transport: HttpTransportType) => void) {
|
||||||
|
|
@ -21,3 +23,38 @@ export function eachEndpointUrl(action: (givenUrl: string, expectedUrl: string)
|
||||||
|
|
||||||
urls.forEach((t) => action(t[0], t[1]));
|
urls.forEach((t) => action(t[0], t[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ErrorMatchFunction = (error: string) => boolean;
|
||||||
|
|
||||||
|
export class VerifyLogger implements ILogger {
|
||||||
|
public unexpectedErrors: string[];
|
||||||
|
private expectedErrors: ErrorMatchFunction[];
|
||||||
|
|
||||||
|
public constructor(...expectedErrors: Array<RegExp | string | ErrorMatchFunction>) {
|
||||||
|
this.unexpectedErrors = [];
|
||||||
|
this.expectedErrors = [];
|
||||||
|
expectedErrors.forEach((element) => {
|
||||||
|
if (element instanceof RegExp) {
|
||||||
|
this.expectedErrors.push((e) => element.test(e));
|
||||||
|
} else if (typeof element === "string") {
|
||||||
|
this.expectedErrors.push((e) => element === e);
|
||||||
|
} else {
|
||||||
|
this.expectedErrors.push(element);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async run(fn: (logger: VerifyLogger) => Promise<void>, ...expectedErrors: Array<RegExp | string | ErrorMatchFunction>): Promise<void> {
|
||||||
|
const logger = new VerifyLogger(...expectedErrors);
|
||||||
|
await fn(logger);
|
||||||
|
expect(logger.unexpectedErrors.join(EOL)).toBe("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public log(logLevel: LogLevel, message: string): void {
|
||||||
|
if (logLevel >= LogLevel.Error) {
|
||||||
|
if (!this.expectedErrors.some((fn) => fn(message))) {
|
||||||
|
this.unexpectedErrors.push(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -10,6 +10,7 @@ import { ILogger, LogLevel } from "../src/ILogger";
|
||||||
import { HttpTransportType, TransferFormat } from "../src/ITransport";
|
import { HttpTransportType, TransferFormat } from "../src/ITransport";
|
||||||
import { NullLogger } from "../src/Loggers";
|
import { NullLogger } from "../src/Loggers";
|
||||||
|
|
||||||
|
import { VerifyLogger } from "./Common";
|
||||||
import { TestHttpClient } from "./TestHttpClient";
|
import { TestHttpClient } from "./TestHttpClient";
|
||||||
import { PromiseSource } from "./Utils";
|
import { PromiseSource } from "./Utils";
|
||||||
|
|
||||||
|
|
@ -43,29 +44,32 @@ describe("HubConnectionBuilder", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("builds HubConnection with HttpConnection using provided URL", async () => {
|
it("builds HubConnection with HttpConnection using provided URL", async () => {
|
||||||
const pollSent = new PromiseSource<HttpRequest>();
|
await VerifyLogger.run(async (logger) => {
|
||||||
const pollCompleted = new PromiseSource<HttpResponse>();
|
const pollSent = new PromiseSource<HttpRequest>();
|
||||||
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
const pollCompleted = new PromiseSource<HttpResponse>();
|
||||||
.on("POST", "http://example.com?id=abc123", (req) => {
|
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
||||||
// Respond from the poll with the handshake response
|
.on("POST", "http://example.com?id=abc123", (req) => {
|
||||||
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
// Respond from the poll with the handshake response
|
||||||
return new HttpResponse(202);
|
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
||||||
});
|
return new HttpResponse(202);
|
||||||
const connection = createConnectionBuilder()
|
});
|
||||||
.withUrl("http://example.com", {
|
const connection = createConnectionBuilder()
|
||||||
...commonHttpOptions,
|
.withUrl("http://example.com", {
|
||||||
httpClient: testClient,
|
...commonHttpOptions,
|
||||||
})
|
httpClient: testClient,
|
||||||
.build();
|
logger,
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
// Start the connection
|
// Start the connection
|
||||||
const closed = makeClosedPromise(connection);
|
const closed = makeClosedPromise(connection);
|
||||||
await connection.start();
|
await connection.start();
|
||||||
|
|
||||||
const pollRequest = await pollSent.promise;
|
const pollRequest = await pollSent.promise;
|
||||||
expect(pollRequest.url).toMatch(/http:\/\/example.com\?id=abc123.*/);
|
expect(pollRequest.url).toMatch(/http:\/\/example.com\?id=abc123.*/);
|
||||||
|
|
||||||
await closed;
|
await closed;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can configure transport type", async () => {
|
it("can configure transport type", async () => {
|
||||||
|
|
@ -78,35 +82,38 @@ describe("HubConnectionBuilder", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can configure hub protocol", async () => {
|
it("can configure hub protocol", async () => {
|
||||||
const protocol = new TestProtocol();
|
await VerifyLogger.run(async (logger) => {
|
||||||
|
const protocol = new TestProtocol();
|
||||||
|
|
||||||
const pollSent = new PromiseSource<HttpRequest>();
|
const pollSent = new PromiseSource<HttpRequest>();
|
||||||
const pollCompleted = new PromiseSource<HttpResponse>();
|
const pollCompleted = new PromiseSource<HttpResponse>();
|
||||||
const negotiateReceived = new PromiseSource<HttpRequest>();
|
const negotiateReceived = new PromiseSource<HttpRequest>();
|
||||||
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
||||||
.on("POST", "http://example.com?id=abc123", (req) => {
|
.on("POST", "http://example.com?id=abc123", (req) => {
|
||||||
// Respond from the poll with the handshake response
|
// Respond from the poll with the handshake response
|
||||||
negotiateReceived.resolve(req);
|
negotiateReceived.resolve(req);
|
||||||
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
||||||
return new HttpResponse(202);
|
return new HttpResponse(202);
|
||||||
});
|
});
|
||||||
|
|
||||||
const connection = createConnectionBuilder()
|
const connection = createConnectionBuilder()
|
||||||
.withUrl("http://example.com", {
|
.withUrl("http://example.com", {
|
||||||
...commonHttpOptions,
|
...commonHttpOptions,
|
||||||
httpClient: testClient,
|
httpClient: testClient,
|
||||||
})
|
logger,
|
||||||
.withHubProtocol(protocol)
|
})
|
||||||
.build();
|
.withHubProtocol(protocol)
|
||||||
|
.build();
|
||||||
|
|
||||||
// Start the connection
|
// Start the connection
|
||||||
const closed = makeClosedPromise(connection);
|
const closed = makeClosedPromise(connection);
|
||||||
await connection.start();
|
await connection.start();
|
||||||
|
|
||||||
const negotiateRequest = await negotiateReceived.promise;
|
const negotiateRequest = await negotiateReceived.promise;
|
||||||
expect(negotiateRequest.content).toBe(`{"protocol":"${protocol.name}","version":1}\x1E`);
|
expect(negotiateRequest.content).toBe(`{"protocol":"${protocol.name}","version":1}\x1E`);
|
||||||
|
|
||||||
await closed;
|
await closed;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("allows logger to be replaced", async () => {
|
it("allows logger to be replaced", async () => {
|
||||||
|
|
|
||||||
|
|
@ -3,63 +3,71 @@
|
||||||
|
|
||||||
import { CompletionMessage, InvocationMessage, MessageType, StreamItemMessage } from "../src/IHubProtocol";
|
import { CompletionMessage, InvocationMessage, MessageType, StreamItemMessage } from "../src/IHubProtocol";
|
||||||
import { JsonHubProtocol } from "../src/JsonHubProtocol";
|
import { JsonHubProtocol } from "../src/JsonHubProtocol";
|
||||||
import { NullLogger } from "../src/Loggers";
|
|
||||||
import { TextMessageFormat } from "../src/TextMessageFormat";
|
import { TextMessageFormat } from "../src/TextMessageFormat";
|
||||||
|
import { VerifyLogger } from "./Common";
|
||||||
|
|
||||||
describe("JsonHubProtocol", () => {
|
describe("JsonHubProtocol", () => {
|
||||||
it("can write/read non-blocking Invocation message", () => {
|
it("can write/read non-blocking Invocation message", async () => {
|
||||||
const invocation = {
|
await VerifyLogger.run(async (logger) => {
|
||||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
const invocation = {
|
||||||
headers: {},
|
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||||
target: "myMethod",
|
headers: {},
|
||||||
type: MessageType.Invocation,
|
target: "myMethod",
|
||||||
} as InvocationMessage;
|
type: MessageType.Invocation,
|
||||||
|
} as InvocationMessage;
|
||||||
|
|
||||||
const protocol = new JsonHubProtocol();
|
const protocol = new JsonHubProtocol();
|
||||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||||
expect(parsedMessages).toEqual([invocation]);
|
expect(parsedMessages).toEqual([invocation]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can read Invocation message with Date argument", () => {
|
it("can read Invocation message with Date argument", async () => {
|
||||||
const invocation = {
|
await VerifyLogger.run(async (logger) => {
|
||||||
arguments: [Date.UTC(2018, 1, 1, 12, 34, 56)],
|
const invocation = {
|
||||||
headers: {},
|
arguments: [Date.UTC(2018, 1, 1, 12, 34, 56)],
|
||||||
target: "mymethod",
|
headers: {},
|
||||||
type: MessageType.Invocation,
|
target: "mymethod",
|
||||||
} as InvocationMessage;
|
type: MessageType.Invocation,
|
||||||
|
} as InvocationMessage;
|
||||||
|
|
||||||
const protocol = new JsonHubProtocol();
|
const protocol = new JsonHubProtocol();
|
||||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||||
expect(parsedMessages).toEqual([invocation]);
|
expect(parsedMessages).toEqual([invocation]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can write/read Invocation message with headers", () => {
|
it("can write/read Invocation message with headers", async () => {
|
||||||
const invocation = {
|
await VerifyLogger.run(async (logger) => {
|
||||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
const invocation = {
|
||||||
headers: {
|
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||||
foo: "bar",
|
headers: {
|
||||||
},
|
foo: "bar",
|
||||||
target: "myMethod",
|
},
|
||||||
type: MessageType.Invocation,
|
target: "myMethod",
|
||||||
} as InvocationMessage;
|
type: MessageType.Invocation,
|
||||||
|
} as InvocationMessage;
|
||||||
|
|
||||||
const protocol = new JsonHubProtocol();
|
const protocol = new JsonHubProtocol();
|
||||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||||
expect(parsedMessages).toEqual([invocation]);
|
expect(parsedMessages).toEqual([invocation]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can write/read Invocation message", () => {
|
it("can write/read Invocation message", async () => {
|
||||||
const invocation = {
|
await VerifyLogger.run(async (logger) => {
|
||||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
const invocation = {
|
||||||
headers: {},
|
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||||
invocationId: "123",
|
headers: {},
|
||||||
target: "myMethod",
|
invocationId: "123",
|
||||||
type: MessageType.Invocation,
|
target: "myMethod",
|
||||||
} as InvocationMessage;
|
type: MessageType.Invocation,
|
||||||
|
} as InvocationMessage;
|
||||||
|
|
||||||
const protocol = new JsonHubProtocol();
|
const protocol = new JsonHubProtocol();
|
||||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||||
expect(parsedMessages).toEqual([invocation]);
|
expect(parsedMessages).toEqual([invocation]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
([
|
([
|
||||||
|
|
@ -101,9 +109,11 @@ describe("JsonHubProtocol", () => {
|
||||||
type: MessageType.Completion,
|
type: MessageType.Completion,
|
||||||
} as CompletionMessage],
|
} as CompletionMessage],
|
||||||
] as Array<[string, CompletionMessage]>).forEach(([payload, expectedMessage]) =>
|
] as Array<[string, CompletionMessage]>).forEach(([payload, expectedMessage]) =>
|
||||||
it("can read Completion message", () => {
|
it("can read Completion message", async () => {
|
||||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
await VerifyLogger.run(async (logger) => {
|
||||||
expect(messages).toEqual([expectedMessage]);
|
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||||
|
expect(messages).toEqual([expectedMessage]);
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
([
|
([
|
||||||
|
|
@ -122,9 +132,11 @@ describe("JsonHubProtocol", () => {
|
||||||
type: MessageType.StreamItem,
|
type: MessageType.StreamItem,
|
||||||
} as StreamItemMessage],
|
} as StreamItemMessage],
|
||||||
] as Array<[string, StreamItemMessage]>).forEach(([payload, expectedMessage]) =>
|
] as Array<[string, StreamItemMessage]>).forEach(([payload, expectedMessage]) =>
|
||||||
it("can read StreamItem message", () => {
|
it("can read StreamItem message", async () => {
|
||||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
await VerifyLogger.run(async (logger) => {
|
||||||
expect(messages).toEqual([expectedMessage]);
|
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||||
|
expect(messages).toEqual([expectedMessage]);
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
([
|
([
|
||||||
|
|
@ -138,9 +150,11 @@ describe("JsonHubProtocol", () => {
|
||||||
type: MessageType.StreamItem,
|
type: MessageType.StreamItem,
|
||||||
} as StreamItemMessage],
|
} as StreamItemMessage],
|
||||||
] as Array<[string, StreamItemMessage]>).forEach(([payload, expectedMessage]) =>
|
] as Array<[string, StreamItemMessage]>).forEach(([payload, expectedMessage]) =>
|
||||||
it("can read message with headers", () => {
|
it("can read message with headers", async () => {
|
||||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
await VerifyLogger.run(async (logger) => {
|
||||||
expect(messages).toEqual([expectedMessage]);
|
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||||
|
expect(messages).toEqual([expectedMessage]);
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
([
|
([
|
||||||
|
|
@ -155,37 +169,43 @@ describe("JsonHubProtocol", () => {
|
||||||
["Completion message with result and error", `{"type":3,"invocationId":"1","result":2,"error":"error"}${TextMessageFormat.RecordSeparator}`, "Invalid payload for Completion message."],
|
["Completion message with result and error", `{"type":3,"invocationId":"1","result":2,"error":"error"}${TextMessageFormat.RecordSeparator}`, "Invalid payload for Completion message."],
|
||||||
["Completion message with non-string error", `{"type":3,"invocationId":"1","error":21}${TextMessageFormat.RecordSeparator}`, "Invalid payload for Completion message."],
|
["Completion message with non-string error", `{"type":3,"invocationId":"1","error":21}${TextMessageFormat.RecordSeparator}`, "Invalid payload for Completion message."],
|
||||||
] as Array<[string, string, string]>).forEach(([name, payload, expectedError]) =>
|
] as Array<[string, string, string]>).forEach(([name, payload, expectedError]) =>
|
||||||
it("throws for " + name, () => {
|
it("throws for " + name, async () => {
|
||||||
expect(() => new JsonHubProtocol().parseMessages(payload, NullLogger.instance))
|
await VerifyLogger.run(async (logger) => {
|
||||||
.toThrow(expectedError);
|
expect(() => new JsonHubProtocol().parseMessages(payload, logger))
|
||||||
|
.toThrow(expectedError);
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("can read multiple messages", () => {
|
it("can read multiple messages", async () => {
|
||||||
const payload = `{"type":2, "invocationId": "abc", "headers": {}, "item": 8}${TextMessageFormat.RecordSeparator}{"type":3, "invocationId": "abc", "headers": {}, "result": "OK"}${TextMessageFormat.RecordSeparator}`;
|
await VerifyLogger.run(async (logger) => {
|
||||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
const payload = `{"type":2, "invocationId": "abc", "headers": {}, "item": 8}${TextMessageFormat.RecordSeparator}{"type":3, "invocationId": "abc", "headers": {}, "result": "OK"}${TextMessageFormat.RecordSeparator}`;
|
||||||
expect(messages).toEqual([
|
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||||
{
|
expect(messages).toEqual([
|
||||||
headers: {},
|
{
|
||||||
invocationId: "abc",
|
headers: {},
|
||||||
item: 8,
|
invocationId: "abc",
|
||||||
type: MessageType.StreamItem,
|
item: 8,
|
||||||
} as StreamItemMessage,
|
type: MessageType.StreamItem,
|
||||||
{
|
} as StreamItemMessage,
|
||||||
headers: {},
|
{
|
||||||
invocationId: "abc",
|
headers: {},
|
||||||
result: "OK",
|
invocationId: "abc",
|
||||||
type: MessageType.Completion,
|
result: "OK",
|
||||||
} as CompletionMessage,
|
type: MessageType.Completion,
|
||||||
]);
|
} as CompletionMessage,
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can read ping message", () => {
|
it("can read ping message", async () => {
|
||||||
const payload = `{"type":6}${TextMessageFormat.RecordSeparator}`;
|
await VerifyLogger.run(async (logger) => {
|
||||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
const payload = `{"type":6}${TextMessageFormat.RecordSeparator}`;
|
||||||
expect(messages).toEqual([
|
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||||
{
|
expect(messages).toEqual([
|
||||||
type: MessageType.Ping,
|
{
|
||||||
},
|
type: MessageType.Ping,
|
||||||
]);
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,47 +3,56 @@
|
||||||
|
|
||||||
import { HttpResponse } from "../src/HttpClient";
|
import { HttpResponse } from "../src/HttpClient";
|
||||||
import { TransferFormat } from "../src/ITransport";
|
import { TransferFormat } from "../src/ITransport";
|
||||||
import { NullLogger } from "../src/Loggers";
|
|
||||||
import { LongPollingTransport } from "../src/LongPollingTransport";
|
import { LongPollingTransport } from "../src/LongPollingTransport";
|
||||||
|
|
||||||
|
import { VerifyLogger } from "./Common";
|
||||||
import { TestHttpClient } from "./TestHttpClient";
|
import { TestHttpClient } from "./TestHttpClient";
|
||||||
import { PromiseSource, SyncPoint } from "./Utils";
|
import { PromiseSource, SyncPoint } from "./Utils";
|
||||||
|
|
||||||
describe("LongPollingTransport", () => {
|
describe("LongPollingTransport", () => {
|
||||||
it("shuts down polling by aborting in-progress request", async () => {
|
it("shuts down polling by aborting in-progress request", async () => {
|
||||||
let firstPoll = true;
|
await VerifyLogger.run(async (logger) => {
|
||||||
const pollCompleted = new PromiseSource();
|
let firstPoll = true;
|
||||||
const client = new TestHttpClient()
|
const pollCompleted = new PromiseSource();
|
||||||
.on("GET", async (r) => {
|
const client = new TestHttpClient()
|
||||||
if (firstPoll) {
|
.on("GET", async (r) => {
|
||||||
firstPoll = false;
|
if (firstPoll) {
|
||||||
return new HttpResponse(200);
|
firstPoll = false;
|
||||||
} else {
|
return new HttpResponse(200);
|
||||||
// Turn 'onabort' into a promise.
|
} else {
|
||||||
const abort = new Promise((resolve, reject) => r.abortSignal!.onabort = resolve);
|
// Turn 'onabort' into a promise.
|
||||||
await abort;
|
const abort = new Promise((resolve, reject) => {
|
||||||
|
if (r.abortSignal!.aborted) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
r.abortSignal!.onabort = resolve;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await abort;
|
||||||
|
|
||||||
// Signal that the poll has completed.
|
// Signal that the poll has completed.
|
||||||
pollCompleted.resolve();
|
pollCompleted.resolve();
|
||||||
|
|
||||||
return new HttpResponse(200);
|
return new HttpResponse(200);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("DELETE", () => new HttpResponse(202));
|
.on("DELETE", () => new HttpResponse(202));
|
||||||
const transport = new LongPollingTransport(client, undefined, NullLogger.instance, false);
|
const transport = new LongPollingTransport(client, undefined, logger, false);
|
||||||
|
|
||||||
await transport.connect("http://example.com", TransferFormat.Text);
|
await transport.connect("http://example.com", TransferFormat.Text);
|
||||||
const stopPromise = transport.stop();
|
const stopPromise = transport.stop();
|
||||||
|
|
||||||
await pollCompleted.promise;
|
await pollCompleted.promise;
|
||||||
|
|
||||||
await stopPromise;
|
await stopPromise;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("204 server response stops polling and raises onClose", async () => {
|
it("204 server response stops polling and raises onClose", async () => {
|
||||||
let firstPoll = true;
|
await VerifyLogger.run(async (logger) => {
|
||||||
const client = new TestHttpClient()
|
let firstPoll = true;
|
||||||
.on("GET", async () => {
|
const client = new TestHttpClient()
|
||||||
|
.on("GET", async () => {
|
||||||
if (firstPoll) {
|
if (firstPoll) {
|
||||||
firstPoll = false;
|
firstPoll = false;
|
||||||
return new HttpResponse(200);
|
return new HttpResponse(200);
|
||||||
|
|
@ -52,59 +61,62 @@ describe("LongPollingTransport", () => {
|
||||||
return new HttpResponse(204);
|
return new HttpResponse(204);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const transport = new LongPollingTransport(client, undefined, NullLogger.instance, false);
|
const transport = new LongPollingTransport(client, undefined, logger, false);
|
||||||
|
|
||||||
const stopPromise = makeClosedPromise(transport);
|
const stopPromise = makeClosedPromise(transport);
|
||||||
|
|
||||||
await transport.connect("http://example.com", TransferFormat.Text);
|
await transport.connect("http://example.com", TransferFormat.Text);
|
||||||
|
|
||||||
// Close will be called on transport because of 204 result from polling
|
// Close will be called on transport because of 204 result from polling
|
||||||
await stopPromise;
|
await stopPromise;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends DELETE on stop after polling has finished", async () => {
|
it("sends DELETE on stop after polling has finished", async () => {
|
||||||
let firstPoll = true;
|
await VerifyLogger.run(async (logger) => {
|
||||||
let deleteSent = false;
|
let firstPoll = true;
|
||||||
const pollingPromiseSource = new PromiseSource();
|
let deleteSent = false;
|
||||||
const deleteSyncPoint = new SyncPoint();
|
const pollingPromiseSource = new PromiseSource();
|
||||||
const httpClient = new TestHttpClient()
|
const deleteSyncPoint = new SyncPoint();
|
||||||
.on("GET", async (r) => {
|
const httpClient = new TestHttpClient()
|
||||||
if (firstPoll) {
|
.on("GET", async (r) => {
|
||||||
firstPoll = false;
|
if (firstPoll) {
|
||||||
return new HttpResponse(200);
|
firstPoll = false;
|
||||||
} else {
|
return new HttpResponse(200);
|
||||||
await pollingPromiseSource.promise;
|
} else {
|
||||||
return new HttpResponse(204);
|
await pollingPromiseSource.promise;
|
||||||
}
|
return new HttpResponse(204);
|
||||||
})
|
}
|
||||||
.on("DELETE", async (r) => {
|
})
|
||||||
deleteSent = true;
|
.on("DELETE", async (r) => {
|
||||||
await deleteSyncPoint.waitToContinue();
|
deleteSent = true;
|
||||||
return new HttpResponse(202);
|
await deleteSyncPoint.waitToContinue();
|
||||||
});
|
return new HttpResponse(202);
|
||||||
|
});
|
||||||
|
|
||||||
const transport = new LongPollingTransport(httpClient, undefined, NullLogger.instance, false);
|
const transport = new LongPollingTransport(httpClient, undefined, logger, false);
|
||||||
|
|
||||||
await transport.connect("http://tempuri.org", TransferFormat.Text);
|
await transport.connect("http://tempuri.org", TransferFormat.Text);
|
||||||
|
|
||||||
// Begin stopping transport
|
// Begin stopping transport
|
||||||
const stopPromise = transport.stop();
|
const stopPromise = transport.stop();
|
||||||
|
|
||||||
// Delete will not be sent until polling is finished
|
// Delete will not be sent until polling is finished
|
||||||
expect(deleteSent).toEqual(false);
|
expect(deleteSent).toEqual(false);
|
||||||
|
|
||||||
// Allow polling to complete
|
// Allow polling to complete
|
||||||
pollingPromiseSource.resolve();
|
pollingPromiseSource.resolve();
|
||||||
|
|
||||||
// Wait for delete to be called
|
// Wait for delete to be called
|
||||||
await deleteSyncPoint.waitForSyncPoint();
|
await deleteSyncPoint.waitForSyncPoint();
|
||||||
|
|
||||||
expect(deleteSent).toEqual(true);
|
expect(deleteSent).toEqual(true);
|
||||||
|
|
||||||
deleteSyncPoint.continue();
|
deleteSyncPoint.continue();
|
||||||
|
|
||||||
// Wait for stop to complete
|
// Wait for stop to complete
|
||||||
await stopPromise;
|
await stopPromise;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue