How to use Hub method in Best

Best JavaScript code snippet using best

HubConnection.test.ts

Source:HubConnection.test.ts Github

copy

Full Screen

1// Copyright (c) .NET Foundation. All rights reserved.2// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.3import { HubConnection, HubConnectionState } from "../src/HubConnection";4import { IConnection } from "../src/IConnection";5import { HubMessage, IHubProtocol, MessageType } from "../src/IHubProtocol";6import { ILogger, LogLevel } from "../src/ILogger";7import { TransferFormat } from "../src/ITransport";8import { JsonHubProtocol } from "../src/JsonHubProtocol";9import { NullLogger } from "../src/Loggers";10import { IStreamSubscriber } from "../src/Stream";11import { TextMessageFormat } from "../src/TextMessageFormat";12import { VerifyLogger } from "./Common";13import { delay, PromiseSource, registerUnhandledRejectionHandler } from "./Utils";14function createHubConnection(connection: IConnection, logger?: ILogger | null, protocol?: IHubProtocol | null) {15 return HubConnection.create(connection, logger || NullLogger.instance, protocol || new JsonHubProtocol());16}17registerUnhandledRejectionHandler();18describe("HubConnection", () => {19 describe("start", () => {20 it("sends handshake message", async () => {21 await VerifyLogger.run(async (logger) => {22 const connection = new TestConnection();23 const hubConnection = createHubConnection(connection, logger);24 try {25 await hubConnection.start();26 expect(connection.sentData.length).toBe(1);27 expect(JSON.parse(connection.sentData[0])).toEqual({28 protocol: "json",29 version: 1,30 });31 } finally {32 await hubConnection.stop();33 }34 });35 });36 it("state connected", async () => {37 await VerifyLogger.run(async (logger) => {38 const connection = new TestConnection();39 const hubConnection = createHubConnection(connection, logger);40 expect(hubConnection.state).toBe(HubConnectionState.Disconnected);41 try {42 await hubConnection.start();43 expect(hubConnection.state).toBe(HubConnectionState.Connected);44 } finally {45 await hubConnection.stop();46 }47 });48 });49 });50 describe("ping", () => {51 it("automatically sends multiple pings", async () => {52 await VerifyLogger.run(async (logger) => {53 const connection = new TestConnection();54 const hubConnection = createHubConnection(connection, logger);55 hubConnection.keepAliveIntervalInMilliseconds = 5;56 try {57 await hubConnection.start();58 await delay(500);59 const numPings = connection.sentData.filter((s) => JSON.parse(s).type === MessageType.Ping).length;60 expect(numPings).toBeGreaterThanOrEqual(2);61 } finally {62 await hubConnection.stop();63 }64 });65 });66 });67 describe("stop", () => {68 it("state disconnected", async () => {69 await VerifyLogger.run(async (logger) => {70 const connection = new TestConnection();71 const hubConnection = createHubConnection(connection, logger);72 expect(hubConnection.state).toBe(HubConnectionState.Disconnected);73 try {74 await hubConnection.start();75 expect(hubConnection.state).toBe(HubConnectionState.Connected);76 } finally {77 await hubConnection.stop();78 expect(hubConnection.state).toBe(HubConnectionState.Disconnected);79 }80 });81 });82 });83 describe("send", () => {84 it("sends a non blocking invocation", async () => {85 await VerifyLogger.run(async (logger) => {86 const connection = new TestConnection();87 const hubConnection = createHubConnection(connection, logger);88 try {89 // We don't actually care to wait for the send.90 // tslint:disable-next-line:no-floating-promises91 hubConnection.send("testMethod", "arg", 42)92 .catch((_) => { }); // Suppress exception and unhandled promise rejection warning.93 // Verify the message is sent94 expect(connection.sentData.length).toBe(1);95 expect(JSON.parse(connection.sentData[0])).toEqual({96 arguments: [97 "arg",98 42,99 ],100 target: "testMethod",101 type: MessageType.Invocation,102 });103 } finally {104 // Close the connection105 await hubConnection.stop();106 }107 });108 });109 });110 describe("invoke", () => {111 it("sends an invocation", async () => {112 await VerifyLogger.run(async (logger) => {113 const connection = new TestConnection();114 const hubConnection = createHubConnection(connection, logger);115 try {116 // We don't actually care to wait for the send.117 // tslint:disable-next-line:no-floating-promises118 hubConnection.invoke("testMethod", "arg", 42)119 .catch((_) => { }); // Suppress exception and unhandled promise rejection warning.120 // Verify the message is sent121 expect(connection.sentData.length).toBe(1);122 expect(JSON.parse(connection.sentData[0])).toEqual({123 arguments: [124 "arg",125 42,126 ],127 invocationId: connection.lastInvocationId,128 target: "testMethod",129 type: MessageType.Invocation,130 });131 } finally {132 // Close the connection133 await hubConnection.stop();134 }135 });136 });137 it("can process handshake from text", async () => {138 await VerifyLogger.run(async (logger) => {139 let protocolCalled = false;140 const mockProtocol = new TestProtocol(TransferFormat.Text);141 mockProtocol.onreceive = (d) => {142 protocolCalled = true;143 };144 const connection = new TestConnection(false);145 const hubConnection = createHubConnection(connection, logger, mockProtocol);146 try {147 let startCompleted = false;148 const startPromise = hubConnection.start().then(() => startCompleted = true);149 const data = "{}" + TextMessageFormat.RecordSeparator;150 expect(startCompleted).toBe(false);151 connection.receiveText(data);152 await startPromise;153 // message only contained handshake response154 expect(protocolCalled).toEqual(false);155 } finally {156 await hubConnection.stop();157 }158 });159 });160 it("can process handshake from binary", async () => {161 await VerifyLogger.run(async (logger) => {162 let protocolCalled = false;163 const mockProtocol = new TestProtocol(TransferFormat.Binary);164 mockProtocol.onreceive = (d) => {165 protocolCalled = true;166 };167 const connection = new TestConnection(false);168 const hubConnection = createHubConnection(connection, logger, mockProtocol);169 try {170 let startCompleted = false;171 const startPromise = hubConnection.start().then(() => startCompleted = true);172 expect(startCompleted).toBe(false);173 // handshake response + message separator174 const data = [0x7b, 0x7d, 0x1e];175 connection.receiveBinary(new Uint8Array(data).buffer);176 await startPromise;177 // message only contained handshake response178 expect(protocolCalled).toEqual(false);179 } finally {180 await hubConnection.stop();181 }182 });183 });184 it("can process handshake and additional messages from binary", async () => {185 await VerifyLogger.run(async (logger) => {186 let receivedProcotolData: ArrayBuffer | undefined;187 const mockProtocol = new TestProtocol(TransferFormat.Binary);188 mockProtocol.onreceive = (d) => receivedProcotolData = d as ArrayBuffer;189 const connection = new TestConnection(false);190 const hubConnection = createHubConnection(connection, logger, mockProtocol);191 try {192 let startCompleted = false;193 const startPromise = hubConnection.start().then(() => startCompleted = true);194 expect(startCompleted).toBe(false);195 // handshake response + message separator + message pack message196 const data = [197 0x7b, 0x7d, 0x1e, 0x65, 0x95, 0x03, 0x80, 0xa1, 0x30, 0x01, 0xd9, 0x5d, 0x54, 0x68, 0x65, 0x20, 0x63, 0x6c,198 0x69, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20,199 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69,200 0x6e, 0x67, 0x20, 0x27, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x27, 0x20, 0x6d,201 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x6e, 0x2d, 0x73, 0x74, 0x72,202 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x61, 0x73, 0x68, 0x69, 0x6f, 0x6e, 0x2e,203 ];204 connection.receiveBinary(new Uint8Array(data).buffer);205 await startPromise;206 // left over data is the message pack message207 expect(receivedProcotolData!.byteLength).toEqual(102);208 } finally {209 await hubConnection.stop();210 }211 });212 });213 it("can process handshake and additional messages from text", async () => {214 await VerifyLogger.run(async (logger) => {215 let receivedProcotolData: string | undefined;216 const mockProtocol = new TestProtocol(TransferFormat.Text);217 mockProtocol.onreceive = (d) => receivedProcotolData = d as string;218 const connection = new TestConnection(false);219 const hubConnection = createHubConnection(connection, logger, mockProtocol);220 try {221 let startCompleted = false;222 const startPromise = hubConnection.start().then(() => startCompleted = true);223 expect(startCompleted).toBe(false);224 const data = "{}" + TextMessageFormat.RecordSeparator + "{\"type\":6}" + TextMessageFormat.RecordSeparator;225 connection.receiveText(data);226 await startPromise;227 expect(receivedProcotolData).toEqual("{\"type\":6}" + TextMessageFormat.RecordSeparator);228 } finally {229 await hubConnection.stop();230 }231 });232 });233 it.only("start completes if connection closes and handshake not received yet", async () => {234 await VerifyLogger.run(async (logger) => {235 const mockProtocol = new TestProtocol(TransferFormat.Text);236 const connection = new TestConnection(false);237 const hubConnection = createHubConnection(connection, logger, mockProtocol);238 try {239 let startCompleted = false;240 const startPromise = hubConnection.start().then(() => startCompleted = true);241 expect(startCompleted).toBe(false);242 await connection.stop();243 try {244 await startPromise;245 } catch { }246 } finally {247 await hubConnection.stop();248 }249 });250 });251 it("rejects the promise when an error is received", async () => {252 await VerifyLogger.run(async (logger) => {253 const connection = new TestConnection();254 const hubConnection = createHubConnection(connection, logger);255 try {256 await hubConnection.start();257 const invokePromise = hubConnection.invoke("testMethod", "arg", 42);258 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId, error: "foo" });259 await expect(invokePromise).rejects.toThrow("foo");260 } finally {261 await hubConnection.stop();262 }263 });264 });265 it("resolves the promise when a result is received", async () => {266 await VerifyLogger.run(async (logger) => {267 const connection = new TestConnection();268 const hubConnection = createHubConnection(connection, logger);269 try {270 await hubConnection.start();271 const invokePromise = hubConnection.invoke("testMethod", "arg", 42);272 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId, result: "foo" });273 expect(await invokePromise).toBe("foo");274 } finally {275 await hubConnection.stop();276 }277 });278 });279 it("completes pending invocations when stopped", async () => {280 await VerifyLogger.run(async (logger) => {281 const connection = new TestConnection();282 const hubConnection = createHubConnection(connection, logger);283 await hubConnection.start();284 const invokePromise = hubConnection.invoke("testMethod");285 await hubConnection.stop();286 await expect(invokePromise).rejects.toThrow("Invocation canceled due to connection being closed.");287 });288 });289 it("completes pending invocations when connection is lost", async () => {290 await VerifyLogger.run(async (logger) => {291 const connection = new TestConnection();292 const hubConnection = createHubConnection(connection, logger);293 try {294 await hubConnection.start();295 const invokePromise = hubConnection.invoke("testMethod");296 // Typically this would be called by the transport297 connection.onclose!(new Error("Connection lost"));298 await expect(invokePromise).rejects.toThrow("Connection lost");299 } finally {300 await hubConnection.stop();301 }302 });303 });304 });305 describe("on", () => {306 it("invocations ignored in callbacks not registered", async () => {307 await VerifyLogger.run(async (logger) => {308 const warnings: string[] = [];309 const wrappingLogger = {310 log: (logLevel: LogLevel, message: string) => {311 if (logLevel === LogLevel.Warning) {312 warnings.push(message);313 }314 logger.log(logLevel, message);315 },316 } as ILogger;317 const connection = new TestConnection();318 const hubConnection = createHubConnection(connection, wrappingLogger);319 try {320 await hubConnection.start();321 connection.receive({322 arguments: ["test"],323 nonblocking: true,324 target: "message",325 type: MessageType.Invocation,326 });327 expect(warnings).toEqual(["No client method with the name 'message' found."]);328 } finally {329 await hubConnection.stop();330 }331 });332 });333 it("invocations ignored in callbacks that have registered then unregistered", async () => {334 await VerifyLogger.run(async (logger) => {335 const warnings: string[] = [];336 const wrappingLogger = {337 log: (logLevel: LogLevel, message: string) => {338 if (logLevel === LogLevel.Warning) {339 warnings.push(message);340 }341 logger.log(logLevel, message);342 },343 } as ILogger;344 const connection = new TestConnection();345 const hubConnection = createHubConnection(connection, wrappingLogger);346 try {347 await hubConnection.start();348 const handler = () => { };349 hubConnection.on("message", handler);350 hubConnection.off("message", handler);351 connection.receive({352 arguments: ["test"],353 invocationId: "0",354 nonblocking: true,355 target: "message",356 type: MessageType.Invocation,357 });358 expect(warnings).toEqual(["No client method with the name 'message' found."]);359 } finally {360 await hubConnection.stop();361 }362 });363 });364 it("all handlers can be unregistered with just the method name", async () => {365 await VerifyLogger.run(async (logger) => {366 const connection = new TestConnection();367 const hubConnection = createHubConnection(connection, logger);368 try {369 await hubConnection.start();370 let count = 0;371 const handler = () => { count++; };372 const secondHandler = () => { count++; };373 hubConnection.on("inc", handler);374 hubConnection.on("inc", secondHandler);375 connection.receive({376 arguments: [],377 nonblocking: true,378 target: "inc",379 type: MessageType.Invocation,380 });381 hubConnection.off("inc");382 connection.receive({383 arguments: [],384 nonblocking: true,385 target: "inc",386 type: MessageType.Invocation,387 });388 expect(count).toBe(2);389 } finally {390 await hubConnection.stop();391 }392 });393 });394 it("a single handler can be unregistered with the method name and handler", async () => {395 await VerifyLogger.run(async (logger) => {396 const connection = new TestConnection();397 const hubConnection = createHubConnection(connection, logger);398 try {399 await hubConnection.start();400 let count = 0;401 const handler = () => { count++; };402 const secondHandler = () => { count++; };403 hubConnection.on("inc", handler);404 hubConnection.on("inc", secondHandler);405 connection.receive({406 arguments: [],407 nonblocking: true,408 target: "inc",409 type: MessageType.Invocation,410 });411 hubConnection.off("inc", handler);412 connection.receive({413 arguments: [],414 nonblocking: true,415 target: "inc",416 type: MessageType.Invocation,417 });418 expect(count).toBe(3);419 } finally {420 await hubConnection.stop();421 }422 });423 });424 it("can't register the same handler multiple times", async () => {425 await VerifyLogger.run(async (logger) => {426 const connection = new TestConnection();427 const hubConnection = createHubConnection(connection, logger);428 try {429 await hubConnection.start();430 let count = 0;431 const handler = () => { count++; };432 hubConnection.on("inc", handler);433 hubConnection.on("inc", handler);434 connection.receive({435 arguments: [],436 nonblocking: true,437 target: "inc",438 type: MessageType.Invocation,439 });440 expect(count).toBe(1);441 } finally {442 await hubConnection.stop();443 }444 });445 });446 it("callback invoked when servers invokes a method on the client", async () => {447 await VerifyLogger.run(async (logger) => {448 const connection = new TestConnection();449 const hubConnection = createHubConnection(connection, logger);450 try {451 await hubConnection.start();452 let value = "";453 hubConnection.on("message", (v) => value = v);454 connection.receive({455 arguments: ["test"],456 nonblocking: true,457 target: "message",458 type: MessageType.Invocation,459 });460 expect(value).toBe("test");461 } finally {462 await hubConnection.stop();463 }464 });465 });466 it("stop on handshake error", async () => {467 await VerifyLogger.run(async (logger) => {468 const connection = new TestConnection(false);469 const hubConnection = createHubConnection(connection, logger);470 try {471 let closeError: Error | undefined;472 hubConnection.onclose((e) => closeError = e);473 let startCompleted = false;474 const startPromise = hubConnection.start().then(() => startCompleted = true);475 expect(startCompleted).toBe(false);476 try {477 connection.receiveHandshakeResponse("Error!");478 } catch {479 }480 await expect(startPromise)481 .rejects482 .toBe("Server returned handshake error: Error!");483 expect(closeError!.message).toEqual("Server returned handshake error: Error!");484 } finally {485 await hubConnection.stop();486 }487 },488 "Server returned handshake error: Error!");489 });490 it("stop on close message", async () => {491 await VerifyLogger.run(async (logger) => {492 const connection = new TestConnection();493 const hubConnection = createHubConnection(connection, logger);494 try {495 let isClosed = false;496 let closeError: Error | undefined;497 hubConnection.onclose((e) => {498 isClosed = true;499 closeError = e;500 });501 await hubConnection.start();502 connection.receive({503 type: MessageType.Close,504 });505 expect(isClosed).toEqual(true);506 expect(closeError).toBeUndefined();507 } finally {508 await hubConnection.stop();509 }510 });511 });512 it("stop on error close message", async () => {513 await VerifyLogger.run(async (logger) => {514 const connection = new TestConnection();515 const hubConnection = createHubConnection(connection, logger);516 try {517 let isClosed = false;518 let closeError: Error | undefined;519 hubConnection.onclose((e) => {520 isClosed = true;521 closeError = e;522 });523 await hubConnection.start();524 connection.receive({525 error: "Error!",526 type: MessageType.Close,527 });528 expect(isClosed).toEqual(true);529 expect(closeError!.message).toEqual("Server returned an error on close: Error!");530 } finally {531 await hubConnection.stop();532 }533 });534 });535 it("can have multiple callbacks", async () => {536 await VerifyLogger.run(async (logger) => {537 const connection = new TestConnection();538 const hubConnection = createHubConnection(connection, logger);539 try {540 await hubConnection.start();541 let numInvocations1 = 0;542 let numInvocations2 = 0;543 hubConnection.on("message", () => numInvocations1++);544 hubConnection.on("message", () => numInvocations2++);545 connection.receive({546 arguments: [],547 nonblocking: true,548 target: "message",549 type: MessageType.Invocation,550 });551 expect(numInvocations1).toBe(1);552 expect(numInvocations2).toBe(1);553 } finally {554 await hubConnection.stop();555 }556 });557 });558 it("can unsubscribe from on", async () => {559 await VerifyLogger.run(async (logger) => {560 const connection = new TestConnection();561 const hubConnection = createHubConnection(connection, logger);562 try {563 await hubConnection.start();564 let numInvocations = 0;565 const callback = () => numInvocations++;566 hubConnection.on("message", callback);567 connection.receive({568 arguments: [],569 nonblocking: true,570 target: "message",571 type: MessageType.Invocation,572 });573 hubConnection.off("message", callback);574 connection.receive({575 arguments: [],576 nonblocking: true,577 target: "message",578 type: MessageType.Invocation,579 });580 expect(numInvocations).toBe(1);581 } finally {582 await hubConnection.stop();583 }584 });585 });586 it("unsubscribing from non-existing callbacks no-ops", async () => {587 await VerifyLogger.run(async (logger) => {588 const connection = new TestConnection();589 const hubConnection = createHubConnection(connection, logger);590 try {591 hubConnection.off("_", () => { });592 hubConnection.on("message", (t) => { });593 hubConnection.on("message", () => { });594 } finally {595 await hubConnection.stop();596 }597 });598 });599 it("using null/undefined for methodName or method no-ops", async () => {600 await VerifyLogger.run(async (logger) => {601 const warnings: string[] = [];602 const wrappingLogger = {603 log(logLevel: LogLevel, message: string) {604 if (logLevel === LogLevel.Warning) {605 warnings.push(message);606 }607 logger.log(logLevel, message);608 },609 } as ILogger;610 const connection = new TestConnection();611 const hubConnection = createHubConnection(connection, wrappingLogger);612 try {613 await hubConnection.start();614 hubConnection.on(null!, undefined!);615 hubConnection.on(undefined!, null!);616 hubConnection.on("message", null!);617 hubConnection.on("message", undefined!);618 hubConnection.on(null!, () => { });619 hubConnection.on(undefined!, () => { });620 // invoke a method to make sure we are not trying to use null/undefined621 connection.receive({622 arguments: [],623 invocationId: "0",624 nonblocking: true,625 target: "message",626 type: MessageType.Invocation,627 });628 expect(warnings).toEqual(["No client method with the name 'message' found."]);629 hubConnection.off(null!, undefined!);630 hubConnection.off(undefined!, null!);631 hubConnection.off("message", null!);632 hubConnection.off("message", undefined!);633 hubConnection.off(null!, () => { });634 hubConnection.off(undefined!, () => { });635 } finally {636 await hubConnection.stop();637 }638 });639 });640 });641 describe("stream", () => {642 it("sends an invocation", async () => {643 await VerifyLogger.run(async (logger) => {644 const connection = new TestConnection();645 const hubConnection = createHubConnection(connection, logger);646 try {647 await hubConnection.start();648 hubConnection.stream("testStream", "arg", 42);649 // Verify the message is sent (+ handshake)650 expect(connection.sentData.length).toBe(2);651 expect(JSON.parse(connection.sentData[1])).toEqual({652 arguments: [653 "arg",654 42,655 ],656 invocationId: connection.lastInvocationId,657 target: "testStream",658 type: MessageType.StreamInvocation,659 });660 // Close the connection661 await hubConnection.stop();662 } finally {663 await hubConnection.stop();664 }665 });666 });667 it("completes with an error when an error is yielded", async () => {668 await VerifyLogger.run(async (logger) => {669 const connection = new TestConnection();670 const hubConnection = createHubConnection(connection, logger);671 try {672 await hubConnection.start();673 const observer = new TestObserver();674 hubConnection.stream<any>("testMethod", "arg", 42)675 .subscribe(observer);676 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId, error: "foo" });677 await expect(observer.completed).rejects.toThrow("Error: foo");678 } finally {679 await hubConnection.stop();680 }681 });682 });683 it("completes the observer when a completion is received", async () => {684 await VerifyLogger.run(async (logger) => {685 const connection = new TestConnection();686 const hubConnection = createHubConnection(connection, logger);687 try {688 await hubConnection.start();689 const observer = new TestObserver();690 hubConnection.stream<any>("testMethod", "arg", 42)691 .subscribe(observer);692 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId });693 expect(await observer.completed).toEqual([]);694 } finally {695 await hubConnection.stop();696 }697 });698 });699 it("completes pending streams when stopped", async () => {700 await VerifyLogger.run(async (logger) => {701 const connection = new TestConnection();702 const hubConnection = createHubConnection(connection, logger);703 try {704 await hubConnection.start();705 const observer = new TestObserver();706 hubConnection.stream<any>("testMethod")707 .subscribe(observer);708 await hubConnection.stop();709 await expect(observer.completed).rejects.toThrow("Error: Invocation canceled due to connection being closed.");710 } finally {711 await hubConnection.stop();712 }713 });714 });715 it("completes pending streams when connection is lost", async () => {716 await VerifyLogger.run(async (logger) => {717 const connection = new TestConnection();718 const hubConnection = createHubConnection(connection, logger);719 try {720 await hubConnection.start();721 const observer = new TestObserver();722 hubConnection.stream<any>("testMethod")723 .subscribe(observer);724 // Typically this would be called by the transport725 connection.onclose!(new Error("Connection lost"));726 await expect(observer.completed).rejects.toThrow("Error: Connection lost");727 } finally {728 await hubConnection.stop();729 }730 });731 });732 it("yields items as they arrive", async () => {733 await VerifyLogger.run(async (logger) => {734 const connection = new TestConnection();735 const hubConnection = createHubConnection(connection, logger);736 try {737 await hubConnection.start();738 const observer = new TestObserver();739 hubConnection.stream<any>("testMethod")740 .subscribe(observer);741 connection.receive({ type: MessageType.StreamItem, invocationId: connection.lastInvocationId, item: 1 });742 expect(observer.itemsReceived).toEqual([1]);743 connection.receive({ type: MessageType.StreamItem, invocationId: connection.lastInvocationId, item: 2 });744 expect(observer.itemsReceived).toEqual([1, 2]);745 connection.receive({ type: MessageType.StreamItem, invocationId: connection.lastInvocationId, item: 3 });746 expect(observer.itemsReceived).toEqual([1, 2, 3]);747 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId });748 expect(await observer.completed).toEqual([1, 2, 3]);749 } finally {750 await hubConnection.stop();751 }752 });753 });754 it("does not require error function registered", async () => {755 await VerifyLogger.run(async (logger) => {756 const connection = new TestConnection();757 const hubConnection = createHubConnection(connection, logger);758 try {759 await hubConnection.start();760 hubConnection.stream("testMethod").subscribe(NullSubscriber.instance);761 // Typically this would be called by the transport762 // triggers observer.error()763 connection.onclose!(new Error("Connection lost"));764 } finally {765 await hubConnection.stop();766 }767 });768 });769 it("does not require complete function registered", async () => {770 await VerifyLogger.run(async (logger) => {771 const connection = new TestConnection();772 const hubConnection = createHubConnection(connection, logger);773 try {774 await hubConnection.start();775 hubConnection.stream("testMethod").subscribe(NullSubscriber.instance);776 // Send completion to trigger observer.complete()777 // Expectation is connection.receive will not to throw778 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId });779 } finally {780 await hubConnection.stop();781 }782 });783 });784 it("can be canceled", async () => {785 await VerifyLogger.run(async (logger) => {786 const connection = new TestConnection();787 const hubConnection = createHubConnection(connection, logger);788 try {789 await hubConnection.start();790 const observer = new TestObserver();791 const subscription = hubConnection.stream("testMethod")792 .subscribe(observer);793 connection.receive({ type: MessageType.StreamItem, invocationId: connection.lastInvocationId, item: 1 });794 expect(observer.itemsReceived).toEqual([1]);795 subscription.dispose();796 connection.receive({ type: MessageType.StreamItem, invocationId: connection.lastInvocationId, item: 2 });797 // Observer should no longer receive messages798 expect(observer.itemsReceived).toEqual([1]);799 // Verify the cancel is sent (+ handshake)800 expect(connection.sentData.length).toBe(3);801 expect(JSON.parse(connection.sentData[2])).toEqual({802 invocationId: connection.lastInvocationId,803 type: MessageType.CancelInvocation,804 });805 } finally {806 await hubConnection.stop();807 }808 });809 });810 });811 describe("onClose", () => {812 it("can have multiple callbacks", async () => {813 await VerifyLogger.run(async (logger) => {814 const connection = new TestConnection();815 const hubConnection = createHubConnection(connection, logger);816 try {817 let invocations = 0;818 hubConnection.onclose((e) => invocations++);819 hubConnection.onclose((e) => invocations++);820 // Typically this would be called by the transport821 connection.onclose!();822 expect(invocations).toBe(2);823 } finally {824 await hubConnection.stop();825 }826 });827 });828 it("callbacks receive error", async () => {829 await VerifyLogger.run(async (logger) => {830 const connection = new TestConnection();831 const hubConnection = createHubConnection(connection, logger);832 try {833 let error: Error | undefined;834 hubConnection.onclose((e) => error = e);835 // Typically this would be called by the transport836 connection.onclose!(new Error("Test error."));837 expect(error!.message).toBe("Test error.");838 } finally {839 await hubConnection.stop();840 }841 });842 });843 it("ignores null callbacks", async () => {844 await VerifyLogger.run(async (logger) => {845 const connection = new TestConnection();846 const hubConnection = createHubConnection(connection, logger);847 try {848 hubConnection.onclose(null!);849 hubConnection.onclose(undefined!);850 // Typically this would be called by the transport851 connection.onclose!();852 // expect no errors853 } finally {854 await hubConnection.stop();855 }856 });857 });858 it("state disconnected", async () => {859 await VerifyLogger.run(async (logger) => {860 const connection = new TestConnection();861 const hubConnection = createHubConnection(connection, logger);862 try {863 let state: HubConnectionState | undefined;864 hubConnection.onclose((e) => state = hubConnection.state);865 // Typically this would be called by the transport866 connection.onclose!();867 expect(state).toBe(HubConnectionState.Disconnected);868 } finally {869 await hubConnection.stop();870 }871 });872 });873 });874 describe("keepAlive", () => {875 it("can receive ping messages", async () => {876 await VerifyLogger.run(async (logger) => {877 // Receive the ping mid-invocation so we can see that the rest of the flow works fine878 const connection = new TestConnection();879 const hubConnection = createHubConnection(connection, logger);880 try {881 await hubConnection.start();882 const invokePromise = hubConnection.invoke("testMethod", "arg", 42);883 connection.receive({ type: MessageType.Ping });884 connection.receive({ type: MessageType.Completion, invocationId: connection.lastInvocationId, result: "foo" });885 expect(await invokePromise).toBe("foo");886 } finally {887 await hubConnection.stop();888 }889 });890 });891 it("does not terminate if messages are received", async () => {892 await VerifyLogger.run(async (logger) => {893 const connection = new TestConnection();894 const hubConnection = createHubConnection(connection, logger);895 try {896 hubConnection.serverTimeoutInMilliseconds = 200;897 const p = new PromiseSource<Error>();898 hubConnection.onclose((e) => p.resolve(e));899 await hubConnection.start();900 for (let i = 0; i < 6; i++) {901 await pingAndWait(connection);902 }903 await connection.stop();904 const error = await p.promise;905 expect(error).toBeUndefined();906 } finally {907 await hubConnection.stop();908 }909 });910 });911 it("terminates if no messages received within timeout interval", async () => {912 await VerifyLogger.run(async (logger) => {913 const connection = new TestConnection();914 const hubConnection = createHubConnection(connection, logger);915 try {916 hubConnection.serverTimeoutInMilliseconds = 100;917 const p = new PromiseSource<Error>();918 hubConnection.onclose((e) => p.resolve(e));919 await hubConnection.start();920 const error = await p.promise;921 expect(error).toEqual(new Error("Server timeout elapsed without receiving a message from the server."));922 } finally {923 await hubConnection.stop();924 }925 });926 });927 });928});929async function pingAndWait(connection: TestConnection): Promise<void> {930 await connection.receive({ type: MessageType.Ping });931 await delay(50);932}933class TestConnection implements IConnection {934 public readonly features: any = {};935 public onreceive: ((data: string | ArrayBuffer) => void) | null;936 public onclose: ((error?: Error) => void) | null;937 public sentData: any[];938 public lastInvocationId: string | null;939 private autoHandshake: boolean | null;940 constructor(autoHandshake: boolean = true) {941 this.onreceive = null;942 this.onclose = null;943 this.sentData = [];944 this.lastInvocationId = null;945 this.autoHandshake = autoHandshake;946 }947 public start(): Promise<void> {948 return Promise.resolve();949 }950 public send(data: any): Promise<void> {951 const invocation = TextMessageFormat.parse(data)[0];952 const parsedInvocation = JSON.parse(invocation);953 const invocationId = parsedInvocation.invocationId;954 if (parsedInvocation.protocol && parsedInvocation.version && this.autoHandshake) {955 this.receiveHandshakeResponse();956 }957 if (invocationId) {958 this.lastInvocationId = invocationId;959 }960 if (this.sentData) {961 this.sentData.push(invocation);962 } else {963 this.sentData = [invocation];964 }965 return Promise.resolve();966 }967 public stop(error?: Error): Promise<void> {968 if (this.onclose) {969 this.onclose(error);970 }971 return Promise.resolve();972 }973 public receiveHandshakeResponse(error?: string): void {974 this.receive({ error });975 }976 public receive(data: any): void {977 const payload = JSON.stringify(data);978 this.invokeOnReceive(TextMessageFormat.write(payload));979 }980 public receiveText(data: string) {981 this.invokeOnReceive(data);982 }983 public receiveBinary(data: ArrayBuffer) {984 this.invokeOnReceive(data);985 }986 private invokeOnReceive(data: string | ArrayBuffer) {987 if (this.onreceive) {988 this.onreceive(data);989 }990 }991}992class TestProtocol implements IHubProtocol {993 public readonly name: string = "TestProtocol";994 public readonly version: number = 1;995 public readonly transferFormat: TransferFormat;996 public onreceive: ((data: string | ArrayBuffer) => void) | null;997 constructor(transferFormat: TransferFormat) {998 this.transferFormat = transferFormat;999 this.onreceive = null;1000 }1001 public parseMessages(input: any): HubMessage[] {1002 if (this.onreceive) {1003 this.onreceive(input);1004 }1005 return [];1006 }1007 public writeMessage(message: HubMessage): any {1008 }1009}1010class TestObserver implements IStreamSubscriber<any> {1011 public readonly closed: boolean = false;1012 public itemsReceived: any[];1013 private itemsSource: PromiseSource<any[]>;1014 get completed(): Promise<any[]> {1015 return this.itemsSource.promise;1016 }1017 constructor() {1018 this.itemsReceived = [];1019 this.itemsSource = new PromiseSource<any[]>();1020 }1021 public next(value: any) {1022 this.itemsReceived.push(value);1023 }1024 public error(err: any) {1025 this.itemsSource.reject(new Error(err));1026 }1027 public complete() {1028 this.itemsSource.resolve(this.itemsReceived);1029 }1030}1031class NullSubscriber<T> implements IStreamSubscriber<T> {1032 public static instance: NullSubscriber<any> = new NullSubscriber();1033 private constructor() {1034 }1035 public next(value: T): void {1036 }1037 public error(err: any): void {1038 }1039 public complete(): void {1040 }...

