Skip to content

Commit 74360c7

Browse files
Fix a couple things in Typescript client (#13863)
1 parent 8a4b839 commit 74360c7

File tree

4 files changed

+92
-10
lines changed

4 files changed

+92
-10
lines changed

src/SignalR/clients/ts/signalr/src/HttpConnection.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export class HttpConnection implements IConnection {
322322
});
323323

324324
if (response.statusCode !== 200) {
325-
return Promise.reject(new Error(`Unexpected status code returned from negotiate ${response.statusCode}`));
325+
return Promise.reject(new Error(`Unexpected status code returned from negotiate '${response.statusCode}'`));
326326
}
327327

328328
const negotiateResponse = JSON.parse(response.content as string) as INegotiateResponse;
@@ -475,8 +475,8 @@ export class HttpConnection implements IConnection {
475475
}
476476

477477
if (this.connectionState === ConnectionState.Connecting) {
478-
this.logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection hasn't yet left the in the connecting state.`);
479-
return;
478+
this.logger.log(LogLevel.Warning, `Call to HttpConnection.stopConnection(${error}) was ignored because the connection is still in the connecting state.`);
479+
throw new Error(`HttpConnection.stopConnection(${error}) was called while the connection is still in the connecting state.`);
480480
}
481481

482482
if (this.connectionState === ConnectionState.Disconnecting) {
@@ -626,7 +626,7 @@ export class TransportSendQueue {
626626
offset += item.byteLength;
627627
}
628628

629-
return result;
629+
return result.buffer;
630630
}
631631
}
632632

src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ export class WebSocketTransport implements ITransport {
105105
}
106106
};
107107

108-
webSocket.onclose = (event: CloseEvent) => this.close(event);
108+
webSocket.onclose = (event: CloseEvent) => {
109+
if (this.webSocket) {
110+
this.close(event);
111+
}
112+
};
109113
});
110114
}
111115

src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { HttpTransportType, ITransport, TransferFormat } from "../src/ITransport
88
import { getUserAgentHeader } from "../src/Utils";
99

1010
import { HttpError } from "../src/Errors";
11+
import { ILogger, LogLevel } from "../src/ILogger";
1112
import { NullLogger } from "../src/Loggers";
1213
import { EventSourceConstructor, WebSocketConstructor } from "../src/Polyfills";
1314

@@ -192,9 +193,9 @@ describe("HttpConnection", () => {
192193
const connection = new HttpConnection("http://tempuri.org", options);
193194
await expect(connection.start(TransferFormat.Text))
194195
.rejects
195-
.toThrow("Unexpected status code returned from negotiate 999");
196+
.toThrow("Unexpected status code returned from negotiate '999'");
196197
},
197-
"Failed to start the connection: Error: Unexpected status code returned from negotiate 999");
198+
"Failed to start the connection: Error: Unexpected status code returned from negotiate '999'");
198199
});
199200

200201
it("all transport failure errors get aggregated", async () => {
@@ -1151,6 +1152,53 @@ describe("HttpConnection", () => {
11511152
}, "Failed to start the connection: Error: nope");
11521153
});
11531154

1155+
it("logMessageContent displays correctly with binary data", async () => {
1156+
await VerifyLogger.run(async (logger) => {
1157+
const availableTransport = { transport: "LongPolling", transferFormats: ["Text", "Binary"] };
1158+
1159+
let sentMessage = "";
1160+
const captureLogger: ILogger = {
1161+
log: (logLevel: LogLevel, message: string) => {
1162+
if (logLevel === LogLevel.Trace && message.search("data of length") > 0) {
1163+
sentMessage = message;
1164+
}
1165+
1166+
logger.log(logLevel, message);
1167+
},
1168+
};
1169+
1170+
let httpClientGetCount = 0;
1171+
const options: IHttpConnectionOptions = {
1172+
...commonOptions,
1173+
httpClient: new TestHttpClient()
1174+
.on("POST", () => ({ connectionId: "42", availableTransports: [availableTransport] }))
1175+
.on("GET", () => {
1176+
httpClientGetCount++;
1177+
if (httpClientGetCount === 1) {
1178+
// First long polling request must succeed so start completes
1179+
return "";
1180+
}
1181+
return Promise.resolve();
1182+
})
1183+
.on("DELETE", () => new HttpResponse(202)),
1184+
logMessageContent: true,
1185+
logger: captureLogger,
1186+
transport: HttpTransportType.LongPolling,
1187+
} as IHttpConnectionOptions;
1188+
1189+
const connection = new HttpConnection("http://tempuri.org", options);
1190+
connection.onreceive = () => null;
1191+
try {
1192+
await connection.start(TransferFormat.Binary);
1193+
await connection.send(new Uint8Array([0x68, 0x69, 0x20, 0x3a, 0x29]));
1194+
} finally {
1195+
await connection.stop();
1196+
}
1197+
1198+
expect(sentMessage).toBe("(LongPolling transport) sending data. Binary data of length 5. Content: '0x68 0x69 0x20 0x3a 0x29'.");
1199+
});
1200+
});
1201+
11541202
describe(".constructor", () => {
11551203
it("throws if no Url is provided", async () => {
11561204
// Force TypeScript to let us call the constructor incorrectly :)
@@ -1413,7 +1461,7 @@ describe("TransportSendQueue", () => {
14131461

14141462
const queue = new TransportSendQueue(transport);
14151463

1416-
const first = queue.send(new Uint8Array([4, 5, 6]));
1464+
const first = queue.send(new Uint8Array([4, 5, 6]).buffer);
14171465
// This should allow first to enter transport.send
14181466
promiseSource1.resolve();
14191467
// Wait until we're inside transport.send
@@ -1428,8 +1476,8 @@ describe("TransportSendQueue", () => {
14281476
await Promise.all([first, second, third]);
14291477

14301478
expect(sendMock.mock.calls.length).toBe(2);
1431-
expect(sendMock.mock.calls[0][0]).toEqual(new Uint8Array([4, 5, 6]));
1432-
expect(sendMock.mock.calls[1][0]).toEqual(new Uint8Array([7, 8, 10, 12, 14]));
1479+
expect(sendMock.mock.calls[0][0]).toEqual(new Uint8Array([4, 5, 6]).buffer);
1480+
expect(sendMock.mock.calls[1][0]).toEqual(new Uint8Array([7, 8, 10, 12, 14]).buffer);
14331481

14341482
await queue.stop();
14351483
});

src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,36 @@ describe("WebSocketTransport", () => {
259259
.toBe("WebSocket is not in the OPEN state");
260260
});
261261
});
262+
263+
it("does not run onclose callback if Transport does not fully connect and exits", async () => {
264+
await VerifyLogger.run(async (logger) => {
265+
(global as any).ErrorEvent = TestErrorEvent;
266+
const webSocket = new WebSocketTransport(new TestHttpClient(), undefined, logger, true, TestWebSocket);
267+
268+
const connectPromise = webSocket.connect("http://example.com", TransferFormat.Text);
269+
270+
await TestWebSocket.webSocket.closeSet;
271+
272+
let closeCalled: boolean = false;
273+
let error: Error;
274+
webSocket.onclose = (e) => {
275+
closeCalled = true;
276+
error = e!;
277+
};
278+
279+
const message = new TestCloseEvent();
280+
message.wasClean = false;
281+
message.code = 1;
282+
message.reason = "just cause";
283+
TestWebSocket.webSocket.onclose(message);
284+
285+
expect(closeCalled).toBe(false);
286+
expect(error!).toBeUndefined();
287+
288+
TestWebSocket.webSocket.onerror(new TestEvent());
289+
await expect(connectPromise).rejects.toThrow("There was an error with the transport.");
290+
});
291+
});
262292
});
263293

264294
async function createAndStartWebSocket(logger: ILogger, url?: string, accessTokenFactory?: (() => string | Promise<string>), format?: TransferFormat): Promise<WebSocketTransport> {

0 commit comments

Comments
 (0)