|
2 | 2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
3 | 3 |
|
4 | 4 | import { DefaultReconnectPolicy } from "../src/DefaultReconnectPolicy";
|
| 5 | +import { HttpConnection, INegotiateResponse } from "../src/HttpConnection"; |
5 | 6 | import { HubConnection, HubConnectionState } from "../src/HubConnection";
|
| 7 | +import { IHttpConnectionOptions } from "../src/IHttpConnectionOptions"; |
6 | 8 | import { MessageType } from "../src/IHubProtocol";
|
7 | 9 | import { RetryContext } from "../src/IRetryPolicy";
|
8 | 10 | import { JsonHubProtocol } from "../src/JsonHubProtocol";
|
9 | 11 |
|
10 | 12 | import { VerifyLogger } from "./Common";
|
11 | 13 | import { TestConnection } from "./TestConnection";
|
| 14 | +import { TestHttpClient } from "./TestHttpClient"; |
| 15 | +import { TestEvent, TestMessageEvent, TestWebSocket } from "./TestWebSocket"; |
12 | 16 | import { PromiseSource } from "./Utils";
|
13 | 17 |
|
14 | 18 | describe("auto reconnect", () => {
|
@@ -785,4 +789,93 @@ describe("auto reconnect", () => {
|
785 | 789 | }
|
786 | 790 | });
|
787 | 791 | });
|
| 792 | + |
| 793 | + it("can be stopped while restarting the underlying connection and negotiate throws", async () => { |
| 794 | + await VerifyLogger.run(async (logger) => { |
| 795 | + let onreconnectingCount = 0; |
| 796 | + let onreconnectedCount = 0; |
| 797 | + let closeCount = 0; |
| 798 | + |
| 799 | + const nextRetryDelayCalledPromise = new PromiseSource(); |
| 800 | + |
| 801 | + const defaultConnectionId = "abc123"; |
| 802 | + const defaultConnectionToken = "123abc"; |
| 803 | + const defaultNegotiateResponse: INegotiateResponse = { |
| 804 | + availableTransports: [ |
| 805 | + { transport: "WebSockets", transferFormats: ["Text", "Binary"] }, |
| 806 | + { transport: "ServerSentEvents", transferFormats: ["Text"] }, |
| 807 | + { transport: "LongPolling", transferFormats: ["Text", "Binary"] }, |
| 808 | + ], |
| 809 | + connectionId: defaultConnectionId, |
| 810 | + connectionToken: defaultConnectionToken, |
| 811 | + negotiateVersion: 1, |
| 812 | + }; |
| 813 | + |
| 814 | + const startStarted = new PromiseSource(); |
| 815 | + let negotiateCount = 0; |
| 816 | + |
| 817 | + const options: IHttpConnectionOptions = { |
| 818 | + WebSocket: TestWebSocket, |
| 819 | + httpClient: new TestHttpClient() |
| 820 | + .on("POST", async () => { |
| 821 | + ++negotiateCount; |
| 822 | + if (negotiateCount === 1) { |
| 823 | + return defaultNegotiateResponse; |
| 824 | + } |
| 825 | + startStarted.resolve(); |
| 826 | + return Promise.reject("Error with negotiate"); |
| 827 | + }) |
| 828 | + .on("GET", () => ""), |
| 829 | + logger, |
| 830 | + } as IHttpConnectionOptions; |
| 831 | + |
| 832 | + const connection = new HttpConnection("http://tempuri.org", options); |
| 833 | + const hubConnection = HubConnection.create(connection, logger, new JsonHubProtocol(), { |
| 834 | + nextRetryDelayInMilliseconds() { |
| 835 | + nextRetryDelayCalledPromise.resolve(); |
| 836 | + return 0; |
| 837 | + }, |
| 838 | + }); |
| 839 | + |
| 840 | + hubConnection.onreconnecting(() => { |
| 841 | + onreconnectingCount++; |
| 842 | + }); |
| 843 | + |
| 844 | + hubConnection.onreconnected(() => { |
| 845 | + onreconnectedCount++; |
| 846 | + }); |
| 847 | + |
| 848 | + hubConnection.onclose(() => { |
| 849 | + closeCount++; |
| 850 | + }); |
| 851 | + |
| 852 | + TestWebSocket.webSocketSet = new PromiseSource(); |
| 853 | + const startPromise = hubConnection.start(); |
| 854 | + await TestWebSocket.webSocketSet; |
| 855 | + await TestWebSocket.webSocket.openSet; |
| 856 | + TestWebSocket.webSocket.onopen(new TestEvent()); |
| 857 | + TestWebSocket.webSocket.onmessage(new TestMessageEvent("{}\x1e")); |
| 858 | + |
| 859 | + await startPromise; |
| 860 | + TestWebSocket.webSocket.close(); |
| 861 | + TestWebSocket.webSocketSet = new PromiseSource(); |
| 862 | + |
| 863 | + await nextRetryDelayCalledPromise; |
| 864 | + |
| 865 | + expect(hubConnection.state).toBe(HubConnectionState.Reconnecting); |
| 866 | + expect(onreconnectingCount).toBe(1); |
| 867 | + expect(onreconnectedCount).toBe(0); |
| 868 | + expect(closeCount).toBe(0); |
| 869 | + |
| 870 | + await startStarted; |
| 871 | + await hubConnection.stop(); |
| 872 | + |
| 873 | + expect(hubConnection.state).toBe(HubConnectionState.Disconnected); |
| 874 | + expect(onreconnectingCount).toBe(1); |
| 875 | + expect(onreconnectedCount).toBe(0); |
| 876 | + expect(closeCount).toBe(1); |
| 877 | + }, |
| 878 | + "Failed to complete negotiation with the server: Error with negotiate", |
| 879 | + "Failed to start the connection: Error with negotiate"); |
| 880 | + }); |
788 | 881 | });
|
0 commit comments