|
1 | 1 | import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; |
2 | 2 |
|
3 | | -import { Json, JRPCParams, JRPCRequest } from "../../src"; |
4 | | -import { stringify } from "../../src/utils/jrpc"; |
| 3 | +import { JRPCParams, JRPCRequest, Json } from "../../src"; |
5 | 4 | import { JsonRpcError } from "../../src/jrpc/errors"; |
6 | 5 | import { |
7 | 6 | deepClone, |
8 | 7 | deserializeError, |
9 | 8 | fromLegacyRequest, |
10 | 9 | makeContext, |
11 | 10 | propagateToContext, |
| 11 | + propagateToMutableRequest, |
12 | 12 | propagateToRequest, |
13 | 13 | } from "../../src/jrpc/v2/compatibility-utils"; |
14 | 14 | import { MiddlewareContext } from "../../src/jrpc/v2/MiddlewareContext"; |
| 15 | +import { stringify } from "../../src/utils/jrpc"; |
15 | 16 |
|
16 | 17 | const jsonrpc = "2.0" as const; |
17 | 18 |
|
@@ -340,6 +341,85 @@ describe("compatibility-utils", () => { |
340 | 341 | }); |
341 | 342 | }); |
342 | 343 |
|
| 344 | + describe("propagateToMutableRequest", () => { |
| 345 | + it("returns a mutable object from a frozen request", () => { |
| 346 | + const request = Object.freeze({ |
| 347 | + jsonrpc, |
| 348 | + method: "test_method", |
| 349 | + params: Object.freeze([1, 2, 3]), |
| 350 | + id: 1, |
| 351 | + }); |
| 352 | + const context = new MiddlewareContext<Record<string, unknown>>(); |
| 353 | + context.set("extraProp", "value"); |
| 354 | + |
| 355 | + const result = propagateToMutableRequest(request, context); |
| 356 | + |
| 357 | + expect(Object.isFrozen(result)).toBe(false); |
| 358 | + result.newKey = "can assign"; |
| 359 | + expect(result.newKey).toBe("can assign"); |
| 360 | + }); |
| 361 | + |
| 362 | + it("does not mutate the original frozen request", () => { |
| 363 | + const request = Object.freeze({ |
| 364 | + jsonrpc, |
| 365 | + method: "test_method", |
| 366 | + params: Object.freeze([1, 2, 3]), |
| 367 | + id: 1, |
| 368 | + }); |
| 369 | + const context = new MiddlewareContext<Record<string, unknown>>(); |
| 370 | + context.set("extraProp", "value"); |
| 371 | + |
| 372 | + propagateToMutableRequest(request, context); |
| 373 | + |
| 374 | + expect(request).toStrictEqual({ |
| 375 | + jsonrpc, |
| 376 | + method: "test_method", |
| 377 | + params: [1, 2, 3], |
| 378 | + id: 1, |
| 379 | + }); |
| 380 | + expect("extraProp" in request).toBe(false); |
| 381 | + }); |
| 382 | + |
| 383 | + it("propagates context properties onto the mutable clone of a frozen request", () => { |
| 384 | + const request = Object.freeze({ |
| 385 | + jsonrpc, |
| 386 | + method: "test_method", |
| 387 | + params: Object.freeze([1]), |
| 388 | + id: 42, |
| 389 | + }); |
| 390 | + const context = new MiddlewareContext<Record<string, unknown>>(); |
| 391 | + context.set("extraProp", "value"); |
| 392 | + context.set("anotherProp", { nested: true }); |
| 393 | + |
| 394 | + const result = propagateToMutableRequest(request, context); |
| 395 | + |
| 396 | + expect(result).toStrictEqual({ |
| 397 | + jsonrpc, |
| 398 | + method: "test_method", |
| 399 | + params: [1], |
| 400 | + id: 42, |
| 401 | + extraProp: "value", |
| 402 | + anotherProp: { nested: true }, |
| 403 | + }); |
| 404 | + }); |
| 405 | + |
| 406 | + it("produces deeply mutable params from a frozen request", () => { |
| 407 | + const request = Object.freeze({ |
| 408 | + jsonrpc, |
| 409 | + method: "test_method", |
| 410 | + params: Object.freeze([Object.freeze({ a: 1 }), 2]), |
| 411 | + id: 1, |
| 412 | + }); |
| 413 | + const context = new MiddlewareContext(); |
| 414 | + |
| 415 | + const result = propagateToMutableRequest(request, context); |
| 416 | + |
| 417 | + expect(Object.isFrozen(result.params)).toBe(false); |
| 418 | + (result.params as unknown[])[0] = "replaced"; |
| 419 | + expect((result.params as unknown[])[0]).toBe("replaced"); |
| 420 | + }); |
| 421 | + }); |
| 422 | + |
343 | 423 | describe("deserializeError", () => { |
344 | 424 | // Requires some special handling due to the possible existence or |
345 | 425 | // non-existence of Error.isError |
|
0 commit comments