Full Screen

Full Screen

HubConnectionTests.ts

Source:HubConnectionTests.ts Github

copy

Full Screen

1// Copyright (c) .NET Foundation. All rights reserved.2// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.3// This code uses a lot of `.then` instead of `await` and TSLint doesn't like it.4// tslint:disable:no-floating-promises5import { AbortError, DefaultHttpClient, HttpClient, HttpRequest, HttpResponse, HttpTransportType, HubConnectionBuilder, IHttpConnectionOptions, JsonHubProtocol, NullLogger } from "@aspnet/signalr";6import { MessagePackHubProtocol } from "@aspnet/signalr-protocol-msgpack";7import { eachTransport, eachTransportAndProtocol, ENDPOINT_BASE_HTTPS_URL, ENDPOINT_BASE_URL } from "./Common";8import "./LogBannerReporter";9import { TestLogger } from "./TestLogger";10const TESTHUBENDPOINT_URL = ENDPOINT_BASE_URL + "/testhub";11const TESTHUBENDPOINT_HTTPS_URL = ENDPOINT_BASE_HTTPS_URL + "/testhub";12const TESTHUB_NOWEBSOCKETS_ENDPOINT_URL = ENDPOINT_BASE_URL + "/testhub-nowebsockets";13// On slower CI machines, these tests sometimes take longer than 5s14jasmine.DEFAULT_TIMEOUT_INTERVAL = 10 * 1000;15const commonOptions: IHttpConnectionOptions = {16 logMessageContent: true,17};18function getConnectionBuilder(transportType?: HttpTransportType, url?: string, options?: IHttpConnectionOptions): HubConnectionBuilder {19 let actualOptions: IHttpConnectionOptions = options || {};20 if (transportType) {21 actualOptions.transport = transportType;22 }23 actualOptions = { ...actualOptions, ...commonOptions };24 return new HubConnectionBuilder()25 .configureLogging(TestLogger.instance)26 .withUrl(url || TESTHUBENDPOINT_URL, actualOptions);27}28describe("hubConnection", () => {29 eachTransportAndProtocol((transportType, protocol) => {30 describe("using " + protocol.name + " over " + HttpTransportType[transportType] + " transport", async () => {31 it("can invoke server method and receive result", (done) => {32 const message = "你好,世界!";33 const hubConnection = getConnectionBuilder(transportType)34 .withHubProtocol(protocol)35 .build();36 hubConnection.onclose((error) => {37 expect(error).toBeUndefined();38 done();39 });40 hubConnection.start().then(() => {41 hubConnection.invoke("Echo", message).then((result) => {42 expect(result).toBe(message);43 }).catch((e) => {44 fail(e);45 }).then(() => {46 hubConnection.stop();47 });48 }).catch((e) => {49 fail(e);50 done();51 });52 });53 // Run test in Node or Chrome, but not on macOS54 if ((process && process.platform !== "darwin") && (typeof navigator === "undefined" || navigator.userAgent.search("Chrome") !== -1)) {55 it("using https, can invoke server method and receive result", (done) => {56 const message = "你好,世界!";57 const hubConnection = getConnectionBuilder(transportType, TESTHUBENDPOINT_HTTPS_URL)58 .withHubProtocol(protocol)59 .build();60 hubConnection.onclose((error) => {61 expect(error).toBeUndefined();62 done();63 });64 hubConnection.start().then(() => {65 hubConnection.invoke("Echo", message).then((result) => {66 expect(result).toBe(message);67 }).catch((e) => {68 fail(e);69 }).then(() => {70 hubConnection.stop();71 });72 }).catch((e) => {73 fail(e);74 done();75 });76 });77 }78 it("can invoke server method non-blocking and not receive result", (done) => {79 const message = "你好,世界!";80 const hubConnection = getConnectionBuilder(transportType)81 .withHubProtocol(protocol)82 .build();83 hubConnection.onclose((error) => {84 expect(error).toBe(undefined);85 done();86 });87 hubConnection.start().then(() => {88 hubConnection.send("Echo", message).catch((e) => {89 fail(e);90 }).then(() => {91 hubConnection.stop();92 });93 }).catch((e) => {94 fail(e);95 done();96 });97 });98 it("can invoke server method structural object and receive structural result", (done) => {99 const hubConnection = getConnectionBuilder(transportType)100 .withHubProtocol(protocol)101 .build();102 hubConnection.on("CustomObject", (customObject) => {103 expect(customObject.Name).toBe("test");104 expect(customObject.Value).toBe(42);105 hubConnection.stop();106 });107 hubConnection.onclose((error) => {108 expect(error).toBe(undefined);109 done();110 });111 hubConnection.start().then(() => {112 hubConnection.send("SendCustomObject", { Name: "test", Value: 42 });113 }).catch((e) => {114 fail(e);115 done();116 });117 });118 it("can stream server method and receive result", (done) => {119 const hubConnection = getConnectionBuilder(transportType)120 .withHubProtocol(protocol)121 .build();122 hubConnection.onclose((error) => {123 expect(error).toBe(undefined);124 done();125 });126 const received: string[] = [];127 hubConnection.start().then(() => {128 hubConnection.stream<string>("Stream").subscribe({129 complete() {130 expect(received).toEqual(["a", "b", "c"]);131 hubConnection.stop();132 },133 error(err) {134 fail(err);135 hubConnection.stop();136 },137 next(item) {138 received.push(item);139 },140 });141 }).catch((e) => {142 fail(e);143 done();144 });145 });146 it("rethrows an exception from the server when invoking", (done) => {147 const errorMessage = "An unexpected error occurred invoking 'ThrowException' on the server. InvalidOperationException: An error occurred.";148 const hubConnection = getConnectionBuilder(transportType)149 .withHubProtocol(protocol)150 .build();151 hubConnection.start().then(() => {152 hubConnection.invoke("ThrowException", "An error occurred.").then(() => {153 // exception expected but none thrown154 fail();155 }).catch((e) => {156 expect(e.message).toBe(errorMessage);157 }).then(() => {158 return hubConnection.stop();159 }).then(() => {160 done();161 });162 }).catch((e) => {163 fail(e);164 done();165 });166 });167 it("throws an exception when invoking streaming method with invoke", (done) => {168 const hubConnection = getConnectionBuilder(transportType)169 .withHubProtocol(protocol)170 .build();171 hubConnection.start().then(() => {172 hubConnection.invoke("EmptyStream").then(() => {173 // exception expected but none thrown174 fail();175 }).catch((e) => {176 expect(e.message).toBe("The client attempted to invoke the streaming 'EmptyStream' method with a non-streaming invocation.");177 }).then(() => {178 return hubConnection.stop();179 }).then(() => {180 done();181 });182 }).catch((e) => {183 fail(e);184 done();185 });186 });187 it("throws an exception when receiving a streaming result for method called with invoke", (done) => {188 const hubConnection = getConnectionBuilder(transportType)189 .withHubProtocol(protocol)190 .build();191 hubConnection.start().then(() => {192 hubConnection.invoke("Stream").then(() => {193 // exception expected but none thrown194 fail();195 }).catch((e) => {196 expect(e.message).toBe("The client attempted to invoke the streaming 'Stream' method with a non-streaming invocation.");197 }).then(() => {198 return hubConnection.stop();199 }).then(() => {200 done();201 });202 }).catch((e) => {203 fail(e);204 done();205 });206 });207 it("rethrows an exception from the server when streaming", (done) => {208 const errorMessage = "An unexpected error occurred invoking 'StreamThrowException' on the server. InvalidOperationException: An error occurred.";209 const hubConnection = getConnectionBuilder(transportType)210 .withHubProtocol(protocol)211 .build();212 hubConnection.start().then(() => {213 hubConnection.stream("StreamThrowException", "An error occurred.").subscribe({214 complete() {215 hubConnection.stop();216 fail();217 },218 error(err) {219 expect(err.message).toEqual(errorMessage);220 hubConnection.stop();221 done();222 },223 next() {224 hubConnection.stop();225 fail();226 },227 });228 }).catch((e) => {229 fail(e);230 done();231 });232 });233 it("throws an exception when invoking hub method with stream", (done) => {234 const hubConnection = getConnectionBuilder(transportType)235 .withHubProtocol(protocol)236 .build();237 hubConnection.start().then(() => {238 hubConnection.stream("Echo", "42").subscribe({239 complete() {240 hubConnection.stop();241 fail();242 },243 error(err) {244 expect(err.message).toEqual("The client attempted to invoke the non-streaming 'Echo' method with a streaming invocation.");245 hubConnection.stop();246 done();247 },248 next() {249 hubConnection.stop();250 fail();251 },252 });253 }).catch((e) => {254 fail(e);255 done();256 });257 });258 it("can receive server calls", (done) => {259 const hubConnection = getConnectionBuilder(transportType)260 .withHubProtocol(protocol)261 .build();262 const message = "你好 SignalR!";263 // client side method names are case insensitive264 let methodName = "message";265 const idx = Math.floor(Math.random() * (methodName.length - 1));266 methodName = methodName.substr(0, idx) + methodName[idx].toUpperCase() + methodName.substr(idx + 1);267 hubConnection.on(methodName, (msg) => {268 expect(msg).toBe(message);269 done();270 });271 hubConnection.start()272 .then(() => {273 return hubConnection.invoke("InvokeWithString", message);274 })275 .then(() => {276 return hubConnection.stop();277 })278 .catch((e) => {279 fail(e);280 done();281 });282 });283 it("can receive server calls without rebinding handler when restarted", (done) => {284 const hubConnection = getConnectionBuilder(transportType)285 .withHubProtocol(protocol)286 .build();287 const message = "你好 SignalR!";288 // client side method names are case insensitive289 let methodName = "message";290 const idx = Math.floor(Math.random() * (methodName.length - 1));291 methodName = methodName.substr(0, idx) + methodName[idx].toUpperCase() + methodName.substr(idx + 1);292 let closeCount = 0;293 let invocationCount = 0;294 hubConnection.onclose((e) => {295 expect(e).toBeUndefined();296 closeCount += 1;297 if (closeCount === 1) {298 // Reconnect299 hubConnection.start()300 .then(() => {301 return hubConnection.invoke("InvokeWithString", message);302 })303 .then(() => {304 return hubConnection.stop();305 })306 .catch((error) => {307 fail(error);308 done();309 });310 } else {311 expect(invocationCount).toBe(2);312 done();313 }314 });315 hubConnection.on(methodName, (msg) => {316 expect(msg).toBe(message);317 invocationCount += 1;318 });319 hubConnection.start()320 .then(() => {321 return hubConnection.invoke("InvokeWithString", message);322 })323 .then(() => {324 return hubConnection.stop();325 })326 .catch((e) => {327 fail(e);328 done();329 });330 });331 it("closed with error if hub cannot be created", (done) => {332 const hubConnection = getConnectionBuilder(transportType, ENDPOINT_BASE_URL + "/uncreatable")333 .withHubProtocol(protocol)334 .build();335 hubConnection.onclose((error) => {336 expect(error!.message).toEqual("Server returned an error on close: Connection closed with an error. InvalidOperationException: Unable to resolve service for type 'System.Object' while attempting to activate 'FunctionalTests.UncreatableHub'.");337 done();338 });339 hubConnection.start();340 });341 it("can handle different types", (done) => {342 const hubConnection = getConnectionBuilder(transportType)343 .withHubProtocol(protocol)344 .build();345 hubConnection.onclose((error) => {346 expect(error).toBe(undefined);347 done();348 });349 const complexObject = {350 ByteArray: protocol.name === "json"351 ? "aGVsbG8="352 : new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f]),353 DateTime: protocol.name === "json"354 ? "2002-04-01T10:20:15Z"355 : new Date(Date.UTC(2002, 3, 1, 10, 20, 15)), // Apr 1, 2002, 10:20:15am UTC356 GUID: "00010203-0405-0607-0706-050403020100",357 IntArray: [0x01, 0x02, 0x03, 0xff],358 String: "Hello, World!",359 };360 hubConnection.start()361 .then(() => {362 return hubConnection.invoke("EchoComplexObject", complexObject);363 })364 .then((value) => {365 if (protocol.name === "messagepack") {366 // msgpack5 creates a Buffer for byte arrays and jasmine fails to compare a Buffer367 // and a Uint8Array even though Buffer instances are also Uint8Array instances368 value.ByteArray = new Uint8Array(value.ByteArray);369 }370 expect(value).toEqual(complexObject);371 })372 .then(() => {373 hubConnection.stop();374 })375 .catch((e) => {376 fail(e);377 done();378 });379 });380 it("can receive different types", (done) => {381 const hubConnection = getConnectionBuilder(transportType)382 .withHubProtocol(protocol)383 .build();384 hubConnection.onclose((error) => {385 expect(error).toBe(undefined);386 done();387 });388 const complexObject = {389 ByteArray: protocol.name === "json"390 ? "AQID"391 : new Uint8Array([0x1, 0x2, 0x3]),392 DateTime: protocol.name === "json"393 ? "2000-01-01T00:00:00Z"394 : new Date(Date.UTC(2000, 0, 1)),395 GUID: "00010203-0405-0607-0706-050403020100",396 IntArray: [0x01, 0x02, 0x03],397 String: "hello world",398 };399 hubConnection.start()400 .then(() => {401 return hubConnection.invoke("SendComplexObject");402 })403 .then((value) => {404 if (protocol.name === "messagepack") {405 // msgpack5 creates a Buffer for byte arrays and jasmine fails to compare a Buffer406 // and a Uint8Array even though Buffer instances are also Uint8Array instances407 value.ByteArray = new Uint8Array(value.ByteArray);408 }409 expect(value).toEqual(complexObject);410 })411 .then(() => {412 hubConnection.stop();413 })414 .catch((e) => {415 fail(e);416 done();417 });418 });419 it("can be restarted", (done) => {420 const message = "你好,世界!";421 const hubConnection = getConnectionBuilder(transportType)422 .withHubProtocol(protocol)423 .build();424 let closeCount = 0;425 hubConnection.onclose((error) => {426 expect(error).toBe(undefined);427 // Start and invoke again428 if (closeCount === 0) {429 closeCount += 1;430 hubConnection.start().then(() => {431 hubConnection.invoke("Echo", message).then((result) => {432 expect(result).toBe(message);433 }).catch((e) => {434 fail(e);435 }).then(() => {436 hubConnection.stop();437 });438 }).catch((e) => {439 fail(e);440 done();441 });442 } else {443 done();444 }445 });446 hubConnection.start().then(() => {447 hubConnection.invoke("Echo", message).then((result) => {448 expect(result).toBe(message);449 }).catch((e) => {450 fail(e);451 }).then(() => {452 hubConnection.stop();453 });454 }).catch((e) => {455 fail(e);456 done();457 });458 });459 });460 });461 eachTransport((transportType) => {462 describe("over " + HttpTransportType[transportType] + " transport", () => {463 it("can connect to hub with authorization", async (done) => {464 const message = "你好,世界!";465 try {466 const jwtToken = await getJwtToken(ENDPOINT_BASE_URL + "/generateJwtToken");467 const hubConnection = getConnectionBuilder(transportType, ENDPOINT_BASE_URL + "/authorizedhub", {468 accessTokenFactory: () => jwtToken,469 }).build();470 hubConnection.onclose((error) => {471 expect(error).toBe(undefined);472 done();473 });474 await hubConnection.start();475 const response = await hubConnection.invoke("Echo", message);476 expect(response).toEqual(message);477 await hubConnection.stop();478 done();479 } catch (err) {480 fail(err);481 done();482 }483 });484 it("can connect to hub with authorization using async token factory", async (done) => {485 const message = "你好,世界!";486 try {487 const hubConnection = getConnectionBuilder(transportType, ENDPOINT_BASE_URL + "/authorizedhub", {488 accessTokenFactory: () => getJwtToken(ENDPOINT_BASE_URL + "/generateJwtToken"),489 }).build();490 hubConnection.onclose((error) => {491 expect(error).toBe(undefined);492 done();493 });494 await hubConnection.start();495 const response = await hubConnection.invoke("Echo", message);496 expect(response).toEqual(message);497 await hubConnection.stop();498 done();499 } catch (err) {500 fail(err);501 done();502 }503 });504 if (transportType !== HttpTransportType.LongPolling) {505 it("terminates if no messages received within timeout interval", (done) => {506 const hubConnection = getConnectionBuilder(transportType).build();507 hubConnection.serverTimeoutInMilliseconds = 100;508 hubConnection.start().then(() => {509 hubConnection.onclose((error) => {510 expect(error).toEqual(new Error("Server timeout elapsed without receiving a message from the server."));511 done();512 });513 });514 });515 }516 it("preserves cookies between requests", async (done) => {517 const hubConnection = getConnectionBuilder(transportType).build();518 await hubConnection.start();519 const cookieValue = await hubConnection.invoke<string>("GetCookie", "testCookie");520 const cookieValue2 = await hubConnection.invoke<string>("GetCookie", "testCookie2");521 expect(cookieValue).toEqual("testValue");522 expect(cookieValue2).toEqual("testValue2");523 await hubConnection.stop();524 done();525 });526 it("expired cookies are not preserved", async (done) => {527 const hubConnection = getConnectionBuilder(transportType).build();528 await hubConnection.start();529 const cookieValue = await hubConnection.invoke<string>("GetCookie", "expiredCookie");530 expect(cookieValue).toBeNull();531 await hubConnection.stop();532 done();533 });534 });535 });536 if (typeof EventSource !== "undefined") {537 it("allows Server-Sent Events when negotiating for JSON protocol", async (done) => {538 const hubConnection = getConnectionBuilder(undefined, TESTHUB_NOWEBSOCKETS_ENDPOINT_URL)539 .withHubProtocol(new JsonHubProtocol())540 .build();541 try {542 await hubConnection.start();543 // Check what transport was used by asking the server to tell us.544 expect(await hubConnection.invoke("GetActiveTransportName")).toEqual("ServerSentEvents");545 await hubConnection.stop();546 done();547 } catch (e) {548 fail(e);549 }550 });551 }552 it("skips Server-Sent Events when negotiating for MessagePack protocol", async (done) => {553 const hubConnection = getConnectionBuilder(undefined, TESTHUB_NOWEBSOCKETS_ENDPOINT_URL)554 .withHubProtocol(new MessagePackHubProtocol())555 .build();556 try {557 await hubConnection.start();558 // Check what transport was used by asking the server to tell us.559 expect(await hubConnection.invoke("GetActiveTransportName")).toEqual("LongPolling");560 await hubConnection.stop();561 done();562 } catch (e) {563 fail(e);564 }565 });566 it("transport falls back from WebSockets to SSE or LongPolling", async (done) => {567 // Skip test on Node as there will always be a WebSockets implementation on Node568 if (typeof window === "undefined") {569 done();570 return;571 }572 // Replace Websockets with a function that just573 // throws to force fallback.574 const oldWebSocket = (window as any).WebSocket;575 (window as any).WebSocket = () => {576 throw new Error("Kick rocks");577 };578 const hubConnection = getConnectionBuilder()579 .withHubProtocol(new JsonHubProtocol())580 .build();581 try {582 await hubConnection.start();583 // Make sure that we connect with SSE or LongPolling after Websockets fail584 const transportName = await hubConnection.invoke("GetActiveTransportName");585 expect(transportName === "ServerSentEvents" || transportName === "LongPolling").toBe(true);586 await hubConnection.stop();587 } catch (e) {588 fail(e);589 } finally {590 (window as any).WebSocket = oldWebSocket;591 done();592 }593 });594 it("over LongPolling it sends DELETE request and waits for poll to terminate", async (done) => {595 // Create an HTTP client to capture the poll596 const defaultClient = new DefaultHttpClient(TestLogger.instance);597 class TestClient extends HttpClient {598 public pollPromise: Promise<HttpResponse> | null;599 constructor() {600 super();601 this.pollPromise = null;602 }603 public send(request: HttpRequest): Promise<HttpResponse> {604 if (request.method === "GET") {605 this.pollPromise = defaultClient.send(request);606 return this.pollPromise;607 }608 return defaultClient.send(request);609 }610 }611 const testClient = new TestClient();612 const hubConnection = getConnectionBuilder(HttpTransportType.LongPolling, TESTHUBENDPOINT_URL, {613 httpClient: testClient,614 }).build();615 try {616 await hubConnection.start();617 expect(testClient.pollPromise).not.toBeNull();618 // Stop the connection and await the poll terminating619 const stopPromise = hubConnection.stop();620 try {621 await testClient.pollPromise;622 } catch (e) {623 if (e instanceof AbortError) {624 // Poll request may have been aborted625 } else {626 throw e;627 }628 }629 await stopPromise;630 } catch (e) {631 fail(e);632 } finally {633 done();634 }635 });636 it("populates the Content-Type header when sending XMLHttpRequest", async (done) => {637 // Skip test on Node as this header isn't set (it was added for React-Native)638 if (typeof window === "undefined") {639 done();640 return;641 }642 const hubConnection = getConnectionBuilder(HttpTransportType.LongPolling, TESTHUB_NOWEBSOCKETS_ENDPOINT_URL)643 .withHubProtocol(new JsonHubProtocol())644 .build();645 try {646 await hubConnection.start();647 // Check what transport was used by asking the server to tell us.648 expect(await hubConnection.invoke("GetActiveTransportName")).toEqual("LongPolling");649 // Check to see that the Content-Type header is set the expected value650 expect(await hubConnection.invoke("GetContentTypeHeader")).toEqual("text/plain;charset=UTF-8");651 await hubConnection.stop();652 done();653 } catch (e) {654 fail(e);655 }656 });657 function getJwtToken(url: string): Promise<string> {658 return new Promise((resolve, reject) => {659 const httpClient = new DefaultHttpClient(NullLogger.instance);660 httpClient.get(url).then((response) => {661 if (response.statusCode >= 200 && response.statusCode < 300) {662 resolve(response.content as string);663 } else {664 reject(new Error(response.statusText));665 }666 });667 });668 }...

Full Screen

Full Screen

board.component.ts

Source:board.component.ts Github

copy

Full Screen

...69 (data: Array<PupilHub>) => {70 // Convert each raw hub representation to the PupilHub object71 // to populate the array72 data.map(raw =>73 this.pupilHubs.push(new PupilHub(raw)));74 // Sort the pupil's hubs75 this.sortPupilHubs();76 },77 (error: HttpErrorResponse) => {78 this.toastr.error(79 'Une erreur est survenue lors de la récupération de vos hubs',80 'Erreur de connexion');81 });82 }83 public onJoinHub() {84 // Value of the input field in the modal85 const invitationLink: string = this.f.inputJoinHub.value;86 // Value of the hub's hash87 const hubHash = invitationLink.split('?link=')[1];88 // Check if a hash has been found89 // If no hash was found display an error90 if (!hubHash) {91 this.toastr.error(92 'Veuillez rentrer un lien valide',93 'Erreur lors de l\'inscription');94 // Clear the field on invalid input95 this.f.inputJoinHub.setValue('');96 // Else a hash has been found97 } else {98 this.hubService.joinHub(hubHash)99 .subscribe(_ => {100 // Display information on success101 this.toastr.success('Vous pouvez maintenant accéder au hub', 'Hub rejoint !');102 // Reset the modal on success103 this.f.inputJoinHub.setValue('');104 document.getElementById('closeHubJoinModal').click();105 // Add the new hub to the list106 this.hubService.getHubByLink(hubHash)107 .subscribe((hub: PupilHub) => {108 this.pupilHubs.push(hub);109 // Sort the pupil's hubs110 this.sortPupilHubs();111 },112 () => {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1var request = require('request');2var async = require('async');3var fs = require('fs');4var cheerio = require('cheerio');5var json2csv = require('json2csv');6var fields = ['SKU', 'Name', 'Brand', 'Price', 'Description', 'URL', 'ImageURL'];7var data = [];

Full Screen

Using AI Code Generation

copy

Full Screen

1var request = require('request');2var http = require('http');3var express = require('express');4var app = express();5var bodyParser = require('body-parser');6var search = require('./search.js');7var async = require('async');8var fs = require('fs');9var path = require('path');10var ejs = require('ejs');11app.set('view engine', 'ejs');12app.set('views', path.join(__dirname, '/views'));13app.use(express.static(path.join(__dirname, '/public')));14app.use(bodyParser.urlencoded({ extended: true }));15app.use(bodyParser.json());16app.get('/', function(req, res) {17 res.render('index', { products: [] });18});19app.post('/search', function(req, res) {20 var searchTerm = req.body.searchTerm;21 search.getProducts(searchTerm, function(err, products) {22 if (err) {23 console.log(err);24 } else {25 res.render('index', { products: products });26 }27 });28});29app.get('/products/:sku', function(req, res) {30 var sku = req.params.sku;31 search.getProductDetails(sku, function(err, details) {32 if (err) {33 console.log(err);34 } else {35 res.render('details', { details: details });36 }37 });38});39app.get('/stores/:sku', function(req, res) {40 var sku = req.params.sku;41 search.getStores(sku, function(err, stores) {42 if (err) {43 console.log(err);44 } else {45 res.render('stores', { stores: stores });46 }47 });48});49app.get('/stores/:storeNumber/:sku', function(req, res) {50 var storeNumber = req.params.storeNumber;51 var sku = req.params.sku;52 search.getStoreDetails(storeNumber, sku, function(err, details) {53 if (err) {54 console.log(err);55 } else {56 res.render('storeDetails', { details: details });57 }58 });59});60app.listen(3000, function() {61 console.log('Example app listening on port 3000!');62});

Full Screen

Using AI Code Generation

copy

Full Screen

1var config = require('./config.js');2var api_key = config.api_key;3var hub_id = config.hub_id;4var request = require('request');5var options = {6 headers: {7 }8};9request(options, function (error, response, body) {10 if (!error && response.statusCode == 200) {11 var info = JSON.parse(body);12 var num_stores = info.stores.length;13 for (var i = 0; i < num_stores; i++) {14 var store_id = info.stores[i].storeId;15 var store_type = info.stores[i].storeType;16 var store_name = info.stores[i].name;17 var store_phone = info.stores[i].phone;18 var store_city = info.stores[i].city;19 var store_distance = info.stores[i].distance;20 console.log(store_id + " " + store_type + " " + store_name + " " + store_phone + " " + store_city + " " + store_distance + " miles");21 }22 }23});

Full Screen

Using AI Code Generation

copy

Full Screen

1var bestbuy = require('./bestbuy.js');2var bestBuy = new bestbuy('yourBestBuyAPIKey');3bestBuy.products('sku=1234567', function(err, data) {4 if (err) {5 console.log(err);6 } else {7 console.log(data);8 }9});10### BestBuy(apiKey)11### BestBuy.products(query, callback)12bestBuy.products('sku=1234567', function(err, data) {13 if (err) {14 console.log(err);15 } else {16 console.log(data);17 }18});19bestBuy.products('sku=1234567,name="TV"', function(err, data) {20 if (err) {21 console.log(err);22 } else {23 console.log(data);24 }25});26bestBuy.products('sku=1234567,name="TV",salePrice=100', function(err, data) {27 if (err) {28 console.log(err);29 } else {30 console.log(data);31 }32});33bestBuy.products('sku=1234567,name="TV",salePrice=100,categoryPath.id=abcat0101000', function(err, data) {34 if (err) {35 console.log(err);36 } else {37 console.log(data);38 }39});40### BestBuy.stores(query, callback)41bestBuy.stores('storeId=1234',

Full Screen

Using AI Code Generation

copy

Full Screen

1var bb = require('bestbuy')(process.env.BBY_API_KEY);2bb.categories('cat00000', {show: 'name,products.name'})3 .then(function(data) {4 console.log(data.products);5 })6 .catch(function(err) {7 console.log(err);8 });

Full Screen

Using AI Code Generation

copy

Full Screen

1var request = require('request');2var async = require('async');3var fs = require('fs');4var _ = require('underscore');5var apikey = '3h7qz5p5j8m5n5y5n5y5h5y5';6var apiurl3 = '))?format=json&show=sku,name,salePrice,regularPrice,shortDescription,image,customerReviewAverage,customerReviewCount,shipping,shippingCost,manufacturer&apiKey=';7function getproducts(callback) {8 async.waterfall([9 function(callback) {10 request(apiurl + '?show=sku,name,salePrice,regular

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Best automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful