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.
|
||||
// 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";
|
||||
|
||||
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]));
|
||||
}
|
||||
|
||||
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 { NullLogger } from "../src/Loggers";
|
||||
|
||||
import { VerifyLogger } from "./Common";
|
||||
import { TestHttpClient } from "./TestHttpClient";
|
||||
import { PromiseSource } from "./Utils";
|
||||
|
||||
|
|
@ -43,29 +44,32 @@ describe("HubConnectionBuilder", () => {
|
|||
});
|
||||
|
||||
it("builds HubConnection with HttpConnection using provided URL", async () => {
|
||||
const pollSent = new PromiseSource<HttpRequest>();
|
||||
const pollCompleted = new PromiseSource<HttpResponse>();
|
||||
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
||||
.on("POST", "http://example.com?id=abc123", (req) => {
|
||||
// Respond from the poll with the handshake response
|
||||
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
||||
return new HttpResponse(202);
|
||||
});
|
||||
const connection = createConnectionBuilder()
|
||||
.withUrl("http://example.com", {
|
||||
...commonHttpOptions,
|
||||
httpClient: testClient,
|
||||
})
|
||||
.build();
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const pollSent = new PromiseSource<HttpRequest>();
|
||||
const pollCompleted = new PromiseSource<HttpResponse>();
|
||||
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
||||
.on("POST", "http://example.com?id=abc123", (req) => {
|
||||
// Respond from the poll with the handshake response
|
||||
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
||||
return new HttpResponse(202);
|
||||
});
|
||||
const connection = createConnectionBuilder()
|
||||
.withUrl("http://example.com", {
|
||||
...commonHttpOptions,
|
||||
httpClient: testClient,
|
||||
logger,
|
||||
})
|
||||
.build();
|
||||
|
||||
// Start the connection
|
||||
const closed = makeClosedPromise(connection);
|
||||
await connection.start();
|
||||
// Start the connection
|
||||
const closed = makeClosedPromise(connection);
|
||||
await connection.start();
|
||||
|
||||
const pollRequest = await pollSent.promise;
|
||||
expect(pollRequest.url).toMatch(/http:\/\/example.com\?id=abc123.*/);
|
||||
const pollRequest = await pollSent.promise;
|
||||
expect(pollRequest.url).toMatch(/http:\/\/example.com\?id=abc123.*/);
|
||||
|
||||
await closed;
|
||||
await closed;
|
||||
});
|
||||
});
|
||||
|
||||
it("can configure transport type", async () => {
|
||||
|
|
@ -78,35 +82,38 @@ describe("HubConnectionBuilder", () => {
|
|||
});
|
||||
|
||||
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 pollCompleted = new PromiseSource<HttpResponse>();
|
||||
const negotiateReceived = new PromiseSource<HttpRequest>();
|
||||
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
||||
.on("POST", "http://example.com?id=abc123", (req) => {
|
||||
// Respond from the poll with the handshake response
|
||||
negotiateReceived.resolve(req);
|
||||
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
||||
return new HttpResponse(202);
|
||||
});
|
||||
const pollSent = new PromiseSource<HttpRequest>();
|
||||
const pollCompleted = new PromiseSource<HttpResponse>();
|
||||
const negotiateReceived = new PromiseSource<HttpRequest>();
|
||||
const testClient = createTestClient(pollSent, pollCompleted.promise)
|
||||
.on("POST", "http://example.com?id=abc123", (req) => {
|
||||
// Respond from the poll with the handshake response
|
||||
negotiateReceived.resolve(req);
|
||||
pollCompleted.resolve(new HttpResponse(204, "No Content", "{}"));
|
||||
return new HttpResponse(202);
|
||||
});
|
||||
|
||||
const connection = createConnectionBuilder()
|
||||
.withUrl("http://example.com", {
|
||||
...commonHttpOptions,
|
||||
httpClient: testClient,
|
||||
})
|
||||
.withHubProtocol(protocol)
|
||||
.build();
|
||||
const connection = createConnectionBuilder()
|
||||
.withUrl("http://example.com", {
|
||||
...commonHttpOptions,
|
||||
httpClient: testClient,
|
||||
logger,
|
||||
})
|
||||
.withHubProtocol(protocol)
|
||||
.build();
|
||||
|
||||
// Start the connection
|
||||
const closed = makeClosedPromise(connection);
|
||||
await connection.start();
|
||||
// Start the connection
|
||||
const closed = makeClosedPromise(connection);
|
||||
await connection.start();
|
||||
|
||||
const negotiateRequest = await negotiateReceived.promise;
|
||||
expect(negotiateRequest.content).toBe(`{"protocol":"${protocol.name}","version":1}\x1E`);
|
||||
const negotiateRequest = await negotiateReceived.promise;
|
||||
expect(negotiateRequest.content).toBe(`{"protocol":"${protocol.name}","version":1}\x1E`);
|
||||
|
||||
await closed;
|
||||
await closed;
|
||||
});
|
||||
});
|
||||
|
||||
it("allows logger to be replaced", async () => {
|
||||
|
|
|
|||
|
|
@ -3,63 +3,71 @@
|
|||
|
||||
import { CompletionMessage, InvocationMessage, MessageType, StreamItemMessage } from "../src/IHubProtocol";
|
||||
import { JsonHubProtocol } from "../src/JsonHubProtocol";
|
||||
import { NullLogger } from "../src/Loggers";
|
||||
import { TextMessageFormat } from "../src/TextMessageFormat";
|
||||
import { VerifyLogger } from "./Common";
|
||||
|
||||
describe("JsonHubProtocol", () => {
|
||||
it("can write/read non-blocking Invocation message", () => {
|
||||
const invocation = {
|
||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||
headers: {},
|
||||
target: "myMethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
it("can write/read non-blocking Invocation message", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const invocation = {
|
||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||
headers: {},
|
||||
target: "myMethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
});
|
||||
});
|
||||
|
||||
it("can read Invocation message with Date argument", () => {
|
||||
const invocation = {
|
||||
arguments: [Date.UTC(2018, 1, 1, 12, 34, 56)],
|
||||
headers: {},
|
||||
target: "mymethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
it("can read Invocation message with Date argument", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const invocation = {
|
||||
arguments: [Date.UTC(2018, 1, 1, 12, 34, 56)],
|
||||
headers: {},
|
||||
target: "mymethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
});
|
||||
});
|
||||
|
||||
it("can write/read Invocation message with headers", () => {
|
||||
const invocation = {
|
||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||
headers: {
|
||||
foo: "bar",
|
||||
},
|
||||
target: "myMethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
it("can write/read Invocation message with headers", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const invocation = {
|
||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||
headers: {
|
||||
foo: "bar",
|
||||
},
|
||||
target: "myMethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
});
|
||||
});
|
||||
|
||||
it("can write/read Invocation message", () => {
|
||||
const invocation = {
|
||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||
headers: {},
|
||||
invocationId: "123",
|
||||
target: "myMethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
it("can write/read Invocation message", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const invocation = {
|
||||
arguments: [42, true, "test", ["x1", "y2"], null],
|
||||
headers: {},
|
||||
invocationId: "123",
|
||||
target: "myMethod",
|
||||
type: MessageType.Invocation,
|
||||
} as InvocationMessage;
|
||||
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), NullLogger.instance);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
const protocol = new JsonHubProtocol();
|
||||
const parsedMessages = protocol.parseMessages(protocol.writeMessage(invocation), logger);
|
||||
expect(parsedMessages).toEqual([invocation]);
|
||||
});
|
||||
});
|
||||
|
||||
([
|
||||
|
|
@ -101,9 +109,11 @@ describe("JsonHubProtocol", () => {
|
|||
type: MessageType.Completion,
|
||||
} as CompletionMessage],
|
||||
] as Array<[string, CompletionMessage]>).forEach(([payload, expectedMessage]) =>
|
||||
it("can read Completion message", () => {
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
||||
expect(messages).toEqual([expectedMessage]);
|
||||
it("can read Completion message", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||
expect(messages).toEqual([expectedMessage]);
|
||||
});
|
||||
}));
|
||||
|
||||
([
|
||||
|
|
@ -122,9 +132,11 @@ describe("JsonHubProtocol", () => {
|
|||
type: MessageType.StreamItem,
|
||||
} as StreamItemMessage],
|
||||
] as Array<[string, StreamItemMessage]>).forEach(([payload, expectedMessage]) =>
|
||||
it("can read StreamItem message", () => {
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
||||
expect(messages).toEqual([expectedMessage]);
|
||||
it("can read StreamItem message", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||
expect(messages).toEqual([expectedMessage]);
|
||||
});
|
||||
}));
|
||||
|
||||
([
|
||||
|
|
@ -138,9 +150,11 @@ describe("JsonHubProtocol", () => {
|
|||
type: MessageType.StreamItem,
|
||||
} as StreamItemMessage],
|
||||
] as Array<[string, StreamItemMessage]>).forEach(([payload, expectedMessage]) =>
|
||||
it("can read message with headers", () => {
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
||||
expect(messages).toEqual([expectedMessage]);
|
||||
it("can read message with headers", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
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 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]) =>
|
||||
it("throws for " + name, () => {
|
||||
expect(() => new JsonHubProtocol().parseMessages(payload, NullLogger.instance))
|
||||
.toThrow(expectedError);
|
||||
it("throws for " + name, async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
expect(() => new JsonHubProtocol().parseMessages(payload, logger))
|
||||
.toThrow(expectedError);
|
||||
});
|
||||
}));
|
||||
|
||||
it("can read multiple messages", () => {
|
||||
const payload = `{"type":2, "invocationId": "abc", "headers": {}, "item": 8}${TextMessageFormat.RecordSeparator}{"type":3, "invocationId": "abc", "headers": {}, "result": "OK"}${TextMessageFormat.RecordSeparator}`;
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
||||
expect(messages).toEqual([
|
||||
{
|
||||
headers: {},
|
||||
invocationId: "abc",
|
||||
item: 8,
|
||||
type: MessageType.StreamItem,
|
||||
} as StreamItemMessage,
|
||||
{
|
||||
headers: {},
|
||||
invocationId: "abc",
|
||||
result: "OK",
|
||||
type: MessageType.Completion,
|
||||
} as CompletionMessage,
|
||||
]);
|
||||
it("can read multiple messages", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const payload = `{"type":2, "invocationId": "abc", "headers": {}, "item": 8}${TextMessageFormat.RecordSeparator}{"type":3, "invocationId": "abc", "headers": {}, "result": "OK"}${TextMessageFormat.RecordSeparator}`;
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||
expect(messages).toEqual([
|
||||
{
|
||||
headers: {},
|
||||
invocationId: "abc",
|
||||
item: 8,
|
||||
type: MessageType.StreamItem,
|
||||
} as StreamItemMessage,
|
||||
{
|
||||
headers: {},
|
||||
invocationId: "abc",
|
||||
result: "OK",
|
||||
type: MessageType.Completion,
|
||||
} as CompletionMessage,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it("can read ping message", () => {
|
||||
const payload = `{"type":6}${TextMessageFormat.RecordSeparator}`;
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, NullLogger.instance);
|
||||
expect(messages).toEqual([
|
||||
{
|
||||
type: MessageType.Ping,
|
||||
},
|
||||
]);
|
||||
it("can read ping message", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
const payload = `{"type":6}${TextMessageFormat.RecordSeparator}`;
|
||||
const messages = new JsonHubProtocol().parseMessages(payload, logger);
|
||||
expect(messages).toEqual([
|
||||
{
|
||||
type: MessageType.Ping,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,47 +3,56 @@
|
|||
|
||||
import { HttpResponse } from "../src/HttpClient";
|
||||
import { TransferFormat } from "../src/ITransport";
|
||||
import { NullLogger } from "../src/Loggers";
|
||||
import { LongPollingTransport } from "../src/LongPollingTransport";
|
||||
|
||||
import { VerifyLogger } from "./Common";
|
||||
import { TestHttpClient } from "./TestHttpClient";
|
||||
import { PromiseSource, SyncPoint } from "./Utils";
|
||||
|
||||
describe("LongPollingTransport", () => {
|
||||
it("shuts down polling by aborting in-progress request", async () => {
|
||||
let firstPoll = true;
|
||||
const pollCompleted = new PromiseSource();
|
||||
const client = new TestHttpClient()
|
||||
.on("GET", async (r) => {
|
||||
if (firstPoll) {
|
||||
firstPoll = false;
|
||||
return new HttpResponse(200);
|
||||
} else {
|
||||
// Turn 'onabort' into a promise.
|
||||
const abort = new Promise((resolve, reject) => r.abortSignal!.onabort = resolve);
|
||||
await abort;
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
let firstPoll = true;
|
||||
const pollCompleted = new PromiseSource();
|
||||
const client = new TestHttpClient()
|
||||
.on("GET", async (r) => {
|
||||
if (firstPoll) {
|
||||
firstPoll = false;
|
||||
return new HttpResponse(200);
|
||||
} else {
|
||||
// Turn 'onabort' into a promise.
|
||||
const abort = new Promise((resolve, reject) => {
|
||||
if (r.abortSignal!.aborted) {
|
||||
resolve();
|
||||
} else {
|
||||
r.abortSignal!.onabort = resolve;
|
||||
}
|
||||
});
|
||||
await abort;
|
||||
|
||||
// Signal that the poll has completed.
|
||||
pollCompleted.resolve();
|
||||
// Signal that the poll has completed.
|
||||
pollCompleted.resolve();
|
||||
|
||||
return new HttpResponse(200);
|
||||
}
|
||||
})
|
||||
.on("DELETE", () => new HttpResponse(202));
|
||||
const transport = new LongPollingTransport(client, undefined, NullLogger.instance, false);
|
||||
return new HttpResponse(200);
|
||||
}
|
||||
})
|
||||
.on("DELETE", () => new HttpResponse(202));
|
||||
const transport = new LongPollingTransport(client, undefined, logger, false);
|
||||
|
||||
await transport.connect("http://example.com", TransferFormat.Text);
|
||||
const stopPromise = transport.stop();
|
||||
await transport.connect("http://example.com", TransferFormat.Text);
|
||||
const stopPromise = transport.stop();
|
||||
|
||||
await pollCompleted.promise;
|
||||
await pollCompleted.promise;
|
||||
|
||||
await stopPromise;
|
||||
await stopPromise;
|
||||
});
|
||||
});
|
||||
|
||||
it("204 server response stops polling and raises onClose", async () => {
|
||||
let firstPoll = true;
|
||||
const client = new TestHttpClient()
|
||||
.on("GET", async () => {
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
let firstPoll = true;
|
||||
const client = new TestHttpClient()
|
||||
.on("GET", async () => {
|
||||
if (firstPoll) {
|
||||
firstPoll = false;
|
||||
return new HttpResponse(200);
|
||||
|
|
@ -52,59 +61,62 @@ describe("LongPollingTransport", () => {
|
|||
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
|
||||
await stopPromise;
|
||||
// Close will be called on transport because of 204 result from polling
|
||||
await stopPromise;
|
||||
});
|
||||
});
|
||||
|
||||
it("sends DELETE on stop after polling has finished", async () => {
|
||||
let firstPoll = true;
|
||||
let deleteSent = false;
|
||||
const pollingPromiseSource = new PromiseSource();
|
||||
const deleteSyncPoint = new SyncPoint();
|
||||
const httpClient = new TestHttpClient()
|
||||
.on("GET", async (r) => {
|
||||
if (firstPoll) {
|
||||
firstPoll = false;
|
||||
return new HttpResponse(200);
|
||||
} else {
|
||||
await pollingPromiseSource.promise;
|
||||
return new HttpResponse(204);
|
||||
}
|
||||
})
|
||||
.on("DELETE", async (r) => {
|
||||
deleteSent = true;
|
||||
await deleteSyncPoint.waitToContinue();
|
||||
return new HttpResponse(202);
|
||||
});
|
||||
await VerifyLogger.run(async (logger) => {
|
||||
let firstPoll = true;
|
||||
let deleteSent = false;
|
||||
const pollingPromiseSource = new PromiseSource();
|
||||
const deleteSyncPoint = new SyncPoint();
|
||||
const httpClient = new TestHttpClient()
|
||||
.on("GET", async (r) => {
|
||||
if (firstPoll) {
|
||||
firstPoll = false;
|
||||
return new HttpResponse(200);
|
||||
} else {
|
||||
await pollingPromiseSource.promise;
|
||||
return new HttpResponse(204);
|
||||
}
|
||||
})
|
||||
.on("DELETE", async (r) => {
|
||||
deleteSent = true;
|
||||
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
|
||||
const stopPromise = transport.stop();
|
||||
// Begin stopping transport
|
||||
const stopPromise = transport.stop();
|
||||
|
||||
// Delete will not be sent until polling is finished
|
||||
expect(deleteSent).toEqual(false);
|
||||
// Delete will not be sent until polling is finished
|
||||
expect(deleteSent).toEqual(false);
|
||||
|
||||
// Allow polling to complete
|
||||
pollingPromiseSource.resolve();
|
||||
// Allow polling to complete
|
||||
pollingPromiseSource.resolve();
|
||||
|
||||
// Wait for delete to be called
|
||||
await deleteSyncPoint.waitForSyncPoint();
|
||||
// Wait for delete to be called
|
||||
await deleteSyncPoint.waitForSyncPoint();
|
||||
|
||||
expect(deleteSent).toEqual(true);
|
||||
expect(deleteSent).toEqual(true);
|
||||
|
||||
deleteSyncPoint.continue();
|
||||
deleteSyncPoint.continue();
|
||||
|
||||
// Wait for stop to complete
|
||||
await stopPromise;
|
||||
// Wait for stop to complete
|
||||
await stopPromise;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue