rivetkit 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/schemas/actor-persist/v1.ts +21 -24
- package/dist/schemas/client-protocol/v1.ts +6 -0
- package/dist/tsup/actor/errors.cjs +10 -2
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +17 -4
- package/dist/tsup/actor/errors.d.ts +17 -4
- package/dist/tsup/actor/errors.js +11 -3
- package/dist/tsup/{chunk-6PDXBYI5.js → chunk-3F2YSRJL.js} +8 -23
- package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
- package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
- package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
- package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
- package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
- package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-6LJT3QRL.cjs} +39 -25
- package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
- package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-GICQ3YCU.cjs} +143 -141
- package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
- package/dist/tsup/{chunk-FLMTTN27.js → chunk-H26RP6GD.js} +15 -8
- package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
- package/dist/tsup/chunk-HI3HWJRC.js +20 -0
- package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
- package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-HLLF4B4Q.js} +116 -114
- package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
- package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-IH6CKNDW.cjs} +12 -27
- package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
- package/dist/tsup/chunk-LV2S3OU3.js +250 -0
- package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
- package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LWNKVZG5.cjs} +20 -13
- package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
- package/dist/tsup/{chunk-INGJP237.js → chunk-NFU2BBT5.js} +102 -43
- package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
- package/dist/tsup/{chunk-3H7O2A7I.js → chunk-PQY7KKTL.js} +33 -19
- package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
- package/dist/tsup/{chunk-PO4VLDWA.js → chunk-QK72M5JB.js} +3 -5
- package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
- package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-QNNXFOQV.cjs} +3 -5
- package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
- package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-SBHHJ6QS.cjs} +102 -43
- package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
- package/dist/tsup/chunk-TQ62L3X7.js +325 -0
- package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
- package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
- package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
- package/dist/tsup/client/mod.cjs +10 -10
- package/dist/tsup/client/mod.d.cts +7 -13
- package/dist/tsup/client/mod.d.ts +7 -13
- package/dist/tsup/client/mod.js +9 -9
- package/dist/tsup/common/log.cjs +12 -4
- package/dist/tsup/common/log.cjs.map +1 -1
- package/dist/tsup/common/log.d.cts +23 -17
- package/dist/tsup/common/log.d.ts +23 -17
- package/dist/tsup/common/log.js +15 -7
- package/dist/tsup/common/websocket.cjs +5 -5
- package/dist/tsup/common/websocket.js +4 -4
- package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
- package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
- package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BI-6UIBJ.d.ts} +196 -226
- package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-Dyd4NLGW.d.cts} +196 -226
- package/dist/tsup/driver-helpers/mod.cjs +6 -9
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +5 -6
- package/dist/tsup/driver-helpers/mod.d.ts +5 -6
- package/dist/tsup/driver-helpers/mod.js +6 -9
- package/dist/tsup/driver-test-suite/mod.cjs +155 -1363
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +11 -5
- package/dist/tsup/driver-test-suite/mod.d.ts +11 -5
- package/dist/tsup/driver-test-suite/mod.js +876 -2084
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -8
- package/dist/tsup/inspector/mod.cjs.map +1 -1
- package/dist/tsup/inspector/mod.d.cts +3 -3
- package/dist/tsup/inspector/mod.d.ts +3 -3
- package/dist/tsup/inspector/mod.js +8 -10
- package/dist/tsup/mod.cjs +9 -15
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +47 -42
- package/dist/tsup/mod.d.ts +47 -42
- package/dist/tsup/mod.js +10 -16
- package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-BTe_Rsdn.d.cts} +2 -3
- package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-CBSrKHmo.d.ts} +2 -3
- package/dist/tsup/test/mod.cjs +10 -14
- package/dist/tsup/test/mod.cjs.map +1 -1
- package/dist/tsup/test/mod.d.cts +4 -5
- package/dist/tsup/test/mod.d.ts +4 -5
- package/dist/tsup/test/mod.js +9 -13
- package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
- package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
- package/dist/tsup/utils.cjs +3 -3
- package/dist/tsup/utils.d.cts +1 -1
- package/dist/tsup/utils.d.ts +1 -1
- package/dist/tsup/utils.js +2 -2
- package/package.json +4 -4
- package/src/actor/action.ts +1 -5
- package/src/actor/config.ts +27 -295
- package/src/actor/connection.ts +9 -12
- package/src/actor/context.ts +1 -4
- package/src/actor/definition.ts +7 -11
- package/src/actor/errors.ts +97 -35
- package/src/actor/generic-conn-driver.ts +28 -16
- package/src/actor/instance.ts +177 -133
- package/src/actor/log.ts +4 -13
- package/src/actor/mod.ts +0 -5
- package/src/actor/protocol/old.ts +42 -26
- package/src/actor/protocol/serde.ts +1 -1
- package/src/actor/router-endpoints.ts +41 -38
- package/src/actor/router.ts +20 -18
- package/src/actor/unstable-react.ts +1 -1
- package/src/actor/utils.ts +6 -2
- package/src/client/actor-common.ts +1 -1
- package/src/client/actor-conn.ts +152 -91
- package/src/client/actor-handle.ts +85 -25
- package/src/client/actor-query.ts +65 -0
- package/src/client/client.ts +29 -98
- package/src/client/config.ts +44 -0
- package/src/client/errors.ts +1 -0
- package/src/client/log.ts +2 -4
- package/src/client/mod.ts +16 -12
- package/src/client/raw-utils.ts +82 -25
- package/src/client/utils.ts +5 -3
- package/src/common/fake-event-source.ts +10 -9
- package/src/common/inline-websocket-adapter2.ts +39 -30
- package/src/common/log.ts +176 -101
- package/src/common/logfmt.ts +21 -30
- package/src/common/router.ts +12 -19
- package/src/common/utils.ts +27 -13
- package/src/common/websocket.ts +0 -1
- package/src/driver-helpers/mod.ts +1 -1
- package/src/driver-test-suite/log.ts +1 -3
- package/src/driver-test-suite/mod.ts +86 -60
- package/src/driver-test-suite/tests/actor-handle.ts +33 -0
- package/src/driver-test-suite/tests/manager-driver.ts +5 -3
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
- package/src/driver-test-suite/tests/request-access.ts +112 -126
- package/src/driver-test-suite/utils.ts +13 -10
- package/src/drivers/default.ts +7 -4
- package/src/drivers/engine/actor-driver.ts +22 -13
- package/src/drivers/engine/config.ts +2 -10
- package/src/drivers/engine/kv.ts +1 -1
- package/src/drivers/engine/log.ts +1 -3
- package/src/drivers/engine/mod.ts +2 -3
- package/src/drivers/file-system/actor.ts +1 -1
- package/src/drivers/file-system/global-state.ts +33 -20
- package/src/drivers/file-system/log.ts +1 -3
- package/src/drivers/file-system/manager.ts +31 -8
- package/src/inspector/config.ts +9 -4
- package/src/inspector/log.ts +1 -1
- package/src/inspector/manager.ts +2 -2
- package/src/inspector/utils.ts +1 -1
- package/src/manager/driver.ts +10 -2
- package/src/manager/hono-websocket-adapter.ts +21 -12
- package/src/manager/log.ts +2 -4
- package/src/manager/mod.ts +1 -1
- package/src/manager/router.ts +277 -1657
- package/src/manager-api/routes/actors-create.ts +16 -0
- package/src/manager-api/routes/actors-delete.ts +4 -0
- package/src/manager-api/routes/actors-get-by-id.ts +7 -0
- package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
- package/src/manager-api/routes/actors-get.ts +7 -0
- package/src/manager-api/routes/common.ts +18 -0
- package/src/mod.ts +0 -2
- package/src/registry/config.ts +1 -1
- package/src/registry/log.ts +2 -4
- package/src/registry/mod.ts +57 -24
- package/src/registry/run-config.ts +31 -33
- package/src/registry/serve.ts +4 -5
- package/src/remote-manager-driver/actor-http-client.ts +72 -0
- package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
- package/src/remote-manager-driver/api-endpoints.ts +79 -0
- package/src/remote-manager-driver/api-utils.ts +43 -0
- package/src/remote-manager-driver/log.ts +5 -0
- package/src/remote-manager-driver/mod.ts +274 -0
- package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
- package/src/serde.ts +8 -2
- package/src/test/log.ts +1 -3
- package/src/test/mod.ts +17 -16
- package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
- package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
- package/dist/tsup/chunk-3H7O2A7I.js.map +0 -1
- package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
- package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
- package/dist/tsup/chunk-4NSUQZ2H.js.map +0 -1
- package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
- package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
- package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
- package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
- package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
- package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
- package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
- package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
- package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
- package/dist/tsup/chunk-INGJP237.js.map +0 -1
- package/dist/tsup/chunk-KJCJLKRM.js +0 -116
- package/dist/tsup/chunk-KJCJLKRM.js.map +0 -1
- package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
- package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
- package/dist/tsup/chunk-O2MBYIXO.cjs +0 -2857
- package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
- package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
- package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
- package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
- package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
- package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
- package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
- package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
- package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
- package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
- package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
- package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
- package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
- package/dist/tsup/chunk-UVUPOS46.js +0 -230
- package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
- package/dist/tsup/chunk-VRRHBNJC.js +0 -189
- package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
- package/dist/tsup/chunk-XFSS33EQ.js +0 -202
- package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
- package/src/client/http-client-driver.ts +0 -326
- package/src/driver-test-suite/test-inline-client-driver.ts +0 -402
- package/src/driver-test-suite/tests/actor-auth.ts +0 -591
- package/src/drivers/engine/api-endpoints.ts +0 -128
- package/src/drivers/engine/api-utils.ts +0 -70
- package/src/drivers/engine/manager-driver.ts +0 -391
- package/src/inline-client-driver/log.ts +0 -7
- package/src/inline-client-driver/mod.ts +0 -385
- package/src/manager/auth.ts +0 -121
- /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
- /package/src/{drivers/engine → actor}/keys.ts +0 -0
|
@@ -1,314 +1,52 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getPort
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-3F2YSRJL.js";
|
|
4
|
+
import {
|
|
5
|
+
createClient
|
|
6
|
+
} from "../chunk-HI3HWJRC.js";
|
|
4
7
|
import {
|
|
5
8
|
actor,
|
|
6
|
-
createInlineClientDriver,
|
|
7
9
|
createManagerRouter
|
|
8
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-XJQHKJ4P.js";
|
|
9
11
|
import {
|
|
10
12
|
createActorInspectorClient,
|
|
11
13
|
createManagerInspectorClient
|
|
12
|
-
} from "../chunk-
|
|
13
|
-
import
|
|
14
|
-
createClient
|
|
15
|
-
} from "../chunk-UVUPOS46.js";
|
|
16
|
-
import {
|
|
17
|
-
ActorError,
|
|
18
|
-
createClientWithDriver
|
|
19
|
-
} from "../chunk-EGVZZFE2.js";
|
|
20
|
-
import "../chunk-FLMTTN27.js";
|
|
21
|
-
import {
|
|
22
|
-
importWebSocket
|
|
23
|
-
} from "../chunk-PO4VLDWA.js";
|
|
14
|
+
} from "../chunk-H26RP6GD.js";
|
|
15
|
+
import "../chunk-QK72M5JB.js";
|
|
24
16
|
import {
|
|
25
17
|
RunConfigSchema
|
|
26
|
-
} from "../chunk-
|
|
27
|
-
import "../chunk-VRRHBNJC.js";
|
|
18
|
+
} from "../chunk-TQ62L3X7.js";
|
|
28
19
|
import {
|
|
29
20
|
HEADER_ACTOR_QUERY,
|
|
30
|
-
HEADER_CONN_PARAMS,
|
|
31
|
-
HEADER_ENCODING,
|
|
32
21
|
assertUnreachable
|
|
33
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-HLLF4B4Q.js";
|
|
34
23
|
import {
|
|
35
24
|
getLogger
|
|
36
|
-
} from "../chunk-
|
|
37
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-LV2S3OU3.js";
|
|
26
|
+
import "../chunk-PQY7KKTL.js";
|
|
38
27
|
import {
|
|
39
28
|
INTERNAL_ERROR_CODE,
|
|
40
29
|
INTERNAL_ERROR_DESCRIPTION
|
|
41
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-NFU2BBT5.js";
|
|
42
31
|
|
|
43
32
|
// src/driver-test-suite/mod.ts
|
|
44
33
|
import { serve as honoServe } from "@hono/node-server";
|
|
45
34
|
import { createNodeWebSocket } from "@hono/node-ws";
|
|
46
35
|
import { bundleRequire } from "bundle-require";
|
|
47
36
|
import invariant from "invariant";
|
|
48
|
-
import { describe as
|
|
49
|
-
|
|
50
|
-
// src/driver-test-suite/tests/action-features.ts
|
|
51
|
-
import { describe, expect, test } from "vitest";
|
|
52
|
-
|
|
53
|
-
// src/driver-test-suite/utils.ts
|
|
54
|
-
import { resolve } from "path";
|
|
55
|
-
import { vi } from "vitest";
|
|
56
|
-
|
|
57
|
-
// src/driver-test-suite/test-inline-client-driver.ts
|
|
58
|
-
import * as cbor from "cbor-x";
|
|
37
|
+
import { describe as describe20 } from "vitest";
|
|
59
38
|
|
|
60
39
|
// src/driver-test-suite/log.ts
|
|
61
|
-
var LOGGER_NAME = "test-suite";
|
|
62
40
|
function logger() {
|
|
63
|
-
return getLogger(
|
|
41
|
+
return getLogger("test-suite");
|
|
64
42
|
}
|
|
65
43
|
|
|
66
|
-
// src/driver-test-suite/
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
action: async (_c, actorQuery, encoding, params, name, args) => {
|
|
70
|
-
return makeInlineRequest(
|
|
71
|
-
endpoint,
|
|
72
|
-
encoding,
|
|
73
|
-
transport,
|
|
74
|
-
"action",
|
|
75
|
-
[void 0, actorQuery, encoding, params, name, args]
|
|
76
|
-
);
|
|
77
|
-
},
|
|
78
|
-
resolveActorId: async (_c, actorQuery, encodingKind, params) => {
|
|
79
|
-
return makeInlineRequest(
|
|
80
|
-
endpoint,
|
|
81
|
-
encodingKind,
|
|
82
|
-
transport,
|
|
83
|
-
"resolveActorId",
|
|
84
|
-
[void 0, actorQuery, encodingKind, params]
|
|
85
|
-
);
|
|
86
|
-
},
|
|
87
|
-
connectWebSocket: async (_c, actorQuery, encodingKind, params) => {
|
|
88
|
-
const WebSocket2 = await importWebSocket();
|
|
89
|
-
logger().debug("creating websocket connection via test inline driver", {
|
|
90
|
-
actorQuery,
|
|
91
|
-
encodingKind
|
|
92
|
-
});
|
|
93
|
-
const wsUrl = new URL(
|
|
94
|
-
`${endpoint}/registry/.test/inline-driver/connect-websocket`
|
|
95
|
-
);
|
|
96
|
-
wsUrl.searchParams.set("actorQuery", JSON.stringify(actorQuery));
|
|
97
|
-
if (params !== void 0)
|
|
98
|
-
wsUrl.searchParams.set("params", JSON.stringify(params));
|
|
99
|
-
wsUrl.searchParams.set("encodingKind", encodingKind);
|
|
100
|
-
const wsProtocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
101
|
-
const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}${wsUrl.search}`;
|
|
102
|
-
logger().debug("connecting to websocket", { url: finalWsUrl });
|
|
103
|
-
const ws = new WebSocket2(finalWsUrl, [
|
|
104
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
105
|
-
"rivetkit"
|
|
106
|
-
]);
|
|
107
|
-
return ws;
|
|
108
|
-
},
|
|
109
|
-
connectSse: async (_c, actorQuery, encodingKind, params) => {
|
|
110
|
-
logger().debug("creating sse connection via test inline driver", {
|
|
111
|
-
actorQuery,
|
|
112
|
-
encodingKind,
|
|
113
|
-
params
|
|
114
|
-
});
|
|
115
|
-
const EventSourceImport = await import("eventsource");
|
|
116
|
-
const EventSourceConstructor = EventSourceImport.default || EventSourceImport;
|
|
117
|
-
const actorQueryParam = encodeURIComponent(JSON.stringify(actorQuery));
|
|
118
|
-
const encodingParam = encodeURIComponent(encodingKind);
|
|
119
|
-
const paramsParam = params ? encodeURIComponent(JSON.stringify(params)) : null;
|
|
120
|
-
const sseUrl = new URL(
|
|
121
|
-
`${endpoint}/registry/.test/inline-driver/connect-sse`
|
|
122
|
-
);
|
|
123
|
-
sseUrl.searchParams.set("actorQueryRaw", actorQueryParam);
|
|
124
|
-
sseUrl.searchParams.set("encodingKind", encodingParam);
|
|
125
|
-
if (paramsParam) {
|
|
126
|
-
sseUrl.searchParams.set("params", paramsParam);
|
|
127
|
-
}
|
|
128
|
-
logger().debug("connecting to sse", { url: sseUrl.toString() });
|
|
129
|
-
const eventSource = new EventSourceConstructor(sseUrl.toString());
|
|
130
|
-
await new Promise((resolve2, reject) => {
|
|
131
|
-
eventSource.onopen = () => {
|
|
132
|
-
logger().debug("sse connection established");
|
|
133
|
-
resolve2();
|
|
134
|
-
};
|
|
135
|
-
eventSource.onerror = (event) => {
|
|
136
|
-
logger().error("sse connection failed", { event });
|
|
137
|
-
reject(new Error("Failed to establish SSE connection"));
|
|
138
|
-
};
|
|
139
|
-
setTimeout(() => {
|
|
140
|
-
if (eventSource.readyState !== EventSourceConstructor.OPEN) {
|
|
141
|
-
reject(new Error("SSE connection timed out"));
|
|
142
|
-
}
|
|
143
|
-
}, 1e4);
|
|
144
|
-
});
|
|
145
|
-
return eventSource;
|
|
146
|
-
},
|
|
147
|
-
sendHttpMessage: async (_c, actorId, encoding, connectionId, connectionToken, message) => {
|
|
148
|
-
var _a;
|
|
149
|
-
logger().debug("sending http message via test inline driver", {
|
|
150
|
-
actorId,
|
|
151
|
-
encoding,
|
|
152
|
-
connectionId,
|
|
153
|
-
transport
|
|
154
|
-
});
|
|
155
|
-
const result = await fetch(
|
|
156
|
-
`${endpoint}/registry/.test/inline-driver/call`,
|
|
157
|
-
{
|
|
158
|
-
method: "POST",
|
|
159
|
-
headers: {
|
|
160
|
-
"Content-Type": "application/json"
|
|
161
|
-
},
|
|
162
|
-
body: JSON.stringify({
|
|
163
|
-
encoding,
|
|
164
|
-
transport,
|
|
165
|
-
method: "sendHttpMessage",
|
|
166
|
-
args: [
|
|
167
|
-
void 0,
|
|
168
|
-
actorId,
|
|
169
|
-
encoding,
|
|
170
|
-
connectionId,
|
|
171
|
-
connectionToken,
|
|
172
|
-
message
|
|
173
|
-
]
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
);
|
|
177
|
-
if (!result.ok) {
|
|
178
|
-
throw new Error(`Failed to send HTTP message: ${result.statusText}`);
|
|
179
|
-
}
|
|
180
|
-
await ((_a = result.body) == null ? void 0 : _a.cancel());
|
|
181
|
-
},
|
|
182
|
-
rawHttpRequest: async (_c, actorQuery, encoding, params, path, init) => {
|
|
183
|
-
var _a;
|
|
184
|
-
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
185
|
-
logger().debug("sending raw http request via test inline driver", {
|
|
186
|
-
actorQuery,
|
|
187
|
-
encoding,
|
|
188
|
-
path: normalizedPath
|
|
189
|
-
});
|
|
190
|
-
const url = `${endpoint}/registry/.test/inline-driver/raw-http/${normalizedPath}`;
|
|
191
|
-
logger().debug("rewriting http url", {
|
|
192
|
-
from: path,
|
|
193
|
-
to: url
|
|
194
|
-
});
|
|
195
|
-
const headers = new Headers(init.headers);
|
|
196
|
-
headers.set(HEADER_ACTOR_QUERY, JSON.stringify(actorQuery));
|
|
197
|
-
headers.set(HEADER_ENCODING, encoding);
|
|
198
|
-
if (params !== void 0) {
|
|
199
|
-
headers.set(HEADER_CONN_PARAMS, JSON.stringify(params));
|
|
200
|
-
}
|
|
201
|
-
const response = await fetch(url, {
|
|
202
|
-
...init,
|
|
203
|
-
headers
|
|
204
|
-
});
|
|
205
|
-
if (!response.ok && ((_a = response.headers.get("content-type")) == null ? void 0 : _a.includes("application/json"))) {
|
|
206
|
-
try {
|
|
207
|
-
const clonedResponse = response.clone();
|
|
208
|
-
const errorData = await clonedResponse.json();
|
|
209
|
-
if (errorData.error) {
|
|
210
|
-
if (typeof errorData.error === "object") {
|
|
211
|
-
throw new ActorError(
|
|
212
|
-
errorData.error.code,
|
|
213
|
-
errorData.error.message,
|
|
214
|
-
errorData.error.metadata
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
} catch (e) {
|
|
219
|
-
if (!(e instanceof ActorError)) {
|
|
220
|
-
return response;
|
|
221
|
-
}
|
|
222
|
-
throw e;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return response;
|
|
226
|
-
},
|
|
227
|
-
rawWebSocket: async (_c, actorQuery, encoding, params, path, protocols) => {
|
|
228
|
-
logger().debug("test inline driver rawWebSocket called");
|
|
229
|
-
const WebSocket2 = await importWebSocket();
|
|
230
|
-
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
231
|
-
logger().debug(
|
|
232
|
-
"creating raw websocket connection via test inline driver",
|
|
233
|
-
{
|
|
234
|
-
actorQuery,
|
|
235
|
-
encoding,
|
|
236
|
-
path: normalizedPath,
|
|
237
|
-
protocols
|
|
238
|
-
}
|
|
239
|
-
);
|
|
240
|
-
const wsUrl = new URL(
|
|
241
|
-
`${endpoint}/registry/.test/inline-driver/raw-websocket`
|
|
242
|
-
);
|
|
243
|
-
wsUrl.searchParams.set("actorQuery", JSON.stringify(actorQuery));
|
|
244
|
-
if (params !== void 0)
|
|
245
|
-
wsUrl.searchParams.set("params", JSON.stringify(params));
|
|
246
|
-
wsUrl.searchParams.set("encodingKind", encoding);
|
|
247
|
-
wsUrl.searchParams.set("path", normalizedPath);
|
|
248
|
-
if (protocols !== void 0)
|
|
249
|
-
wsUrl.searchParams.set("protocols", JSON.stringify(protocols));
|
|
250
|
-
const wsProtocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
251
|
-
const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}${wsUrl.search}`;
|
|
252
|
-
logger().debug("connecting to raw websocket", { url: finalWsUrl });
|
|
253
|
-
logger().debug("rewriting websocket url", {
|
|
254
|
-
from: path,
|
|
255
|
-
to: finalWsUrl
|
|
256
|
-
});
|
|
257
|
-
const ws = new WebSocket2(finalWsUrl, [
|
|
258
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
259
|
-
"rivetkit"
|
|
260
|
-
]);
|
|
261
|
-
logger().debug("test inline driver created websocket", {
|
|
262
|
-
readyState: ws.readyState,
|
|
263
|
-
url: ws.url
|
|
264
|
-
});
|
|
265
|
-
return ws;
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
async function makeInlineRequest(endpoint, encoding, transport, method, args) {
|
|
270
|
-
logger().debug("sending inline request", {
|
|
271
|
-
encoding,
|
|
272
|
-
transport,
|
|
273
|
-
method,
|
|
274
|
-
args
|
|
275
|
-
});
|
|
276
|
-
const response = await fetch(
|
|
277
|
-
`${endpoint}/registry/.test/inline-driver/call`,
|
|
278
|
-
{
|
|
279
|
-
method: "POST",
|
|
280
|
-
headers: {
|
|
281
|
-
"Content-Type": "application/json"
|
|
282
|
-
},
|
|
283
|
-
body: cbor.encode({
|
|
284
|
-
encoding,
|
|
285
|
-
transport,
|
|
286
|
-
method,
|
|
287
|
-
args
|
|
288
|
-
})
|
|
289
|
-
}
|
|
290
|
-
);
|
|
291
|
-
if (!response.ok) {
|
|
292
|
-
throw new Error(`Failed to call inline ${method}: ${response.statusText}`);
|
|
293
|
-
}
|
|
294
|
-
const buffer = await response.arrayBuffer();
|
|
295
|
-
const callResponse = cbor.decode(
|
|
296
|
-
new Uint8Array(buffer)
|
|
297
|
-
);
|
|
298
|
-
if ("ok" in callResponse) {
|
|
299
|
-
return callResponse.ok;
|
|
300
|
-
} else if ("err" in callResponse) {
|
|
301
|
-
throw new ActorError(
|
|
302
|
-
callResponse.err.code,
|
|
303
|
-
callResponse.err.message,
|
|
304
|
-
callResponse.err.metadata
|
|
305
|
-
);
|
|
306
|
-
} else {
|
|
307
|
-
assertUnreachable(callResponse);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
44
|
+
// src/driver-test-suite/tests/action-features.ts
|
|
45
|
+
import { describe, expect, test } from "vitest";
|
|
310
46
|
|
|
311
47
|
// src/driver-test-suite/utils.ts
|
|
48
|
+
import { resolve } from "path";
|
|
49
|
+
import { vi } from "vitest";
|
|
312
50
|
var FAKE_TIME = /* @__PURE__ */ new Date("2024-01-01T00:00:00.000Z");
|
|
313
51
|
async function setupDriverTest(c, driverTestConfig) {
|
|
314
52
|
if (!driverTestConfig.useRealTimers) {
|
|
@@ -316,19 +54,18 @@ async function setupDriverTest(c, driverTestConfig) {
|
|
|
316
54
|
vi.setSystemTime(FAKE_TIME);
|
|
317
55
|
}
|
|
318
56
|
const projectPath = resolve(__dirname, "../../fixtures/driver-test-suite");
|
|
319
|
-
const { endpoint, cleanup } = await driverTestConfig.start(projectPath);
|
|
57
|
+
const { endpoint, namespace, runnerName, cleanup } = await driverTestConfig.start(projectPath);
|
|
320
58
|
c.onTestFinished(cleanup);
|
|
321
59
|
let client;
|
|
322
60
|
if (driverTestConfig.clientType === "http") {
|
|
323
|
-
client = createClient(
|
|
61
|
+
client = createClient({
|
|
62
|
+
endpoint,
|
|
63
|
+
namespace,
|
|
64
|
+
runnerName,
|
|
324
65
|
transport: driverTestConfig.transport
|
|
325
66
|
});
|
|
326
67
|
} else if (driverTestConfig.clientType === "inline") {
|
|
327
|
-
|
|
328
|
-
endpoint,
|
|
329
|
-
driverTestConfig.transport ?? "websocket"
|
|
330
|
-
);
|
|
331
|
-
client = createClientWithDriver(clientDriver);
|
|
68
|
+
throw "TODO";
|
|
332
69
|
} else {
|
|
333
70
|
assertUnreachable(driverTestConfig.clientType);
|
|
334
71
|
}
|
|
@@ -430,447 +167,21 @@ function runActionFeaturesTests(driverTestConfig) {
|
|
|
430
167
|
});
|
|
431
168
|
}
|
|
432
169
|
|
|
433
|
-
// src/driver-test-suite/tests/actor-auth.ts
|
|
434
|
-
import { describe as describe2, expect as expect2, test as test2 } from "vitest";
|
|
435
|
-
function runActorAuthTests(driverTestConfig) {
|
|
436
|
-
describe2("Actor Authentication Tests", () => {
|
|
437
|
-
describe2("Basic Authentication", () => {
|
|
438
|
-
test2("should allow access with valid auth", async (c) => {
|
|
439
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
440
|
-
const instance = client.authActor.getOrCreate(void 0, {
|
|
441
|
-
params: { apiKey: "valid-api-key" }
|
|
442
|
-
});
|
|
443
|
-
const authData = await instance.getUserAuth();
|
|
444
|
-
if (driverTestConfig.clientType === "inline") {
|
|
445
|
-
expect2(authData).toBeUndefined();
|
|
446
|
-
} else {
|
|
447
|
-
expect2(authData).toEqual({
|
|
448
|
-
userId: "user123",
|
|
449
|
-
token: "valid-api-key"
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
const requests = await instance.getRequests();
|
|
453
|
-
expect2(requests).toBe(1);
|
|
454
|
-
});
|
|
455
|
-
test2("should deny access with invalid auth", async (c) => {
|
|
456
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
457
|
-
const instance = client.authActor.getOrCreate();
|
|
458
|
-
if (driverTestConfig.clientType === "inline") {
|
|
459
|
-
const requests = await instance.getRequests();
|
|
460
|
-
expect2(typeof requests).toBe("number");
|
|
461
|
-
} else {
|
|
462
|
-
try {
|
|
463
|
-
await instance.getRequests();
|
|
464
|
-
expect2.fail("Expected authentication error");
|
|
465
|
-
} catch (error) {
|
|
466
|
-
expect2(error.code).toBe("missing_auth");
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
test2("should expose auth data on connection", async (c) => {
|
|
471
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
472
|
-
const instance = client.authActor.getOrCreate(void 0, {
|
|
473
|
-
params: { apiKey: "valid-api-key" }
|
|
474
|
-
});
|
|
475
|
-
const authData = await instance.getUserAuth();
|
|
476
|
-
if (driverTestConfig.clientType === "inline") {
|
|
477
|
-
expect2(authData).toBeUndefined();
|
|
478
|
-
} else {
|
|
479
|
-
expect2(authData).toBeDefined();
|
|
480
|
-
expect2(authData.userId).toBe("user123");
|
|
481
|
-
expect2(authData.token).toBe("valid-api-key");
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
});
|
|
485
|
-
describe2("Intent-Based Authentication", () => {
|
|
486
|
-
test2("should allow get operations for any role", async (c) => {
|
|
487
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
488
|
-
const createdInstance = await client.intentAuthActor.create(["foo"], {
|
|
489
|
-
params: { role: "admin" }
|
|
490
|
-
});
|
|
491
|
-
const actorId = await createdInstance.resolve();
|
|
492
|
-
if (driverTestConfig.clientType === "inline") {
|
|
493
|
-
const instance = client.intentAuthActor.getForId(actorId);
|
|
494
|
-
const value = await instance.getValue();
|
|
495
|
-
expect2(value).toBe(0);
|
|
496
|
-
} else {
|
|
497
|
-
const instance = client.intentAuthActor.getForId(actorId, {
|
|
498
|
-
params: { role: "user" }
|
|
499
|
-
// Actions require user or admin role
|
|
500
|
-
});
|
|
501
|
-
const value = await instance.getValue();
|
|
502
|
-
expect2(value).toBe(0);
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
test2("should require admin role for create operations", async (c) => {
|
|
506
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
507
|
-
if (driverTestConfig.clientType === "inline") {
|
|
508
|
-
const instance = client.intentAuthActor.getOrCreate(void 0, {
|
|
509
|
-
params: { role: "user" }
|
|
510
|
-
});
|
|
511
|
-
const value = await instance.getValue();
|
|
512
|
-
expect2(value).toBe(0);
|
|
513
|
-
} else {
|
|
514
|
-
try {
|
|
515
|
-
const instance = client.intentAuthActor.getOrCreate(void 0, {
|
|
516
|
-
params: { role: "user" }
|
|
517
|
-
});
|
|
518
|
-
await instance.getValue();
|
|
519
|
-
expect2.fail("Expected permission error for create operation");
|
|
520
|
-
} catch (error) {
|
|
521
|
-
expect2(error.code).toBe("insufficient_permissions");
|
|
522
|
-
expect2(error.message).toContain(
|
|
523
|
-
"Admin role required"
|
|
524
|
-
);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
});
|
|
528
|
-
test2("should allow actions for user and admin roles", async (c) => {
|
|
529
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
530
|
-
const createdInstance = await client.intentAuthActor.create(["foo"], {
|
|
531
|
-
params: { role: "admin" }
|
|
532
|
-
});
|
|
533
|
-
const actorId = await createdInstance.resolve();
|
|
534
|
-
const instance = client.intentAuthActor.getForId(actorId, {
|
|
535
|
-
params: { role: "guest" }
|
|
536
|
-
});
|
|
537
|
-
if (driverTestConfig.clientType === "inline") {
|
|
538
|
-
const result = await instance.setValue(42);
|
|
539
|
-
expect2(result).toBe(42);
|
|
540
|
-
} else {
|
|
541
|
-
try {
|
|
542
|
-
await instance.setValue(42);
|
|
543
|
-
expect2.fail("Expected permission error for action");
|
|
544
|
-
} catch (error) {
|
|
545
|
-
expect2(error.code).toBe("insufficient_permissions");
|
|
546
|
-
expect2(error.message).toContain(
|
|
547
|
-
"User or admin role required"
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
});
|
|
553
|
-
describe2("Public Access", () => {
|
|
554
|
-
test2("should allow access with empty onAuth", async (c) => {
|
|
555
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
556
|
-
const instance = client.publicActor.getOrCreate();
|
|
557
|
-
const visitors = await instance.visit();
|
|
558
|
-
expect2(visitors).toBe(1);
|
|
559
|
-
const visitors2 = await instance.visit();
|
|
560
|
-
expect2(visitors2).toBe(2);
|
|
561
|
-
});
|
|
562
|
-
test2("should deny access without onAuth defined", async (c) => {
|
|
563
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
564
|
-
const instance = client.noAuthActor.getOrCreate();
|
|
565
|
-
if (driverTestConfig.clientType === "inline") {
|
|
566
|
-
const value = await instance.getValue();
|
|
567
|
-
expect2(value).toBe(42);
|
|
568
|
-
} else {
|
|
569
|
-
try {
|
|
570
|
-
await instance.getValue();
|
|
571
|
-
expect2.fail(
|
|
572
|
-
"Expected access to be denied for actor without onAuth"
|
|
573
|
-
);
|
|
574
|
-
} catch (error) {
|
|
575
|
-
expect2(error.code).toBe("forbidden");
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
});
|
|
579
|
-
});
|
|
580
|
-
describe2("Async Authentication", () => {
|
|
581
|
-
test2("should handle promise-based auth", async (c) => {
|
|
582
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
583
|
-
const instance = client.asyncAuthActor.getOrCreate(void 0, {
|
|
584
|
-
params: { token: "valid" }
|
|
585
|
-
});
|
|
586
|
-
const result = await instance.increment();
|
|
587
|
-
expect2(result).toBe(1);
|
|
588
|
-
const authData = await instance.getAuthData();
|
|
589
|
-
if (driverTestConfig.clientType === "inline") {
|
|
590
|
-
expect2(authData).toBeUndefined();
|
|
591
|
-
} else {
|
|
592
|
-
expect2(authData).toBeDefined();
|
|
593
|
-
expect2(authData.userId).toBe("user-valid");
|
|
594
|
-
expect2(authData.validated).toBe(true);
|
|
595
|
-
}
|
|
596
|
-
});
|
|
597
|
-
test2("should handle async auth failures", async (c) => {
|
|
598
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
599
|
-
const instance = client.asyncAuthActor.getOrCreate();
|
|
600
|
-
if (driverTestConfig.clientType === "inline") {
|
|
601
|
-
const result = await instance.increment();
|
|
602
|
-
expect2(result).toBe(1);
|
|
603
|
-
} else {
|
|
604
|
-
try {
|
|
605
|
-
await instance.increment();
|
|
606
|
-
expect2.fail("Expected async auth failure");
|
|
607
|
-
} catch (error) {
|
|
608
|
-
expect2(error.code).toBe("missing_token");
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
});
|
|
612
|
-
});
|
|
613
|
-
describe2("Authentication Across Transports", () => {
|
|
614
|
-
if (driverTestConfig.transport === "websocket") {
|
|
615
|
-
test2("should authenticate WebSocket connections", async (c) => {
|
|
616
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
617
|
-
const instance = client.authActor.getOrCreate(void 0, {
|
|
618
|
-
params: { apiKey: "valid-api-key" }
|
|
619
|
-
});
|
|
620
|
-
const authData = await instance.getUserAuth();
|
|
621
|
-
expect2(authData).toBeDefined();
|
|
622
|
-
expect2(authData.userId).toBe("user123");
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
test2("should authenticate HTTP actions", async (c) => {
|
|
626
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
627
|
-
const instance = client.authActor.getOrCreate(void 0, {
|
|
628
|
-
params: { apiKey: "valid-api-key" }
|
|
629
|
-
});
|
|
630
|
-
const requests = await instance.getRequests();
|
|
631
|
-
expect2(typeof requests).toBe("number");
|
|
632
|
-
});
|
|
633
|
-
});
|
|
634
|
-
describe2("Error Handling", () => {
|
|
635
|
-
test2("should handle auth errors gracefully", async (c) => {
|
|
636
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
637
|
-
const instance = client.authActor.getOrCreate();
|
|
638
|
-
if (driverTestConfig.clientType === "inline") {
|
|
639
|
-
const requests = await instance.getRequests();
|
|
640
|
-
expect2(typeof requests).toBe("number");
|
|
641
|
-
} else {
|
|
642
|
-
try {
|
|
643
|
-
await instance.getRequests();
|
|
644
|
-
expect2.fail("Expected authentication error");
|
|
645
|
-
} catch (error) {
|
|
646
|
-
const actorError = error;
|
|
647
|
-
expect2(actorError.code).toBeDefined();
|
|
648
|
-
expect2(actorError.message).toBeDefined();
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
});
|
|
652
|
-
test2("should preserve error details for debugging", async (c) => {
|
|
653
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
654
|
-
const instance = client.asyncAuthActor.getOrCreate();
|
|
655
|
-
if (driverTestConfig.clientType === "inline") {
|
|
656
|
-
const result = await instance.increment();
|
|
657
|
-
expect2(result).toBe(1);
|
|
658
|
-
} else {
|
|
659
|
-
try {
|
|
660
|
-
await instance.increment();
|
|
661
|
-
expect2.fail("Expected token error");
|
|
662
|
-
} catch (error) {
|
|
663
|
-
const actorError = error;
|
|
664
|
-
expect2(actorError.code).toBe("missing_token");
|
|
665
|
-
expect2(actorError.message).toBe("Token required");
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
});
|
|
669
|
-
});
|
|
670
|
-
describe2("Raw HTTP Authentication", () => {
|
|
671
|
-
test2("should allow raw HTTP access with valid auth", async (c) => {
|
|
672
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
673
|
-
const instance = client.rawHttpAuthActor.getOrCreate(void 0, {
|
|
674
|
-
params: { apiKey: "valid-api-key" }
|
|
675
|
-
});
|
|
676
|
-
const response = await instance.fetch("api/auth-info");
|
|
677
|
-
expect2(response.ok).toBe(true);
|
|
678
|
-
const data = await response.json();
|
|
679
|
-
expect2(data.message).toBe("Authenticated request");
|
|
680
|
-
expect2(data.requestCount).toBe(1);
|
|
681
|
-
const count = await instance.getRequestCount();
|
|
682
|
-
expect2(count).toBe(1);
|
|
683
|
-
});
|
|
684
|
-
test2("should deny raw HTTP access without auth", async (c) => {
|
|
685
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
686
|
-
const instance = client.rawHttpAuthActor.getOrCreate();
|
|
687
|
-
const response = await instance.fetch("api/protected");
|
|
688
|
-
if (driverTestConfig.clientType === "inline") {
|
|
689
|
-
expect2(response.ok).toBe(true);
|
|
690
|
-
expect2(response.status).toBe(200);
|
|
691
|
-
} else {
|
|
692
|
-
expect2(response.ok).toBe(false);
|
|
693
|
-
expect2(response.status).toBe(400);
|
|
694
|
-
}
|
|
695
|
-
try {
|
|
696
|
-
const errorData = await response.json();
|
|
697
|
-
expect2(errorData.c || errorData.code).toBe("missing_auth");
|
|
698
|
-
} catch {
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
test2("should deny raw HTTP for actors without onAuth", async (c) => {
|
|
702
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
703
|
-
const instance = client.rawHttpNoAuthActor.getOrCreate();
|
|
704
|
-
const response = await instance.fetch("api/test");
|
|
705
|
-
if (driverTestConfig.clientType === "inline") {
|
|
706
|
-
expect2(response.ok).toBe(true);
|
|
707
|
-
expect2(response.status).toBe(200);
|
|
708
|
-
} else {
|
|
709
|
-
expect2(response.ok).toBe(false);
|
|
710
|
-
expect2(response.status).toBe(403);
|
|
711
|
-
}
|
|
712
|
-
try {
|
|
713
|
-
const errorData = await response.json();
|
|
714
|
-
expect2(errorData.c || errorData.code).toBe("forbidden");
|
|
715
|
-
} catch {
|
|
716
|
-
}
|
|
717
|
-
});
|
|
718
|
-
test2("should allow public raw HTTP access", async (c) => {
|
|
719
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
720
|
-
const instance = client.rawHttpPublicActor.getOrCreate();
|
|
721
|
-
const response = await instance.fetch("api/visit");
|
|
722
|
-
expect2(response.ok).toBe(true);
|
|
723
|
-
const data = await response.json();
|
|
724
|
-
expect2(data.message).toBe("Welcome visitor!");
|
|
725
|
-
expect2(data.count).toBe(1);
|
|
726
|
-
const response2 = await instance.fetch("api/visit");
|
|
727
|
-
const data2 = await response2.json();
|
|
728
|
-
expect2(data2.count).toBe(2);
|
|
729
|
-
});
|
|
730
|
-
test2("should handle custom auth in onFetch", async (c) => {
|
|
731
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
732
|
-
const instance = client.rawHttpCustomAuthActor.getOrCreate();
|
|
733
|
-
const response1 = await instance.fetch("api/data");
|
|
734
|
-
expect2(response1.ok).toBe(false);
|
|
735
|
-
expect2(response1.status).toBe(401);
|
|
736
|
-
const error1 = await response1.json();
|
|
737
|
-
expect2(error1.error).toBe("Unauthorized");
|
|
738
|
-
const response2 = await instance.fetch("api/data", {
|
|
739
|
-
headers: {
|
|
740
|
-
Authorization: "Bearer wrong-token"
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
expect2(response2.ok).toBe(false);
|
|
744
|
-
expect2(response2.status).toBe(403);
|
|
745
|
-
const response3 = await instance.fetch("api/data", {
|
|
746
|
-
headers: {
|
|
747
|
-
Authorization: "Bearer custom-token"
|
|
748
|
-
}
|
|
749
|
-
});
|
|
750
|
-
expect2(response3.ok).toBe(true);
|
|
751
|
-
const data = await response3.json();
|
|
752
|
-
expect2(data.message).toBe("Authorized!");
|
|
753
|
-
expect2(data.authorized).toBe(1);
|
|
754
|
-
const stats = await instance.getStats();
|
|
755
|
-
expect2(stats.authorized).toBe(1);
|
|
756
|
-
expect2(stats.unauthorized).toBe(2);
|
|
757
|
-
});
|
|
758
|
-
});
|
|
759
|
-
describe2("Raw WebSocket Authentication", () => {
|
|
760
|
-
test2("should allow raw WebSocket access with valid auth", async (c) => {
|
|
761
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
762
|
-
const instance = client.rawWebSocketAuthActor.getOrCreate(void 0, {
|
|
763
|
-
params: { apiKey: "valid-api-key" }
|
|
764
|
-
});
|
|
765
|
-
const ws = await instance.websocket();
|
|
766
|
-
const welcomePromise = new Promise((resolve2, reject) => {
|
|
767
|
-
ws.addEventListener("message", (event) => {
|
|
768
|
-
const data = JSON.parse(event.data);
|
|
769
|
-
if (data.type === "welcome") {
|
|
770
|
-
resolve2(data);
|
|
771
|
-
}
|
|
772
|
-
});
|
|
773
|
-
ws.addEventListener("close", () => reject("closed"));
|
|
774
|
-
});
|
|
775
|
-
const welcomeData = await welcomePromise;
|
|
776
|
-
expect2(welcomeData.message).toBe("Authenticated WebSocket connection");
|
|
777
|
-
expect2(welcomeData.connectionCount).toBe(1);
|
|
778
|
-
ws.close();
|
|
779
|
-
});
|
|
780
|
-
test2("should deny raw WebSocket access without auth", async (c) => {
|
|
781
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
782
|
-
const instance = client.rawWebSocketAuthActor.getOrCreate();
|
|
783
|
-
try {
|
|
784
|
-
await instance.websocket();
|
|
785
|
-
expect2.fail("Expected authentication error");
|
|
786
|
-
} catch (error) {
|
|
787
|
-
expect2(error).toBeDefined();
|
|
788
|
-
}
|
|
789
|
-
});
|
|
790
|
-
test2("should deny raw WebSocket for actors without onAuth", async (c) => {
|
|
791
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
792
|
-
const instance = client.rawWebSocketNoAuthActor.getOrCreate();
|
|
793
|
-
try {
|
|
794
|
-
await instance.websocket();
|
|
795
|
-
expect2.fail("Expected forbidden error");
|
|
796
|
-
} catch (error) {
|
|
797
|
-
expect2(error).toBeDefined();
|
|
798
|
-
}
|
|
799
|
-
});
|
|
800
|
-
test2("should allow public raw WebSocket access", async (c) => {
|
|
801
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
802
|
-
const instance = client.rawWebSocketPublicActor.getOrCreate();
|
|
803
|
-
const ws = await instance.websocket();
|
|
804
|
-
const welcomePromise = new Promise((resolve2, reject) => {
|
|
805
|
-
ws.addEventListener("message", (event) => {
|
|
806
|
-
const data = JSON.parse(event.data);
|
|
807
|
-
if (data.type === "welcome") {
|
|
808
|
-
resolve2(data);
|
|
809
|
-
}
|
|
810
|
-
});
|
|
811
|
-
ws.addEventListener("close", reject);
|
|
812
|
-
});
|
|
813
|
-
const welcomeData = await welcomePromise;
|
|
814
|
-
expect2(welcomeData.message).toBe("Public WebSocket connection");
|
|
815
|
-
expect2(welcomeData.visitorNumber).toBe(1);
|
|
816
|
-
ws.close();
|
|
817
|
-
});
|
|
818
|
-
test2("should handle custom auth in onWebSocket", async (c) => {
|
|
819
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
820
|
-
const instance = client.rawWebSocketCustomAuthActor.getOrCreate();
|
|
821
|
-
try {
|
|
822
|
-
const ws1 = await instance.websocket();
|
|
823
|
-
const errorPromise = new Promise((resolve2, reject) => {
|
|
824
|
-
ws1.addEventListener("message", (event) => {
|
|
825
|
-
const data = JSON.parse(event.data);
|
|
826
|
-
if (data.type === "error") {
|
|
827
|
-
resolve2(data);
|
|
828
|
-
}
|
|
829
|
-
});
|
|
830
|
-
ws1.addEventListener("close", reject);
|
|
831
|
-
});
|
|
832
|
-
const errorData = await errorPromise;
|
|
833
|
-
expect2(errorData.type).toBe("error");
|
|
834
|
-
expect2(errorData.message).toBe("Unauthorized");
|
|
835
|
-
} catch (error) {
|
|
836
|
-
expect2(error).toBeDefined();
|
|
837
|
-
}
|
|
838
|
-
const ws2 = await instance.websocket("?token=custom-ws-token");
|
|
839
|
-
const authPromise = new Promise((resolve2, reject) => {
|
|
840
|
-
ws2.addEventListener("message", (event) => {
|
|
841
|
-
const data = JSON.parse(event.data);
|
|
842
|
-
if (data.type === "authorized") {
|
|
843
|
-
resolve2(data);
|
|
844
|
-
}
|
|
845
|
-
});
|
|
846
|
-
ws2.addEventListener("close", reject);
|
|
847
|
-
});
|
|
848
|
-
const authData = await authPromise;
|
|
849
|
-
expect2(authData.message).toBe("Welcome authenticated user!");
|
|
850
|
-
ws2.close();
|
|
851
|
-
const stats = await instance.getStats();
|
|
852
|
-
expect2(stats.authorized).toBeGreaterThanOrEqual(1);
|
|
853
|
-
expect2(stats.unauthorized).toBeGreaterThanOrEqual(1);
|
|
854
|
-
});
|
|
855
|
-
});
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
|
|
859
170
|
// src/driver-test-suite/tests/actor-conn.ts
|
|
860
|
-
import { describe as
|
|
171
|
+
import { describe as describe2, expect as expect2, test as test2 } from "vitest";
|
|
861
172
|
function runActorConnTests(driverTestConfig) {
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
173
|
+
describe2("Actor Connection Tests", () => {
|
|
174
|
+
describe2("Connection Methods", () => {
|
|
175
|
+
test2("should connect using .get().connect()", async (c) => {
|
|
865
176
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
866
177
|
await client.counter.create(["test-get"]);
|
|
867
178
|
const handle = client.counter.get(["test-get"]);
|
|
868
179
|
const connection = handle.connect();
|
|
869
180
|
const count = await connection.increment(5);
|
|
870
|
-
|
|
181
|
+
expect2(count).toBe(5);
|
|
871
182
|
await connection.dispose();
|
|
872
183
|
});
|
|
873
|
-
|
|
184
|
+
test2("should connect using .getForId().connect()", async (c) => {
|
|
874
185
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
875
186
|
const handle = client.counter.getOrCreate(["test-get-for-id"]);
|
|
876
187
|
await handle.increment(3);
|
|
@@ -878,28 +189,28 @@ function runActorConnTests(driverTestConfig) {
|
|
|
878
189
|
const idHandle = client.counter.getForId(actorId);
|
|
879
190
|
const connection = idHandle.connect();
|
|
880
191
|
const count = await connection.getCount();
|
|
881
|
-
|
|
192
|
+
expect2(count).toBe(3);
|
|
882
193
|
await connection.dispose();
|
|
883
194
|
});
|
|
884
|
-
|
|
195
|
+
test2("should connect using .getOrCreate().connect()", async (c) => {
|
|
885
196
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
886
197
|
const handle = client.counter.getOrCreate(["test-get-or-create"]);
|
|
887
198
|
const connection = handle.connect();
|
|
888
199
|
const count = await connection.increment(7);
|
|
889
|
-
|
|
200
|
+
expect2(count).toBe(7);
|
|
890
201
|
await connection.dispose();
|
|
891
202
|
});
|
|
892
|
-
|
|
203
|
+
test2("should connect using (await create()).connect()", async (c) => {
|
|
893
204
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
894
205
|
const handle = await client.counter.create(["test-create"]);
|
|
895
206
|
const connection = handle.connect();
|
|
896
207
|
const count = await connection.increment(9);
|
|
897
|
-
|
|
208
|
+
expect2(count).toBe(9);
|
|
898
209
|
await connection.dispose();
|
|
899
210
|
});
|
|
900
211
|
});
|
|
901
|
-
|
|
902
|
-
|
|
212
|
+
describe2("Event Communication", () => {
|
|
213
|
+
test2("should mix RPC calls and WebSocket events", async (c) => {
|
|
903
214
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
904
215
|
const handle = client.counter.getOrCreate(["test-mixed-rpc-ws"]);
|
|
905
216
|
const connection = handle.connect();
|
|
@@ -917,7 +228,7 @@ function runActorConnTests(driverTestConfig) {
|
|
|
917
228
|
await receivedEventsPromise;
|
|
918
229
|
await connection.dispose();
|
|
919
230
|
});
|
|
920
|
-
|
|
231
|
+
test2("should receive events via broadcast", async (c) => {
|
|
921
232
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
922
233
|
const handle = client.counter.getOrCreate(["test-broadcast"]);
|
|
923
234
|
const connection = handle.connect();
|
|
@@ -927,11 +238,11 @@ function runActorConnTests(driverTestConfig) {
|
|
|
927
238
|
});
|
|
928
239
|
await connection.increment(5);
|
|
929
240
|
await connection.increment(3);
|
|
930
|
-
|
|
931
|
-
|
|
241
|
+
expect2(receivedEvents).toContain(5);
|
|
242
|
+
expect2(receivedEvents).toContain(8);
|
|
932
243
|
await connection.dispose();
|
|
933
244
|
});
|
|
934
|
-
|
|
245
|
+
test2("should handle one-time events with once()", async (c) => {
|
|
935
246
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
936
247
|
const handle = client.counter.getOrCreate(["test-once"]);
|
|
937
248
|
const connection = handle.connect();
|
|
@@ -941,11 +252,11 @@ function runActorConnTests(driverTestConfig) {
|
|
|
941
252
|
});
|
|
942
253
|
await connection.increment(5);
|
|
943
254
|
await connection.increment(3);
|
|
944
|
-
|
|
945
|
-
|
|
255
|
+
expect2(receivedEvents).toEqual([5]);
|
|
256
|
+
expect2(receivedEvents).not.toContain(8);
|
|
946
257
|
await connection.dispose();
|
|
947
258
|
});
|
|
948
|
-
|
|
259
|
+
test2("should unsubscribe from events", async (c) => {
|
|
949
260
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
950
261
|
const handle = client.counter.getOrCreate(["test-unsubscribe"]);
|
|
951
262
|
const connection = handle.connect();
|
|
@@ -956,13 +267,13 @@ function runActorConnTests(driverTestConfig) {
|
|
|
956
267
|
await connection.increment(5);
|
|
957
268
|
unsubscribe();
|
|
958
269
|
await connection.increment(3);
|
|
959
|
-
|
|
960
|
-
|
|
270
|
+
expect2(receivedEvents).toEqual([5]);
|
|
271
|
+
expect2(receivedEvents).not.toContain(8);
|
|
961
272
|
await connection.dispose();
|
|
962
273
|
});
|
|
963
274
|
});
|
|
964
|
-
|
|
965
|
-
|
|
275
|
+
describe2("Connection Parameters", () => {
|
|
276
|
+
test2("should pass connection parameters", async (c) => {
|
|
966
277
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
967
278
|
const handle1 = client.counterWithParams.getOrCreate(["test-params"], {
|
|
968
279
|
params: { name: "user1" }
|
|
@@ -975,14 +286,14 @@ function runActorConnTests(driverTestConfig) {
|
|
|
975
286
|
await conn1.getInitializers();
|
|
976
287
|
await conn2.getInitializers();
|
|
977
288
|
const initializers = await conn1.getInitializers();
|
|
978
|
-
|
|
979
|
-
|
|
289
|
+
expect2(initializers).toContain("user1");
|
|
290
|
+
expect2(initializers).toContain("user2");
|
|
980
291
|
await conn1.dispose();
|
|
981
292
|
await conn2.dispose();
|
|
982
293
|
});
|
|
983
294
|
});
|
|
984
|
-
|
|
985
|
-
|
|
295
|
+
describe2("Lifecycle Hooks", () => {
|
|
296
|
+
test2("should trigger lifecycle hooks", async (c) => {
|
|
986
297
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
987
298
|
const connHandle = client.counterWithLifecycle.getOrCreate(
|
|
988
299
|
["test-lifecycle"],
|
|
@@ -992,13 +303,13 @@ function runActorConnTests(driverTestConfig) {
|
|
|
992
303
|
);
|
|
993
304
|
const connection = connHandle.connect();
|
|
994
305
|
const events = await connection.getEvents();
|
|
995
|
-
|
|
306
|
+
expect2(events).toEqual(["onStart", "onBeforeConnect", "onConnect"]);
|
|
996
307
|
await connection.dispose();
|
|
997
308
|
const handle = client.counterWithLifecycle.getOrCreate([
|
|
998
309
|
"test-lifecycle"
|
|
999
310
|
]);
|
|
1000
311
|
const finalEvents = await handle.getEvents();
|
|
1001
|
-
|
|
312
|
+
expect2(finalEvents).toBeOneOf([
|
|
1002
313
|
// Still active
|
|
1003
314
|
["onStart", "onBeforeConnect", "onConnect", "onDisconnect"],
|
|
1004
315
|
// Went to sleep and woke back up
|
|
@@ -1012,8 +323,8 @@ function runActorConnTests(driverTestConfig) {
|
|
|
1012
323
|
]);
|
|
1013
324
|
});
|
|
1014
325
|
});
|
|
1015
|
-
|
|
1016
|
-
|
|
326
|
+
describe2("Connection Liveness", () => {
|
|
327
|
+
test2.skip("should return correct liveness status for connections", async (c) => {
|
|
1017
328
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1018
329
|
const handle = client.connLivenessActor.getOrCreate([
|
|
1019
330
|
"test-liveness-status"
|
|
@@ -1025,18 +336,18 @@ function runActorConnTests(driverTestConfig) {
|
|
|
1025
336
|
await connA.increment(5);
|
|
1026
337
|
await connB.increment(5);
|
|
1027
338
|
const counter = await handle.getCounter();
|
|
1028
|
-
|
|
339
|
+
expect2(counter).toBe(10);
|
|
1029
340
|
const connectionsStatusBeforeKill = await handle.getWsConnectionsLiveness();
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
341
|
+
expect2(connectionsStatusBeforeKill).toHaveLength(2);
|
|
342
|
+
expect2(connectionsStatusBeforeKill).toContainEqual(
|
|
343
|
+
expect2.objectContaining({
|
|
1033
344
|
id: connAId,
|
|
1034
345
|
status: "connected",
|
|
1035
346
|
lastSeen: FAKE_TIME.getTime()
|
|
1036
347
|
})
|
|
1037
348
|
);
|
|
1038
|
-
|
|
1039
|
-
|
|
349
|
+
expect2(connectionsStatusBeforeKill).toContainEqual(
|
|
350
|
+
expect2.objectContaining({
|
|
1040
351
|
id: connBId,
|
|
1041
352
|
status: "connected",
|
|
1042
353
|
lastSeen: FAKE_TIME.getTime()
|
|
@@ -1044,14 +355,14 @@ function runActorConnTests(driverTestConfig) {
|
|
|
1044
355
|
);
|
|
1045
356
|
await handle.kill(connAId);
|
|
1046
357
|
const connectionsStatusAfterKill = await handle.getWsConnectionsLiveness();
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
358
|
+
expect2(connectionsStatusAfterKill).toEqual(
|
|
359
|
+
expect2.arrayContaining([
|
|
360
|
+
expect2.objectContaining({
|
|
1050
361
|
id: connAId,
|
|
1051
362
|
status: "reconnecting",
|
|
1052
363
|
lastSeen: FAKE_TIME.getTime()
|
|
1053
364
|
}),
|
|
1054
|
-
|
|
365
|
+
expect2.objectContaining({
|
|
1055
366
|
id: connBId,
|
|
1056
367
|
status: "connected",
|
|
1057
368
|
lastSeen: FAKE_TIME.getTime()
|
|
@@ -1060,13 +371,13 @@ function runActorConnTests(driverTestConfig) {
|
|
|
1060
371
|
);
|
|
1061
372
|
await waitFor(driverTestConfig, 5e3);
|
|
1062
373
|
const connectionsStatusAfterCleanup = await handle.getWsConnectionsLiveness();
|
|
1063
|
-
|
|
1064
|
-
|
|
374
|
+
expect2(connectionsStatusAfterCleanup).not.toContainEqual(
|
|
375
|
+
expect2.objectContaining({
|
|
1065
376
|
id: connAId
|
|
1066
377
|
})
|
|
1067
378
|
);
|
|
1068
|
-
|
|
1069
|
-
|
|
379
|
+
expect2(connectionsStatusAfterCleanup).toContainEqual(
|
|
380
|
+
expect2.objectContaining({
|
|
1070
381
|
id: connBId
|
|
1071
382
|
})
|
|
1072
383
|
);
|
|
@@ -1076,22 +387,22 @@ function runActorConnTests(driverTestConfig) {
|
|
|
1076
387
|
}
|
|
1077
388
|
|
|
1078
389
|
// src/driver-test-suite/tests/actor-conn-state.ts
|
|
1079
|
-
import { describe as
|
|
390
|
+
import { describe as describe3, expect as expect3, test as test3, vi as vi2 } from "vitest";
|
|
1080
391
|
function runActorConnStateTests(driverTestConfig) {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
392
|
+
describe3("Actor Connection State Tests", () => {
|
|
393
|
+
describe3("Connection State Initialization", () => {
|
|
394
|
+
test3("should retrieve connection state", async (c) => {
|
|
1084
395
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1085
396
|
const connection = client.connStateActor.getOrCreate().connect();
|
|
1086
397
|
const connState = await connection.getConnectionState();
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
398
|
+
expect3(connState.id).toBeDefined();
|
|
399
|
+
expect3(connState.username).toBeDefined();
|
|
400
|
+
expect3(connState.role).toBeDefined();
|
|
401
|
+
expect3(connState.counter).toBeDefined();
|
|
402
|
+
expect3(connState.createdAt).toBeDefined();
|
|
1092
403
|
await connection.dispose();
|
|
1093
404
|
});
|
|
1094
|
-
|
|
405
|
+
test3("should initialize connection state with custom parameters", async (c) => {
|
|
1095
406
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1096
407
|
const connection = client.connStateActor.getOrCreate([], {
|
|
1097
408
|
params: {
|
|
@@ -1100,13 +411,13 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1100
411
|
}
|
|
1101
412
|
}).connect();
|
|
1102
413
|
const connState = await connection.getConnectionState();
|
|
1103
|
-
|
|
1104
|
-
|
|
414
|
+
expect3(connState.username).toBe("testuser");
|
|
415
|
+
expect3(connState.role).toBe("admin");
|
|
1105
416
|
await connection.dispose();
|
|
1106
417
|
});
|
|
1107
418
|
});
|
|
1108
|
-
|
|
1109
|
-
|
|
419
|
+
describe3("Connection State Management", () => {
|
|
420
|
+
test3("should maintain unique state for each connection", async (c) => {
|
|
1110
421
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1111
422
|
const conn1 = client.connStateActor.getOrCreate([], {
|
|
1112
423
|
params: { username: "user1" }
|
|
@@ -1118,14 +429,14 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1118
429
|
await conn2.incrementConnCounter(10);
|
|
1119
430
|
const state1 = await conn1.getConnectionState();
|
|
1120
431
|
const state2 = await conn2.getConnectionState();
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
432
|
+
expect3(state1.counter).toBe(5);
|
|
433
|
+
expect3(state2.counter).toBe(10);
|
|
434
|
+
expect3(state1.username).toBe("user1");
|
|
435
|
+
expect3(state2.username).toBe("user2");
|
|
1125
436
|
await conn1.dispose();
|
|
1126
437
|
await conn2.dispose();
|
|
1127
438
|
});
|
|
1128
|
-
|
|
439
|
+
test3("should track connections in shared state", async (c) => {
|
|
1129
440
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1130
441
|
const handle = client.connStateActor.getOrCreate();
|
|
1131
442
|
const conn1 = handle.connect();
|
|
@@ -1134,12 +445,12 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1134
445
|
await conn2.getConnectionState();
|
|
1135
446
|
const state1 = await conn1.getConnectionState();
|
|
1136
447
|
const connectionIds = await conn1.getConnectionIds();
|
|
1137
|
-
|
|
1138
|
-
|
|
448
|
+
expect3(connectionIds.length).toBeGreaterThanOrEqual(2);
|
|
449
|
+
expect3(connectionIds).toContain(state1.id);
|
|
1139
450
|
await conn1.dispose();
|
|
1140
451
|
await conn2.dispose();
|
|
1141
452
|
});
|
|
1142
|
-
|
|
453
|
+
test3("should identify different connections in the same actor", async (c) => {
|
|
1143
454
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1144
455
|
const handle = client.connStateActor.getOrCreate();
|
|
1145
456
|
const conn1 = handle.connect();
|
|
@@ -1147,50 +458,50 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1147
458
|
await conn1.getConnectionState();
|
|
1148
459
|
await conn2.getConnectionState();
|
|
1149
460
|
const allStates = await conn1.getAllConnectionStates();
|
|
1150
|
-
|
|
461
|
+
expect3(allStates.length).toBeGreaterThanOrEqual(2);
|
|
1151
462
|
const ids = allStates.map((state) => state.id);
|
|
1152
463
|
const uniqueIds = [...new Set(ids)];
|
|
1153
|
-
|
|
464
|
+
expect3(uniqueIds.length).toBe(ids.length);
|
|
1154
465
|
await conn1.dispose();
|
|
1155
466
|
await conn2.dispose();
|
|
1156
467
|
});
|
|
1157
468
|
});
|
|
1158
|
-
|
|
1159
|
-
|
|
469
|
+
describe3("Connection Lifecycle", () => {
|
|
470
|
+
test3("should track connection and disconnection events", async (c) => {
|
|
1160
471
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1161
472
|
const handle = client.connStateActor.getOrCreate();
|
|
1162
473
|
const conn = handle.connect();
|
|
1163
474
|
const connState = await conn.getConnectionState();
|
|
1164
475
|
const connectionIds = await conn.getConnectionIds();
|
|
1165
|
-
|
|
476
|
+
expect3(connectionIds).toContain(connState.id);
|
|
1166
477
|
const initialDisconnections = await conn.getDisconnectionCount();
|
|
1167
478
|
await conn.dispose();
|
|
1168
479
|
const newConn = handle.connect();
|
|
1169
480
|
await vi2.waitFor(async () => {
|
|
1170
481
|
const newDisconnections = await newConn.getDisconnectionCount();
|
|
1171
|
-
|
|
482
|
+
expect3(newDisconnections).toBeGreaterThan(initialDisconnections);
|
|
1172
483
|
});
|
|
1173
484
|
await newConn.dispose();
|
|
1174
485
|
});
|
|
1175
|
-
|
|
486
|
+
test3("should update connection state", async (c) => {
|
|
1176
487
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1177
488
|
const conn = client.connStateActor.getOrCreate().connect();
|
|
1178
489
|
const initialState = await conn.getConnectionState();
|
|
1179
|
-
|
|
490
|
+
expect3(initialState.username).toBe("anonymous");
|
|
1180
491
|
const updatedState = await conn.updateConnection({
|
|
1181
492
|
username: "newname",
|
|
1182
493
|
role: "moderator"
|
|
1183
494
|
});
|
|
1184
|
-
|
|
1185
|
-
|
|
495
|
+
expect3(updatedState.username).toBe("newname");
|
|
496
|
+
expect3(updatedState.role).toBe("moderator");
|
|
1186
497
|
const latestState = await conn.getConnectionState();
|
|
1187
|
-
|
|
1188
|
-
|
|
498
|
+
expect3(latestState.username).toBe("newname");
|
|
499
|
+
expect3(latestState.role).toBe("moderator");
|
|
1189
500
|
await conn.dispose();
|
|
1190
501
|
});
|
|
1191
502
|
});
|
|
1192
|
-
|
|
1193
|
-
|
|
503
|
+
describe3("Connection Communication", () => {
|
|
504
|
+
test3("should send messages to specific connections", async (c) => {
|
|
1194
505
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1195
506
|
const handle = client.connStateActor.getOrCreate();
|
|
1196
507
|
const conn1 = handle.connect();
|
|
@@ -1205,10 +516,10 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1205
516
|
state2.id,
|
|
1206
517
|
"Hello from conn1"
|
|
1207
518
|
);
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
519
|
+
expect3(success).toBe(true);
|
|
520
|
+
expect3(receivedMessages.length).toBe(1);
|
|
521
|
+
expect3(receivedMessages[0].from).toBe(state1.id);
|
|
522
|
+
expect3(receivedMessages[0].message).toBe("Hello from conn1");
|
|
1212
523
|
await conn1.dispose();
|
|
1213
524
|
await conn2.dispose();
|
|
1214
525
|
});
|
|
@@ -1217,17 +528,17 @@ function runActorConnStateTests(driverTestConfig) {
|
|
|
1217
528
|
}
|
|
1218
529
|
|
|
1219
530
|
// src/driver-test-suite/tests/actor-driver.ts
|
|
1220
|
-
import { describe as
|
|
531
|
+
import { describe as describe7 } from "vitest";
|
|
1221
532
|
|
|
1222
533
|
// src/driver-test-suite/tests/actor-schedule.ts
|
|
1223
|
-
import { describe as
|
|
534
|
+
import { describe as describe4, expect as expect4, test as test4 } from "vitest";
|
|
1224
535
|
function runActorScheduleTests(driverTestConfig) {
|
|
1225
536
|
var _a;
|
|
1226
|
-
|
|
537
|
+
describe4.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.schedule)(
|
|
1227
538
|
"Actor Schedule Tests",
|
|
1228
539
|
() => {
|
|
1229
|
-
|
|
1230
|
-
|
|
540
|
+
describe4("Scheduled Alarms", () => {
|
|
541
|
+
test4("executes c.schedule.at() with specific timestamp", async (c) => {
|
|
1231
542
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1232
543
|
const scheduled = client.scheduled.getOrCreate();
|
|
1233
544
|
const timestamp = Date.now() + 100;
|
|
@@ -1235,32 +546,32 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1235
546
|
await waitFor(driverTestConfig, 200);
|
|
1236
547
|
const lastRun = await scheduled.getLastRun();
|
|
1237
548
|
const scheduledCount = await scheduled.getScheduledCount();
|
|
1238
|
-
|
|
1239
|
-
|
|
549
|
+
expect4(lastRun).toBeGreaterThan(0);
|
|
550
|
+
expect4(scheduledCount).toBe(1);
|
|
1240
551
|
});
|
|
1241
|
-
|
|
552
|
+
test4("executes c.schedule.after() with delay", async (c) => {
|
|
1242
553
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1243
554
|
const scheduled = client.scheduled.getOrCreate();
|
|
1244
555
|
await scheduled.scheduleTaskAfter(100);
|
|
1245
556
|
await waitFor(driverTestConfig, 200);
|
|
1246
557
|
const lastRun = await scheduled.getLastRun();
|
|
1247
558
|
const scheduledCount = await scheduled.getScheduledCount();
|
|
1248
|
-
|
|
1249
|
-
|
|
559
|
+
expect4(lastRun).toBeGreaterThan(0);
|
|
560
|
+
expect4(scheduledCount).toBe(1);
|
|
1250
561
|
});
|
|
1251
|
-
|
|
562
|
+
test4("scheduled tasks persist across actor restarts", async (c) => {
|
|
1252
563
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1253
564
|
const scheduled = client.scheduled.getOrCreate();
|
|
1254
565
|
await scheduled.scheduleTaskAfter(200);
|
|
1255
566
|
await waitFor(driverTestConfig, 100);
|
|
1256
567
|
const newInstance = client.scheduled.getOrCreate();
|
|
1257
568
|
const initialCount = await newInstance.getScheduledCount();
|
|
1258
|
-
|
|
569
|
+
expect4(initialCount).toBe(0);
|
|
1259
570
|
await waitFor(driverTestConfig, 200);
|
|
1260
571
|
const scheduledCount = await newInstance.getScheduledCount();
|
|
1261
|
-
|
|
572
|
+
expect4(scheduledCount).toBe(1);
|
|
1262
573
|
});
|
|
1263
|
-
|
|
574
|
+
test4("multiple scheduled tasks execute in order", async (c) => {
|
|
1264
575
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1265
576
|
const scheduled = client.scheduled.getOrCreate();
|
|
1266
577
|
await scheduled.clearHistory();
|
|
@@ -1269,13 +580,13 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1269
580
|
await scheduled.scheduleTaskAfterWithId("third", 500);
|
|
1270
581
|
await waitFor(driverTestConfig, 200);
|
|
1271
582
|
const history1 = await scheduled.getTaskHistory();
|
|
1272
|
-
|
|
583
|
+
expect4(history1).toEqual(["first"]);
|
|
1273
584
|
await waitFor(driverTestConfig, 200);
|
|
1274
585
|
const history2 = await scheduled.getTaskHistory();
|
|
1275
|
-
|
|
586
|
+
expect4(history2).toEqual(["first", "second"]);
|
|
1276
587
|
await waitFor(driverTestConfig, 200);
|
|
1277
588
|
const history3 = await scheduled.getTaskHistory();
|
|
1278
|
-
|
|
589
|
+
expect4(history3).toEqual(["first", "second", "third"]);
|
|
1279
590
|
});
|
|
1280
591
|
});
|
|
1281
592
|
}
|
|
@@ -1283,13 +594,11 @@ function runActorScheduleTests(driverTestConfig) {
|
|
|
1283
594
|
}
|
|
1284
595
|
|
|
1285
596
|
// src/driver-test-suite/tests/actor-sleep.ts
|
|
1286
|
-
import { describe as
|
|
597
|
+
import { describe as describe5, expect as expect5, test as test5 } from "vitest";
|
|
1287
598
|
|
|
1288
599
|
// fixtures/driver-test-suite/sleep.ts
|
|
1289
600
|
var SLEEP_TIMEOUT = 500;
|
|
1290
601
|
var sleep = actor({
|
|
1291
|
-
onAuth: () => {
|
|
1292
|
-
},
|
|
1293
602
|
state: { startCount: 0, sleepCount: 0 },
|
|
1294
603
|
onStart: (c) => {
|
|
1295
604
|
c.state.startCount += 1;
|
|
@@ -1316,8 +625,6 @@ var sleep = actor({
|
|
|
1316
625
|
}
|
|
1317
626
|
});
|
|
1318
627
|
var sleepWithLongRpc = actor({
|
|
1319
|
-
onAuth: () => {
|
|
1320
|
-
},
|
|
1321
628
|
state: { startCount: 0, sleepCount: 0 },
|
|
1322
629
|
createVars: () => ({}),
|
|
1323
630
|
onStart: (c) => {
|
|
@@ -1347,8 +654,6 @@ var sleepWithLongRpc = actor({
|
|
|
1347
654
|
}
|
|
1348
655
|
});
|
|
1349
656
|
var sleepWithRawHttp = actor({
|
|
1350
|
-
onAuth: () => {
|
|
1351
|
-
},
|
|
1352
657
|
state: { startCount: 0, sleepCount: 0, requestCount: 0 },
|
|
1353
658
|
onStart: (c) => {
|
|
1354
659
|
c.state.startCount += 1;
|
|
@@ -1361,7 +666,7 @@ var sleepWithRawHttp = actor({
|
|
|
1361
666
|
const url = new URL(request.url);
|
|
1362
667
|
if (url.pathname === "/long-request") {
|
|
1363
668
|
const duration = parseInt(url.searchParams.get("duration") || "1000");
|
|
1364
|
-
c.log.info("starting long fetch request",
|
|
669
|
+
c.log.info({ msg: "starting long fetch request", duration });
|
|
1365
670
|
await new Promise((resolve2) => setTimeout(resolve2, duration));
|
|
1366
671
|
c.log.info("finished long fetch request");
|
|
1367
672
|
return new Response(JSON.stringify({ completed: true }), {
|
|
@@ -1384,8 +689,6 @@ var sleepWithRawHttp = actor({
|
|
|
1384
689
|
}
|
|
1385
690
|
});
|
|
1386
691
|
var sleepWithRawWebSocket = actor({
|
|
1387
|
-
onAuth: () => {
|
|
1388
|
-
},
|
|
1389
692
|
state: { startCount: 0, sleepCount: 0, connectionCount: 0 },
|
|
1390
693
|
onStart: (c) => {
|
|
1391
694
|
c.state.startCount += 1;
|
|
@@ -1395,7 +698,8 @@ var sleepWithRawWebSocket = actor({
|
|
|
1395
698
|
},
|
|
1396
699
|
onWebSocket: (c, websocket, opts) => {
|
|
1397
700
|
c.state.connectionCount += 1;
|
|
1398
|
-
c.log.info(
|
|
701
|
+
c.log.info({
|
|
702
|
+
msg: "websocket connected",
|
|
1399
703
|
connectionCount: c.state.connectionCount
|
|
1400
704
|
});
|
|
1401
705
|
websocket.send(
|
|
@@ -1428,7 +732,8 @@ var sleepWithRawWebSocket = actor({
|
|
|
1428
732
|
});
|
|
1429
733
|
websocket.addEventListener("close", () => {
|
|
1430
734
|
c.state.connectionCount -= 1;
|
|
1431
|
-
c.log.info(
|
|
735
|
+
c.log.info({
|
|
736
|
+
msg: "websocket disconnected",
|
|
1432
737
|
connectionCount: c.state.connectionCount
|
|
1433
738
|
});
|
|
1434
739
|
});
|
|
@@ -1447,8 +752,6 @@ var sleepWithRawWebSocket = actor({
|
|
|
1447
752
|
}
|
|
1448
753
|
});
|
|
1449
754
|
var sleepWithNoSleepOption = actor({
|
|
1450
|
-
onAuth: () => {
|
|
1451
|
-
},
|
|
1452
755
|
state: { startCount: 0, sleepCount: 0 },
|
|
1453
756
|
onStart: (c) => {
|
|
1454
757
|
c.state.startCount += 1;
|
|
@@ -1470,30 +773,30 @@ var sleepWithNoSleepOption = actor({
|
|
|
1470
773
|
// src/driver-test-suite/tests/actor-sleep.ts
|
|
1471
774
|
function runActorSleepTests(driverTestConfig) {
|
|
1472
775
|
var _a;
|
|
1473
|
-
|
|
1474
|
-
|
|
776
|
+
describe5.skipIf((_a = driverTestConfig.skip) == null ? void 0 : _a.sleep)("Actor Sleep Tests", () => {
|
|
777
|
+
test5("actor sleep persists state", async (c) => {
|
|
1475
778
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1476
779
|
const sleepActor = client.sleep.getOrCreate();
|
|
1477
780
|
{
|
|
1478
781
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1479
|
-
|
|
1480
|
-
|
|
782
|
+
expect5(sleepCount).toBe(0);
|
|
783
|
+
expect5(startCount).toBe(1);
|
|
1481
784
|
}
|
|
1482
785
|
await sleepActor.triggerSleep();
|
|
1483
786
|
await waitFor(driverTestConfig, 100);
|
|
1484
787
|
{
|
|
1485
788
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1486
|
-
|
|
1487
|
-
|
|
789
|
+
expect5(sleepCount).toBe(1);
|
|
790
|
+
expect5(startCount).toBe(2);
|
|
1488
791
|
}
|
|
1489
792
|
});
|
|
1490
|
-
|
|
793
|
+
test5("actor sleep persists state with connect", async (c) => {
|
|
1491
794
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1492
795
|
const sleepActor = client.sleep.getOrCreate().connect();
|
|
1493
796
|
{
|
|
1494
797
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1495
|
-
|
|
1496
|
-
|
|
798
|
+
expect5(sleepCount).toBe(0);
|
|
799
|
+
expect5(startCount).toBe(1);
|
|
1497
800
|
}
|
|
1498
801
|
await sleepActor.triggerSleep();
|
|
1499
802
|
await sleepActor.dispose();
|
|
@@ -1501,108 +804,108 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1501
804
|
const sleepActor2 = client.sleep.getOrCreate();
|
|
1502
805
|
{
|
|
1503
806
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1504
|
-
|
|
1505
|
-
|
|
807
|
+
expect5(sleepCount).toBe(1);
|
|
808
|
+
expect5(startCount).toBe(2);
|
|
1506
809
|
}
|
|
1507
810
|
});
|
|
1508
|
-
|
|
811
|
+
test5("actor automatically sleeps after timeout", async (c) => {
|
|
1509
812
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1510
813
|
const sleepActor = client.sleep.getOrCreate();
|
|
1511
814
|
{
|
|
1512
815
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1513
|
-
|
|
1514
|
-
|
|
816
|
+
expect5(sleepCount).toBe(0);
|
|
817
|
+
expect5(startCount).toBe(1);
|
|
1515
818
|
}
|
|
1516
819
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1517
820
|
{
|
|
1518
821
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1519
|
-
|
|
1520
|
-
|
|
822
|
+
expect5(sleepCount).toBe(1);
|
|
823
|
+
expect5(startCount).toBe(2);
|
|
1521
824
|
}
|
|
1522
825
|
});
|
|
1523
|
-
|
|
826
|
+
test5("actor automatically sleeps after timeout with connect", async (c) => {
|
|
1524
827
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1525
828
|
const sleepActor = client.sleep.getOrCreate().connect();
|
|
1526
829
|
{
|
|
1527
830
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1528
|
-
|
|
1529
|
-
|
|
831
|
+
expect5(sleepCount).toBe(0);
|
|
832
|
+
expect5(startCount).toBe(1);
|
|
1530
833
|
}
|
|
1531
834
|
await sleepActor.dispose();
|
|
1532
835
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1533
836
|
const sleepActor2 = client.sleep.getOrCreate();
|
|
1534
837
|
{
|
|
1535
838
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1536
|
-
|
|
1537
|
-
|
|
839
|
+
expect5(sleepCount).toBe(1);
|
|
840
|
+
expect5(startCount).toBe(2);
|
|
1538
841
|
}
|
|
1539
842
|
});
|
|
1540
|
-
|
|
843
|
+
test5("rpc calls keep actor awake", async (c) => {
|
|
1541
844
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1542
845
|
const sleepActor = client.sleep.getOrCreate();
|
|
1543
846
|
{
|
|
1544
847
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1545
|
-
|
|
1546
|
-
|
|
848
|
+
expect5(sleepCount).toBe(0);
|
|
849
|
+
expect5(startCount).toBe(1);
|
|
1547
850
|
}
|
|
1548
851
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT - 100);
|
|
1549
852
|
{
|
|
1550
853
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1551
|
-
|
|
1552
|
-
|
|
854
|
+
expect5(sleepCount).toBe(0);
|
|
855
|
+
expect5(startCount).toBe(1);
|
|
1553
856
|
}
|
|
1554
857
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT - 100);
|
|
1555
858
|
{
|
|
1556
859
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1557
|
-
|
|
1558
|
-
|
|
860
|
+
expect5(sleepCount).toBe(0);
|
|
861
|
+
expect5(startCount).toBe(1);
|
|
1559
862
|
}
|
|
1560
863
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1561
864
|
{
|
|
1562
865
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1563
|
-
|
|
1564
|
-
|
|
866
|
+
expect5(sleepCount).toBe(1);
|
|
867
|
+
expect5(startCount).toBe(2);
|
|
1565
868
|
}
|
|
1566
869
|
});
|
|
1567
|
-
|
|
870
|
+
test5("alarms keep actor awake", async (c) => {
|
|
1568
871
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1569
872
|
const sleepActor = client.sleep.getOrCreate();
|
|
1570
873
|
{
|
|
1571
874
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1572
|
-
|
|
1573
|
-
|
|
875
|
+
expect5(sleepCount).toBe(0);
|
|
876
|
+
expect5(startCount).toBe(1);
|
|
1574
877
|
}
|
|
1575
878
|
await sleepActor.setAlarm(SLEEP_TIMEOUT - 100);
|
|
1576
879
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1577
880
|
{
|
|
1578
881
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1579
|
-
|
|
1580
|
-
|
|
882
|
+
expect5(sleepCount).toBe(0);
|
|
883
|
+
expect5(startCount).toBe(1);
|
|
1581
884
|
}
|
|
1582
885
|
});
|
|
1583
|
-
|
|
886
|
+
test5("alarms wake actors", async (c) => {
|
|
1584
887
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1585
888
|
const sleepActor = client.sleep.getOrCreate();
|
|
1586
889
|
{
|
|
1587
890
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1588
|
-
|
|
1589
|
-
|
|
891
|
+
expect5(sleepCount).toBe(0);
|
|
892
|
+
expect5(startCount).toBe(1);
|
|
1590
893
|
}
|
|
1591
894
|
await sleepActor.setAlarm(SLEEP_TIMEOUT + 100);
|
|
1592
895
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 200);
|
|
1593
896
|
{
|
|
1594
897
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1595
|
-
|
|
1596
|
-
|
|
898
|
+
expect5(sleepCount).toBe(1);
|
|
899
|
+
expect5(startCount).toBe(2);
|
|
1597
900
|
}
|
|
1598
901
|
});
|
|
1599
|
-
|
|
902
|
+
test5("long running rpcs keep actor awake", async (c) => {
|
|
1600
903
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1601
904
|
const sleepActor = client.sleepWithLongRpc.getOrCreate().connect();
|
|
1602
905
|
{
|
|
1603
906
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1604
|
-
|
|
1605
|
-
|
|
907
|
+
expect5(sleepCount).toBe(0);
|
|
908
|
+
expect5(startCount).toBe(1);
|
|
1606
909
|
}
|
|
1607
910
|
const waitPromise = new Promise(
|
|
1608
911
|
(resolve2) => sleepActor.once("waiting", resolve2)
|
|
@@ -1614,19 +917,19 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1614
917
|
await longRunningPromise;
|
|
1615
918
|
{
|
|
1616
919
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1617
|
-
|
|
1618
|
-
|
|
920
|
+
expect5(sleepCount).toBe(0);
|
|
921
|
+
expect5(startCount).toBe(1);
|
|
1619
922
|
}
|
|
1620
923
|
await sleepActor.dispose();
|
|
1621
924
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1622
925
|
const sleepActor2 = client.sleepWithLongRpc.getOrCreate();
|
|
1623
926
|
{
|
|
1624
927
|
const { startCount, sleepCount } = await sleepActor2.getCounts();
|
|
1625
|
-
|
|
1626
|
-
|
|
928
|
+
expect5(sleepCount).toBe(1);
|
|
929
|
+
expect5(startCount).toBe(2);
|
|
1627
930
|
}
|
|
1628
931
|
});
|
|
1629
|
-
|
|
932
|
+
test5("active raw websockets keep actor awake", async (c) => {
|
|
1630
933
|
const { client, endpoint: baseUrl } = await setupDriverTest(
|
|
1631
934
|
c,
|
|
1632
935
|
driverTestConfig
|
|
@@ -1634,8 +937,8 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1634
937
|
const sleepActor = client.sleepWithRawWebSocket.getOrCreate();
|
|
1635
938
|
{
|
|
1636
939
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1637
|
-
|
|
1638
|
-
|
|
940
|
+
expect5(sleepCount).toBe(0);
|
|
941
|
+
expect5(startCount).toBe(1);
|
|
1639
942
|
}
|
|
1640
943
|
const ws = await sleepActor.websocket();
|
|
1641
944
|
await new Promise((resolve2, reject) => {
|
|
@@ -1660,18 +963,18 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1660
963
|
}
|
|
1661
964
|
};
|
|
1662
965
|
});
|
|
1663
|
-
|
|
1664
|
-
|
|
966
|
+
expect5(counts.sleepCount).toBe(0);
|
|
967
|
+
expect5(counts.startCount).toBe(1);
|
|
1665
968
|
ws.close();
|
|
1666
969
|
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
1667
970
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1668
971
|
{
|
|
1669
972
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1670
|
-
|
|
1671
|
-
|
|
973
|
+
expect5(sleepCount).toBe(1);
|
|
974
|
+
expect5(startCount).toBe(2);
|
|
1672
975
|
}
|
|
1673
976
|
});
|
|
1674
|
-
|
|
977
|
+
test5("active raw fetch requests keep actor awake", async (c) => {
|
|
1675
978
|
const { client, endpoint: baseUrl } = await setupDriverTest(
|
|
1676
979
|
c,
|
|
1677
980
|
driverTestConfig
|
|
@@ -1679,8 +982,8 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1679
982
|
const sleepActor = client.sleepWithRawHttp.getOrCreate();
|
|
1680
983
|
{
|
|
1681
984
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1682
|
-
|
|
1683
|
-
|
|
985
|
+
expect5(sleepCount).toBe(0);
|
|
986
|
+
expect5(startCount).toBe(1);
|
|
1684
987
|
}
|
|
1685
988
|
const fetchDuration = SLEEP_TIMEOUT + 100;
|
|
1686
989
|
const fetchPromise = sleepActor.fetch(
|
|
@@ -1688,67 +991,67 @@ function runActorSleepTests(driverTestConfig) {
|
|
|
1688
991
|
);
|
|
1689
992
|
const response = await fetchPromise;
|
|
1690
993
|
const result = await response.json();
|
|
1691
|
-
|
|
994
|
+
expect5(result.completed).toBe(true);
|
|
1692
995
|
{
|
|
1693
996
|
const { startCount, sleepCount, requestCount } = await sleepActor.getCounts();
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
997
|
+
expect5(sleepCount).toBe(0);
|
|
998
|
+
expect5(startCount).toBe(1);
|
|
999
|
+
expect5(requestCount).toBe(1);
|
|
1697
1000
|
}
|
|
1698
1001
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1699
1002
|
{
|
|
1700
1003
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1701
|
-
|
|
1702
|
-
|
|
1004
|
+
expect5(sleepCount).toBe(1);
|
|
1005
|
+
expect5(startCount).toBe(2);
|
|
1703
1006
|
}
|
|
1704
1007
|
});
|
|
1705
|
-
|
|
1008
|
+
test5("noSleep option disables sleeping", async (c) => {
|
|
1706
1009
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1707
1010
|
const sleepActor = client.sleepWithNoSleepOption.getOrCreate();
|
|
1708
1011
|
{
|
|
1709
1012
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1710
|
-
|
|
1711
|
-
|
|
1013
|
+
expect5(sleepCount).toBe(0);
|
|
1014
|
+
expect5(startCount).toBe(1);
|
|
1712
1015
|
}
|
|
1713
1016
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1714
1017
|
{
|
|
1715
1018
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1716
|
-
|
|
1717
|
-
|
|
1019
|
+
expect5(sleepCount).toBe(0);
|
|
1020
|
+
expect5(startCount).toBe(1);
|
|
1718
1021
|
}
|
|
1719
1022
|
await waitFor(driverTestConfig, SLEEP_TIMEOUT + 100);
|
|
1720
1023
|
{
|
|
1721
1024
|
const { startCount, sleepCount } = await sleepActor.getCounts();
|
|
1722
|
-
|
|
1723
|
-
|
|
1025
|
+
expect5(sleepCount).toBe(0);
|
|
1026
|
+
expect5(startCount).toBe(1);
|
|
1724
1027
|
}
|
|
1725
1028
|
});
|
|
1726
1029
|
});
|
|
1727
1030
|
}
|
|
1728
1031
|
|
|
1729
1032
|
// src/driver-test-suite/tests/actor-state.ts
|
|
1730
|
-
import { describe as
|
|
1033
|
+
import { describe as describe6, expect as expect6, test as test6 } from "vitest";
|
|
1731
1034
|
function runActorStateTests(driverTestConfig) {
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1035
|
+
describe6("Actor State Tests", () => {
|
|
1036
|
+
describe6("State Persistence", () => {
|
|
1037
|
+
test6("persists state between actor instances", async (c) => {
|
|
1735
1038
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1736
1039
|
const counterInstance = client.counter.getOrCreate();
|
|
1737
1040
|
const initialCount = await counterInstance.increment(5);
|
|
1738
|
-
|
|
1041
|
+
expect6(initialCount).toBe(5);
|
|
1739
1042
|
const sameInstance = client.counter.getOrCreate();
|
|
1740
1043
|
const persistedCount = await sameInstance.increment(3);
|
|
1741
|
-
|
|
1044
|
+
expect6(persistedCount).toBe(8);
|
|
1742
1045
|
});
|
|
1743
|
-
|
|
1046
|
+
test6("restores state after actor disconnect/reconnect", async (c) => {
|
|
1744
1047
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1745
1048
|
const counterInstance = client.counter.getOrCreate();
|
|
1746
1049
|
await counterInstance.increment(5);
|
|
1747
1050
|
const reconnectedInstance = client.counter.getOrCreate();
|
|
1748
1051
|
const persistedCount = await reconnectedInstance.increment(0);
|
|
1749
|
-
|
|
1052
|
+
expect6(persistedCount).toBe(5);
|
|
1750
1053
|
});
|
|
1751
|
-
|
|
1054
|
+
test6("maintains separate state for different actors", async (c) => {
|
|
1752
1055
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1753
1056
|
const counterA = client.counter.getOrCreate(["counter-a"]);
|
|
1754
1057
|
await counterA.increment(5);
|
|
@@ -1756,8 +1059,8 @@ function runActorStateTests(driverTestConfig) {
|
|
|
1756
1059
|
await counterB.increment(10);
|
|
1757
1060
|
const countA = await counterA.increment(0);
|
|
1758
1061
|
const countB = await counterB.increment(0);
|
|
1759
|
-
|
|
1760
|
-
|
|
1062
|
+
expect6(countA).toBe(5);
|
|
1063
|
+
expect6(countB).toBe(10);
|
|
1761
1064
|
});
|
|
1762
1065
|
});
|
|
1763
1066
|
});
|
|
@@ -1765,101 +1068,101 @@ function runActorStateTests(driverTestConfig) {
|
|
|
1765
1068
|
|
|
1766
1069
|
// src/driver-test-suite/tests/actor-driver.ts
|
|
1767
1070
|
function runActorDriverTests(driverTestConfig) {
|
|
1768
|
-
|
|
1071
|
+
describe7("Actor Driver Tests", () => {
|
|
1769
1072
|
runActorStateTests(driverTestConfig);
|
|
1770
1073
|
runActorScheduleTests(driverTestConfig);
|
|
1771
1074
|
});
|
|
1772
1075
|
}
|
|
1773
1076
|
function runActorDriverTestsWithTransport(driverTestConfig) {
|
|
1774
|
-
|
|
1077
|
+
describe7("Actor Driver Tests", () => {
|
|
1775
1078
|
runActorSleepTests(driverTestConfig);
|
|
1776
1079
|
});
|
|
1777
1080
|
}
|
|
1778
1081
|
|
|
1779
1082
|
// src/driver-test-suite/tests/actor-error-handling.ts
|
|
1780
|
-
import { describe as
|
|
1083
|
+
import { describe as describe8, expect as expect7, test as test7 } from "vitest";
|
|
1781
1084
|
function runActorErrorHandlingTests(driverTestConfig) {
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1085
|
+
describe8("Actor Error Handling Tests", () => {
|
|
1086
|
+
describe8("UserError Handling", () => {
|
|
1087
|
+
test7("should handle simple UserError with message", async (c) => {
|
|
1785
1088
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1786
1089
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1787
1090
|
try {
|
|
1788
1091
|
await handle.throwSimpleError();
|
|
1789
|
-
|
|
1092
|
+
expect7(true).toBe(false);
|
|
1790
1093
|
} catch (error) {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1094
|
+
expect7(error.message).toBe("Simple error message");
|
|
1095
|
+
expect7(error.code).toBe("user_error");
|
|
1096
|
+
expect7(error.metadata).toBeUndefined();
|
|
1794
1097
|
}
|
|
1795
1098
|
});
|
|
1796
|
-
|
|
1099
|
+
test7("should handle detailed UserError with code and metadata", async (c) => {
|
|
1797
1100
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1798
1101
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1799
1102
|
try {
|
|
1800
1103
|
await handle.throwDetailedError();
|
|
1801
|
-
|
|
1104
|
+
expect7(true).toBe(false);
|
|
1802
1105
|
} catch (error) {
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1106
|
+
expect7(error.message).toBe("Detailed error message");
|
|
1107
|
+
expect7(error.code).toBe("detailed_error");
|
|
1108
|
+
expect7(error.metadata).toBeDefined();
|
|
1109
|
+
expect7(error.metadata.reason).toBe("test");
|
|
1110
|
+
expect7(error.metadata.timestamp).toBeDefined();
|
|
1808
1111
|
}
|
|
1809
1112
|
});
|
|
1810
1113
|
});
|
|
1811
|
-
|
|
1812
|
-
|
|
1114
|
+
describe8("Internal Error Handling", () => {
|
|
1115
|
+
test7("should convert internal errors to safe format", async (c) => {
|
|
1813
1116
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1814
1117
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1815
1118
|
try {
|
|
1816
1119
|
await handle.throwInternalError();
|
|
1817
|
-
|
|
1120
|
+
expect7(true).toBe(false);
|
|
1818
1121
|
} catch (error) {
|
|
1819
1122
|
if (driverTestConfig.clientType === "http") {
|
|
1820
|
-
|
|
1821
|
-
|
|
1123
|
+
expect7(error.code).toBe(INTERNAL_ERROR_CODE);
|
|
1124
|
+
expect7(error.message).toBe(INTERNAL_ERROR_DESCRIPTION);
|
|
1822
1125
|
} else if (driverTestConfig.clientType === "inline") {
|
|
1823
|
-
|
|
1824
|
-
|
|
1126
|
+
expect7(error.code).toBe(INTERNAL_ERROR_CODE);
|
|
1127
|
+
expect7(error.message).toBe("This is an internal error");
|
|
1825
1128
|
} else {
|
|
1826
1129
|
assertUnreachable(driverTestConfig.clientType);
|
|
1827
1130
|
}
|
|
1828
1131
|
}
|
|
1829
1132
|
});
|
|
1830
1133
|
});
|
|
1831
|
-
|
|
1832
|
-
|
|
1134
|
+
describe8.skip("Action Timeout", () => {
|
|
1135
|
+
test7("should handle action timeouts with custom duration", async (c) => {
|
|
1833
1136
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1834
1137
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1835
1138
|
const timeoutPromise = handle.timeoutAction();
|
|
1836
1139
|
try {
|
|
1837
1140
|
await timeoutPromise;
|
|
1838
|
-
|
|
1141
|
+
expect7(true).toBe(false);
|
|
1839
1142
|
} catch (error) {
|
|
1840
|
-
|
|
1143
|
+
expect7(error.message).toMatch(/timed out/i);
|
|
1841
1144
|
}
|
|
1842
1145
|
});
|
|
1843
|
-
|
|
1146
|
+
test7("should successfully run actions within timeout", async (c) => {
|
|
1844
1147
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1845
1148
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1846
1149
|
const result = await handle.delayedAction(200);
|
|
1847
|
-
|
|
1150
|
+
expect7(result).toBe("Completed after 200ms");
|
|
1848
1151
|
});
|
|
1849
|
-
|
|
1152
|
+
test7("should respect different timeouts for different actors", async (c) => {
|
|
1850
1153
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1851
1154
|
try {
|
|
1852
1155
|
await client.customTimeoutActor.getOrCreate().slowAction();
|
|
1853
|
-
|
|
1156
|
+
expect7(true).toBe(false);
|
|
1854
1157
|
} catch (error) {
|
|
1855
|
-
|
|
1158
|
+
expect7(error.message).toMatch(/timed out/i);
|
|
1856
1159
|
}
|
|
1857
1160
|
const quickResult = await client.customTimeoutActor.getOrCreate().quickAction();
|
|
1858
|
-
|
|
1161
|
+
expect7(quickResult).toBe("Quick action completed");
|
|
1859
1162
|
});
|
|
1860
1163
|
});
|
|
1861
|
-
|
|
1862
|
-
|
|
1164
|
+
describe8("Error Recovery", () => {
|
|
1165
|
+
test7("should continue working after errors", async (c) => {
|
|
1863
1166
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1864
1167
|
const handle = client.errorHandlingActor.getOrCreate();
|
|
1865
1168
|
try {
|
|
@@ -1867,150 +1170,173 @@ function runActorErrorHandlingTests(driverTestConfig) {
|
|
|
1867
1170
|
} catch (error) {
|
|
1868
1171
|
}
|
|
1869
1172
|
const result = await handle.successfulAction();
|
|
1870
|
-
|
|
1173
|
+
expect7(result).toBe("success");
|
|
1871
1174
|
});
|
|
1872
1175
|
});
|
|
1873
1176
|
});
|
|
1874
1177
|
}
|
|
1875
1178
|
|
|
1876
1179
|
// src/driver-test-suite/tests/actor-handle.ts
|
|
1877
|
-
import { describe as
|
|
1180
|
+
import { describe as describe9, expect as expect8, test as test8 } from "vitest";
|
|
1878
1181
|
function runActorHandleTests(driverTestConfig) {
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1182
|
+
describe9("Actor Handle Tests", () => {
|
|
1183
|
+
describe9("Access Methods", () => {
|
|
1184
|
+
test8("should use .get() to access a actor", async (c) => {
|
|
1882
1185
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1883
1186
|
await client.counter.create(["test-get-handle"]);
|
|
1884
1187
|
const handle = client.counter.get(["test-get-handle"]);
|
|
1885
1188
|
const count = await handle.increment(5);
|
|
1886
|
-
|
|
1189
|
+
expect8(count).toBe(5);
|
|
1887
1190
|
const retrievedCount = await handle.getCount();
|
|
1888
|
-
|
|
1191
|
+
expect8(retrievedCount).toBe(5);
|
|
1889
1192
|
});
|
|
1890
|
-
|
|
1193
|
+
test8("should use .getForId() to access a actor by ID", async (c) => {
|
|
1891
1194
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1892
1195
|
const handle = client.counter.getOrCreate(["test-get-for-id-handle"]);
|
|
1893
1196
|
await handle.increment(3);
|
|
1894
1197
|
const actorId = await handle.resolve();
|
|
1895
1198
|
const idHandle = client.counter.getForId(actorId);
|
|
1896
1199
|
const count = await idHandle.getCount();
|
|
1897
|
-
|
|
1200
|
+
expect8(count).toBe(3);
|
|
1898
1201
|
const newCount = await idHandle.increment(4);
|
|
1899
|
-
|
|
1202
|
+
expect8(newCount).toBe(7);
|
|
1900
1203
|
});
|
|
1901
|
-
|
|
1204
|
+
test8("should use .getOrCreate() to access or create a actor", async (c) => {
|
|
1902
1205
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1903
1206
|
const handle = client.counter.getOrCreate([
|
|
1904
1207
|
"test-get-or-create-handle"
|
|
1905
1208
|
]);
|
|
1906
1209
|
const count = await handle.increment(7);
|
|
1907
|
-
|
|
1210
|
+
expect8(count).toBe(7);
|
|
1908
1211
|
const sameHandle = client.counter.getOrCreate([
|
|
1909
1212
|
"test-get-or-create-handle"
|
|
1910
1213
|
]);
|
|
1911
1214
|
const retrievedCount = await sameHandle.getCount();
|
|
1912
|
-
|
|
1215
|
+
expect8(retrievedCount).toBe(7);
|
|
1913
1216
|
});
|
|
1914
|
-
|
|
1217
|
+
test8("should use (await create()) to create and return a handle", async (c) => {
|
|
1915
1218
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1916
1219
|
const handle = await client.counter.create(["test-create-handle"]);
|
|
1917
1220
|
const count = await handle.increment(9);
|
|
1918
|
-
|
|
1221
|
+
expect8(count).toBe(9);
|
|
1919
1222
|
const retrievedCount = await handle.getCount();
|
|
1920
|
-
|
|
1223
|
+
expect8(retrievedCount).toBe(9);
|
|
1224
|
+
});
|
|
1225
|
+
test8("errors when calling create twice with the same key", async (c) => {
|
|
1226
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1227
|
+
const key = ["duplicate-create-handle", crypto.randomUUID()];
|
|
1228
|
+
await client.counter.create(key);
|
|
1229
|
+
try {
|
|
1230
|
+
await client.counter.create(key);
|
|
1231
|
+
expect8.fail("did not error on duplicate create");
|
|
1232
|
+
} catch (err) {
|
|
1233
|
+
expect8(err.group).toBe("actor");
|
|
1234
|
+
expect8(err.code).toBe("already_exists");
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
test8(".get().resolve() errors for non-existent actor", async (c) => {
|
|
1238
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1239
|
+
const missingId = `nonexistent-${crypto.randomUUID()}`;
|
|
1240
|
+
try {
|
|
1241
|
+
await client.counter.get([missingId]).resolve();
|
|
1242
|
+
expect8.fail("did not error for get().resolve() on missing actor");
|
|
1243
|
+
} catch (err) {
|
|
1244
|
+
expect8(err.group).toBe("actor");
|
|
1245
|
+
expect8(err.code).toBe("not_found");
|
|
1246
|
+
}
|
|
1921
1247
|
});
|
|
1922
1248
|
});
|
|
1923
|
-
|
|
1924
|
-
|
|
1249
|
+
describe9("Action Functionality", () => {
|
|
1250
|
+
test8("should call actions directly on the handle", async (c) => {
|
|
1925
1251
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1926
1252
|
const handle = client.counter.getOrCreate(["test-action-handle"]);
|
|
1927
1253
|
const count1 = await handle.increment(3);
|
|
1928
|
-
|
|
1254
|
+
expect8(count1).toBe(3);
|
|
1929
1255
|
const count2 = await handle.increment(5);
|
|
1930
|
-
|
|
1256
|
+
expect8(count2).toBe(8);
|
|
1931
1257
|
const retrievedCount = await handle.getCount();
|
|
1932
|
-
|
|
1258
|
+
expect8(retrievedCount).toBe(8);
|
|
1933
1259
|
});
|
|
1934
|
-
|
|
1260
|
+
test8("should handle independent handles to the same actor", async (c) => {
|
|
1935
1261
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1936
1262
|
const handle1 = client.counter.getOrCreate(["test-multiple-handles"]);
|
|
1937
1263
|
const handle2 = client.counter.get(["test-multiple-handles"]);
|
|
1938
1264
|
await handle1.increment(3);
|
|
1939
1265
|
const count = await handle2.getCount();
|
|
1940
|
-
|
|
1266
|
+
expect8(count).toBe(3);
|
|
1941
1267
|
const finalCount = await handle2.increment(4);
|
|
1942
|
-
|
|
1268
|
+
expect8(finalCount).toBe(7);
|
|
1943
1269
|
const checkCount = await handle1.getCount();
|
|
1944
|
-
|
|
1270
|
+
expect8(checkCount).toBe(7);
|
|
1945
1271
|
});
|
|
1946
|
-
|
|
1272
|
+
test8("should resolve a actor's ID", async (c) => {
|
|
1947
1273
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1948
1274
|
const handle = client.counter.getOrCreate(["test-resolve-id"]);
|
|
1949
1275
|
await handle.increment(1);
|
|
1950
1276
|
const actorId = await handle.resolve();
|
|
1951
|
-
|
|
1952
|
-
|
|
1277
|
+
expect8(typeof actorId).toBe("string");
|
|
1278
|
+
expect8(actorId).not.toBe("");
|
|
1953
1279
|
const idHandle = client.counter.getForId(actorId);
|
|
1954
1280
|
const count = await idHandle.getCount();
|
|
1955
|
-
|
|
1281
|
+
expect8(count).toBe(1);
|
|
1956
1282
|
});
|
|
1957
1283
|
});
|
|
1958
|
-
|
|
1959
|
-
|
|
1284
|
+
describe9("Lifecycle Hooks", () => {
|
|
1285
|
+
test8("should trigger lifecycle hooks on actor creation", async (c) => {
|
|
1960
1286
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1961
1287
|
const handle = client.counterWithLifecycle.getOrCreate([
|
|
1962
1288
|
"test-lifecycle-handle"
|
|
1963
1289
|
]);
|
|
1964
1290
|
const initialEvents = await handle.getEvents();
|
|
1965
|
-
|
|
1291
|
+
expect8(initialEvents).toContain("onStart");
|
|
1966
1292
|
const sameHandle = client.counterWithLifecycle.getOrCreate([
|
|
1967
1293
|
"test-lifecycle-handle"
|
|
1968
1294
|
]);
|
|
1969
1295
|
const events = await sameHandle.getEvents();
|
|
1970
|
-
|
|
1971
|
-
|
|
1296
|
+
expect8(events).toContain("onStart");
|
|
1297
|
+
expect8(events.filter((e) => e === "onStart").length).toBe(1);
|
|
1972
1298
|
});
|
|
1973
|
-
|
|
1299
|
+
test8("should trigger lifecycle hooks for each Action call", async (c) => {
|
|
1974
1300
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
1975
1301
|
const viewHandle = client.counterWithLifecycle.getOrCreate([
|
|
1976
1302
|
"test-lifecycle-action"
|
|
1977
1303
|
]);
|
|
1978
1304
|
const initialEvents = await viewHandle.getEvents();
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1305
|
+
expect8(initialEvents).toContain("onStart");
|
|
1306
|
+
expect8(initialEvents).not.toContain("onBeforeConnect");
|
|
1307
|
+
expect8(initialEvents).not.toContain("onConnect");
|
|
1308
|
+
expect8(initialEvents).not.toContain("onDisconnect");
|
|
1983
1309
|
const trackingHandle = client.counterWithLifecycle.getOrCreate(
|
|
1984
1310
|
["test-lifecycle-action"],
|
|
1985
1311
|
{ params: { trackLifecycle: true } }
|
|
1986
1312
|
);
|
|
1987
1313
|
await trackingHandle.increment(5);
|
|
1988
1314
|
const eventsAfterAction = await viewHandle.getEvents();
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1315
|
+
expect8(eventsAfterAction).toContain("onBeforeConnect");
|
|
1316
|
+
expect8(eventsAfterAction).toContain("onConnect");
|
|
1317
|
+
expect8(eventsAfterAction).toContain("onDisconnect");
|
|
1318
|
+
expect8(
|
|
1993
1319
|
eventsAfterAction.filter((e) => e === "onBeforeConnect").length
|
|
1994
1320
|
).toBe(1);
|
|
1995
|
-
|
|
1321
|
+
expect8(eventsAfterAction.filter((e) => e === "onConnect").length).toBe(
|
|
1996
1322
|
1
|
|
1997
1323
|
);
|
|
1998
|
-
|
|
1324
|
+
expect8(
|
|
1999
1325
|
eventsAfterAction.filter((e) => e === "onDisconnect").length
|
|
2000
1326
|
).toBe(1);
|
|
2001
1327
|
await trackingHandle.increment(10);
|
|
2002
1328
|
const eventsAfterSecondAction = await viewHandle.getEvents();
|
|
2003
|
-
|
|
1329
|
+
expect8(
|
|
2004
1330
|
eventsAfterSecondAction.filter((e) => e === "onBeforeConnect").length
|
|
2005
1331
|
).toBe(2);
|
|
2006
|
-
|
|
1332
|
+
expect8(
|
|
2007
1333
|
eventsAfterSecondAction.filter((e) => e === "onConnect").length
|
|
2008
1334
|
).toBe(2);
|
|
2009
|
-
|
|
1335
|
+
expect8(
|
|
2010
1336
|
eventsAfterSecondAction.filter((e) => e === "onDisconnect").length
|
|
2011
1337
|
).toBe(2);
|
|
2012
1338
|
});
|
|
2013
|
-
|
|
1339
|
+
test8("should trigger lifecycle hooks for each Action call across multiple handles", async (c) => {
|
|
2014
1340
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2015
1341
|
const viewHandle = client.counterWithLifecycle.getOrCreate([
|
|
2016
1342
|
"test-lifecycle-multi-handle"
|
|
@@ -2026,35 +1352,35 @@ function runActorHandleTests(driverTestConfig) {
|
|
|
2026
1352
|
await trackingHandle1.increment(5);
|
|
2027
1353
|
await trackingHandle2.increment(10);
|
|
2028
1354
|
const events = await viewHandle.getEvents();
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
1355
|
+
expect8(events.filter((e) => e === "onStart").length).toBe(1);
|
|
1356
|
+
expect8(events.filter((e) => e === "onBeforeConnect").length).toBe(2);
|
|
1357
|
+
expect8(events.filter((e) => e === "onConnect").length).toBe(2);
|
|
1358
|
+
expect8(events.filter((e) => e === "onDisconnect").length).toBe(2);
|
|
2033
1359
|
});
|
|
2034
1360
|
});
|
|
2035
1361
|
});
|
|
2036
1362
|
}
|
|
2037
1363
|
|
|
2038
1364
|
// src/driver-test-suite/tests/actor-inline-client.ts
|
|
2039
|
-
import { describe as
|
|
1365
|
+
import { describe as describe10, expect as expect9, test as test9 } from "vitest";
|
|
2040
1366
|
function runActorInlineClientTests(driverTestConfig) {
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
1367
|
+
describe10("Actor Inline Client Tests", () => {
|
|
1368
|
+
describe10("Stateless Client Calls", () => {
|
|
1369
|
+
test9("should make stateless calls to other actors", async (c) => {
|
|
2044
1370
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2045
1371
|
const inlineClientHandle = client.inlineClientActor.getOrCreate([
|
|
2046
1372
|
"inline-client-test"
|
|
2047
1373
|
]);
|
|
2048
1374
|
const result = await inlineClientHandle.callCounterIncrement(5);
|
|
2049
|
-
|
|
1375
|
+
expect9(result).toBe(5);
|
|
2050
1376
|
const counterState = await inlineClientHandle.getCounterState();
|
|
2051
|
-
|
|
1377
|
+
expect9(counterState).toBe(5);
|
|
2052
1378
|
const messages = await inlineClientHandle.getMessages();
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
1379
|
+
expect9(messages).toHaveLength(2);
|
|
1380
|
+
expect9(messages[0]).toContain("Called counter.increment(5), result: 5");
|
|
1381
|
+
expect9(messages[1]).toContain("Got counter state: 5");
|
|
2056
1382
|
});
|
|
2057
|
-
|
|
1383
|
+
test9("should handle multiple stateless calls", async (c) => {
|
|
2058
1384
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2059
1385
|
const inlineClientHandle = client.inlineClientActor.getOrCreate([
|
|
2060
1386
|
"inline-client-multi"
|
|
@@ -2063,56 +1389,56 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
2063
1389
|
const result1 = await inlineClientHandle.callCounterIncrement(3);
|
|
2064
1390
|
const result2 = await inlineClientHandle.callCounterIncrement(7);
|
|
2065
1391
|
const finalState = await inlineClientHandle.getCounterState();
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
1392
|
+
expect9(result1).toBe(3);
|
|
1393
|
+
expect9(result2).toBe(10);
|
|
1394
|
+
expect9(finalState).toBe(10);
|
|
2069
1395
|
const messages = await inlineClientHandle.getMessages();
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
1396
|
+
expect9(messages).toHaveLength(3);
|
|
1397
|
+
expect9(messages[0]).toContain("Called counter.increment(3), result: 3");
|
|
1398
|
+
expect9(messages[1]).toContain(
|
|
2073
1399
|
"Called counter.increment(7), result: 10"
|
|
2074
1400
|
);
|
|
2075
|
-
|
|
1401
|
+
expect9(messages[2]).toContain("Got counter state: 10");
|
|
2076
1402
|
});
|
|
2077
1403
|
});
|
|
2078
|
-
|
|
2079
|
-
|
|
1404
|
+
describe10("Stateful Client Calls", () => {
|
|
1405
|
+
test9("should connect to other actors and receive events", async (c) => {
|
|
2080
1406
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2081
1407
|
const inlineClientHandle = client.inlineClientActor.getOrCreate([
|
|
2082
1408
|
"inline-client-stateful"
|
|
2083
1409
|
]);
|
|
2084
1410
|
await inlineClientHandle.clearMessages();
|
|
2085
1411
|
const result = await inlineClientHandle.connectToCounterAndIncrement(4);
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
1412
|
+
expect9(result.result1).toBe(4);
|
|
1413
|
+
expect9(result.result2).toBe(12);
|
|
1414
|
+
expect9(result.events).toEqual([4, 12]);
|
|
2089
1415
|
const messages = await inlineClientHandle.getMessages();
|
|
2090
|
-
|
|
2091
|
-
|
|
1416
|
+
expect9(messages).toHaveLength(1);
|
|
1417
|
+
expect9(messages[0]).toContain(
|
|
2092
1418
|
"Connected to counter, incremented by 4 and 8"
|
|
2093
1419
|
);
|
|
2094
|
-
|
|
2095
|
-
|
|
1420
|
+
expect9(messages[0]).toContain("results: 4, 12");
|
|
1421
|
+
expect9(messages[0]).toContain("events: [4,12]");
|
|
2096
1422
|
});
|
|
2097
|
-
|
|
1423
|
+
test9("should handle stateful connection independently", async (c) => {
|
|
2098
1424
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2099
1425
|
const inlineClientHandle = client.inlineClientActor.getOrCreate([
|
|
2100
1426
|
"inline-client-independent"
|
|
2101
1427
|
]);
|
|
2102
1428
|
await inlineClientHandle.clearMessages();
|
|
2103
1429
|
const result = await inlineClientHandle.connectToCounterAndIncrement(2);
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
1430
|
+
expect9(result.result1).toBe(2);
|
|
1431
|
+
expect9(result.result2).toBe(6);
|
|
1432
|
+
expect9(result.events).toEqual([2, 6]);
|
|
2107
1433
|
const messages = await inlineClientHandle.getMessages();
|
|
2108
|
-
|
|
2109
|
-
|
|
1434
|
+
expect9(messages).toHaveLength(1);
|
|
1435
|
+
expect9(messages[0]).toContain(
|
|
2110
1436
|
"Connected to counter, incremented by 2 and 4"
|
|
2111
1437
|
);
|
|
2112
1438
|
});
|
|
2113
1439
|
});
|
|
2114
|
-
|
|
2115
|
-
|
|
1440
|
+
describe10("Mixed Client Usage", () => {
|
|
1441
|
+
test9("should handle both stateless and stateful calls", async (c) => {
|
|
2116
1442
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2117
1443
|
const inlineClientHandle = client.inlineClientActor.getOrCreate([
|
|
2118
1444
|
"inline-client-mixed"
|
|
@@ -2120,15 +1446,15 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
2120
1446
|
await inlineClientHandle.clearMessages();
|
|
2121
1447
|
await inlineClientHandle.callCounterIncrement(1);
|
|
2122
1448
|
const statelessResult = await inlineClientHandle.getCounterState();
|
|
2123
|
-
|
|
1449
|
+
expect9(statelessResult).toBe(1);
|
|
2124
1450
|
const statefulResult = await inlineClientHandle.connectToCounterAndIncrement(3);
|
|
2125
|
-
|
|
2126
|
-
|
|
1451
|
+
expect9(statefulResult.result1).toBe(3);
|
|
1452
|
+
expect9(statefulResult.result2).toBe(9);
|
|
2127
1453
|
const messages = await inlineClientHandle.getMessages();
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
1454
|
+
expect9(messages).toHaveLength(3);
|
|
1455
|
+
expect9(messages[0]).toContain("Called counter.increment(1), result: 1");
|
|
1456
|
+
expect9(messages[1]).toContain("Got counter state: 1");
|
|
1457
|
+
expect9(messages[2]).toContain(
|
|
2132
1458
|
"Connected to counter, incremented by 3 and 6"
|
|
2133
1459
|
);
|
|
2134
1460
|
});
|
|
@@ -2137,11 +1463,11 @@ function runActorInlineClientTests(driverTestConfig) {
|
|
|
2137
1463
|
}
|
|
2138
1464
|
|
|
2139
1465
|
// src/driver-test-suite/tests/actor-inspector.ts
|
|
2140
|
-
import { describe as
|
|
1466
|
+
import { describe as describe11, expect as expect10, test as test10 } from "vitest";
|
|
2141
1467
|
function runActorInspectorTests(driverTestConfig) {
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
1468
|
+
describe11("Actor Inspector Tests", () => {
|
|
1469
|
+
describe11("Manager Inspector", () => {
|
|
1470
|
+
test10("should respond to ping", async (c) => {
|
|
2145
1471
|
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2146
1472
|
const http = createManagerInspectorClient(`${endpoint}/inspect`, {
|
|
2147
1473
|
headers: {
|
|
@@ -2149,11 +1475,11 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2149
1475
|
}
|
|
2150
1476
|
});
|
|
2151
1477
|
const response = await http.ping.$get();
|
|
2152
|
-
|
|
1478
|
+
expect10(response.status).toBe(200);
|
|
2153
1479
|
const data = await response.json();
|
|
2154
|
-
|
|
1480
|
+
expect10(data).toEqual({ message: "pong" });
|
|
2155
1481
|
});
|
|
2156
|
-
|
|
1482
|
+
test10("should get actors with pagination", async (c) => {
|
|
2157
1483
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2158
1484
|
await client.counter.create(["test-actor-1"]);
|
|
2159
1485
|
await client.counter.create(["test-actor-2"]);
|
|
@@ -2165,16 +1491,16 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2165
1491
|
const response = await http.actors.$get({
|
|
2166
1492
|
query: { limit: "1" }
|
|
2167
1493
|
});
|
|
2168
|
-
|
|
1494
|
+
expect10(response.status).toBe(200);
|
|
2169
1495
|
const data = await response.json();
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
1496
|
+
expect10(data).toEqual(
|
|
1497
|
+
expect10.arrayContaining([
|
|
1498
|
+
expect10.objectContaining({ key: ["test-actor-1"] })
|
|
2173
1499
|
])
|
|
2174
1500
|
);
|
|
2175
|
-
|
|
1501
|
+
expect10(data.length).toBe(1);
|
|
2176
1502
|
});
|
|
2177
|
-
|
|
1503
|
+
test10("should get all actors with pagination", async (c) => {
|
|
2178
1504
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2179
1505
|
const actorKey1 = ["test-cursor-1"];
|
|
2180
1506
|
const actorKey2 = ["test-cursor-2"];
|
|
@@ -2188,22 +1514,22 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2188
1514
|
const response = await http.actors.$get({
|
|
2189
1515
|
query: { limit: "5" }
|
|
2190
1516
|
});
|
|
2191
|
-
|
|
1517
|
+
expect10(response.status).toBe(200);
|
|
2192
1518
|
const data = await response.json();
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
id:
|
|
1519
|
+
expect10(data).toEqual(
|
|
1520
|
+
expect10.arrayContaining([
|
|
1521
|
+
expect10.objectContaining({
|
|
1522
|
+
id: expect10.any(String),
|
|
2197
1523
|
key: actorKey1
|
|
2198
1524
|
}),
|
|
2199
|
-
|
|
2200
|
-
id:
|
|
1525
|
+
expect10.objectContaining({
|
|
1526
|
+
id: expect10.any(String),
|
|
2201
1527
|
key: actorKey2
|
|
2202
1528
|
})
|
|
2203
1529
|
])
|
|
2204
1530
|
);
|
|
2205
1531
|
});
|
|
2206
|
-
|
|
1532
|
+
test10("should handle invalid limit parameter", async (c) => {
|
|
2207
1533
|
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2208
1534
|
const http = createManagerInspectorClient(`${endpoint}/inspect`, {
|
|
2209
1535
|
headers: {
|
|
@@ -2213,9 +1539,9 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2213
1539
|
const response = await http.actors.$get({
|
|
2214
1540
|
query: { limit: "0" }
|
|
2215
1541
|
});
|
|
2216
|
-
|
|
1542
|
+
expect10(response.status).toBe(400);
|
|
2217
1543
|
});
|
|
2218
|
-
|
|
1544
|
+
test10("should create a new actor", async (c) => {
|
|
2219
1545
|
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2220
1546
|
const http = createManagerInspectorClient(`${endpoint}/inspect`, {
|
|
2221
1547
|
headers: {
|
|
@@ -2229,17 +1555,17 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2229
1555
|
input: {}
|
|
2230
1556
|
}
|
|
2231
1557
|
});
|
|
2232
|
-
|
|
1558
|
+
expect10(response.status).toBe(201);
|
|
2233
1559
|
const data = await response.json();
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
id:
|
|
1560
|
+
expect10(data).toEqual(
|
|
1561
|
+
expect10.objectContaining({
|
|
1562
|
+
id: expect10.any(String),
|
|
2237
1563
|
name: "default",
|
|
2238
1564
|
key: ["test-create-actor"]
|
|
2239
1565
|
})
|
|
2240
1566
|
);
|
|
2241
1567
|
});
|
|
2242
|
-
|
|
1568
|
+
test10("should get builds", async (c) => {
|
|
2243
1569
|
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2244
1570
|
const http = createManagerInspectorClient(`${endpoint}/inspect`, {
|
|
2245
1571
|
headers: {
|
|
@@ -2247,15 +1573,15 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2247
1573
|
}
|
|
2248
1574
|
});
|
|
2249
1575
|
const response = await http.builds.$get();
|
|
2250
|
-
|
|
1576
|
+
expect10(response.status).toBe(200);
|
|
2251
1577
|
const data = await response.json();
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
1578
|
+
expect10(data).toEqual(
|
|
1579
|
+
expect10.arrayContaining([
|
|
1580
|
+
expect10.objectContaining({ name: expect10.any(String) })
|
|
2255
1581
|
])
|
|
2256
1582
|
);
|
|
2257
1583
|
});
|
|
2258
|
-
|
|
1584
|
+
test10("should get actor by id", async (c) => {
|
|
2259
1585
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2260
1586
|
const handle = await client.counter.create(["test-get-by-id"]);
|
|
2261
1587
|
const actorId = await handle.resolve();
|
|
@@ -2267,11 +1593,11 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2267
1593
|
const response = await http.actor[":id"].$get({
|
|
2268
1594
|
param: { id: actorId }
|
|
2269
1595
|
});
|
|
2270
|
-
|
|
1596
|
+
expect10(response.status).toBe(200);
|
|
2271
1597
|
const data = await response.json();
|
|
2272
|
-
|
|
1598
|
+
expect10(data).toHaveProperty("id", actorId);
|
|
2273
1599
|
});
|
|
2274
|
-
|
|
1600
|
+
test10("should return 404 for non-existent actor", async (c) => {
|
|
2275
1601
|
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2276
1602
|
const http = createManagerInspectorClient(`${endpoint}/inspect`, {
|
|
2277
1603
|
headers: {
|
|
@@ -2281,11 +1607,11 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2281
1607
|
const response = await http.actor[":id"].$get({
|
|
2282
1608
|
param: { id: "non-existent-id" }
|
|
2283
1609
|
});
|
|
2284
|
-
|
|
1610
|
+
expect10(response.status).toBe(404);
|
|
2285
1611
|
const data = await response.json();
|
|
2286
|
-
|
|
1612
|
+
expect10(data).toEqual({ error: "Actor not found" });
|
|
2287
1613
|
});
|
|
2288
|
-
|
|
1614
|
+
test10("should get bootstrap data", async (c) => {
|
|
2289
1615
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2290
1616
|
const handle = await client.counter.create(["test-bootstrap"]);
|
|
2291
1617
|
await handle.resolve();
|
|
@@ -2295,11 +1621,11 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2295
1621
|
}
|
|
2296
1622
|
});
|
|
2297
1623
|
const response = await http.bootstrap.$get();
|
|
2298
|
-
|
|
1624
|
+
expect10(response.status).toBe(200);
|
|
2299
1625
|
const data = await response.json();
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
1626
|
+
expect10(data.actors).toEqual(
|
|
1627
|
+
expect10.arrayContaining([
|
|
1628
|
+
expect10.objectContaining({
|
|
2303
1629
|
key: ["test-bootstrap"],
|
|
2304
1630
|
name: "counter"
|
|
2305
1631
|
})
|
|
@@ -2307,8 +1633,8 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2307
1633
|
);
|
|
2308
1634
|
});
|
|
2309
1635
|
});
|
|
2310
|
-
|
|
2311
|
-
|
|
1636
|
+
describe11("Actor Inspector", () => {
|
|
1637
|
+
test10("should handle actor not found", async (c) => {
|
|
2312
1638
|
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2313
1639
|
const actorId = "non-existing";
|
|
2314
1640
|
const http = createActorInspectorClient(`${endpoint}/actors/inspect`, {
|
|
@@ -2320,9 +1646,9 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2320
1646
|
}
|
|
2321
1647
|
});
|
|
2322
1648
|
const response = await http.ping.$get();
|
|
2323
|
-
|
|
1649
|
+
expect10(response.ok).toBe(false);
|
|
2324
1650
|
});
|
|
2325
|
-
|
|
1651
|
+
test10("should respond to ping", async (c) => {
|
|
2326
1652
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2327
1653
|
const handle = await client.counter.create(["test-ping"]);
|
|
2328
1654
|
const actorId = await handle.resolve();
|
|
@@ -2335,11 +1661,11 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2335
1661
|
}
|
|
2336
1662
|
});
|
|
2337
1663
|
const response = await http.ping.$get();
|
|
2338
|
-
|
|
1664
|
+
expect10(response.status).toBe(200);
|
|
2339
1665
|
const data = await response.json();
|
|
2340
|
-
|
|
1666
|
+
expect10(data).toEqual({ message: "pong" });
|
|
2341
1667
|
});
|
|
2342
|
-
|
|
1668
|
+
test10("should get actor state", async (c) => {
|
|
2343
1669
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2344
1670
|
const handle = await client.counter.create(["test-state"]);
|
|
2345
1671
|
const actorId = await handle.resolve();
|
|
@@ -2353,16 +1679,16 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2353
1679
|
}
|
|
2354
1680
|
});
|
|
2355
1681
|
const response = await http.state.$get();
|
|
2356
|
-
|
|
1682
|
+
expect10(response.status).toBe(200);
|
|
2357
1683
|
const data = await response.json();
|
|
2358
|
-
|
|
1684
|
+
expect10(data).toEqual({
|
|
2359
1685
|
enabled: true,
|
|
2360
|
-
state:
|
|
1686
|
+
state: expect10.objectContaining({
|
|
2361
1687
|
count: 5
|
|
2362
1688
|
})
|
|
2363
1689
|
});
|
|
2364
1690
|
});
|
|
2365
|
-
|
|
1691
|
+
test10("should update actor state with replace", async (c) => {
|
|
2366
1692
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2367
1693
|
const handle = await client.counter.create(["test-state-replace"]);
|
|
2368
1694
|
const actorId = await handle.resolve();
|
|
@@ -2379,14 +1705,14 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2379
1705
|
replace: { count: 10 }
|
|
2380
1706
|
}
|
|
2381
1707
|
});
|
|
2382
|
-
|
|
1708
|
+
expect10(response.status).toBe(200);
|
|
2383
1709
|
const data = await response.json();
|
|
2384
|
-
|
|
1710
|
+
expect10(data).toEqual({
|
|
2385
1711
|
enabled: true,
|
|
2386
1712
|
state: { count: 10 }
|
|
2387
1713
|
});
|
|
2388
1714
|
});
|
|
2389
|
-
|
|
1715
|
+
test10("should update actor state with patch", async (c) => {
|
|
2390
1716
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2391
1717
|
const handle = await client.counter.create(["test-state-patch"]);
|
|
2392
1718
|
const actorId = await handle.resolve();
|
|
@@ -2410,16 +1736,16 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2410
1736
|
]
|
|
2411
1737
|
}
|
|
2412
1738
|
});
|
|
2413
|
-
|
|
1739
|
+
expect10(response.status).toBe(200);
|
|
2414
1740
|
const data = await response.json();
|
|
2415
|
-
|
|
1741
|
+
expect10(data).toEqual({
|
|
2416
1742
|
enabled: true,
|
|
2417
|
-
state:
|
|
1743
|
+
state: expect10.objectContaining({
|
|
2418
1744
|
count: 7
|
|
2419
1745
|
})
|
|
2420
1746
|
});
|
|
2421
1747
|
});
|
|
2422
|
-
|
|
1748
|
+
test10("should get actor connections", async (c) => {
|
|
2423
1749
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2424
1750
|
const handle = await client.counter.create(["test-connections"]);
|
|
2425
1751
|
const actorId = await handle.resolve();
|
|
@@ -2434,17 +1760,17 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2434
1760
|
}
|
|
2435
1761
|
});
|
|
2436
1762
|
const response = await http.connections.$get();
|
|
2437
|
-
|
|
1763
|
+
expect10(response.status).toBe(200);
|
|
2438
1764
|
const data = await response.json();
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
id:
|
|
1765
|
+
expect10(data.connections).toEqual(
|
|
1766
|
+
expect10.arrayContaining([
|
|
1767
|
+
expect10.objectContaining({
|
|
1768
|
+
id: expect10.any(String)
|
|
2443
1769
|
})
|
|
2444
1770
|
])
|
|
2445
1771
|
);
|
|
2446
1772
|
});
|
|
2447
|
-
|
|
1773
|
+
test10("should get actor events", async (c) => {
|
|
2448
1774
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2449
1775
|
const handle = await client.counter.create(["test-events"]);
|
|
2450
1776
|
const actorId = await handle.resolve();
|
|
@@ -2459,18 +1785,18 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2459
1785
|
}
|
|
2460
1786
|
});
|
|
2461
1787
|
const response = await http.events.$get();
|
|
2462
|
-
|
|
1788
|
+
expect10(response.status).toBe(200);
|
|
2463
1789
|
const data = await response.json();
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
1790
|
+
expect10(data.events).toEqual(
|
|
1791
|
+
expect10.arrayContaining([
|
|
1792
|
+
expect10.objectContaining({
|
|
2467
1793
|
type: "broadcast",
|
|
2468
|
-
id:
|
|
1794
|
+
id: expect10.any(String)
|
|
2469
1795
|
})
|
|
2470
1796
|
])
|
|
2471
1797
|
);
|
|
2472
1798
|
});
|
|
2473
|
-
|
|
1799
|
+
test10("should clear actor events", async (c) => {
|
|
2474
1800
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2475
1801
|
const handle = await client.counter.create(["test-events-clear"]);
|
|
2476
1802
|
const actorId = await handle.resolve();
|
|
@@ -2486,21 +1812,21 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2486
1812
|
});
|
|
2487
1813
|
{
|
|
2488
1814
|
const response2 = await http.events.$get();
|
|
2489
|
-
|
|
1815
|
+
expect10(response2.status).toBe(200);
|
|
2490
1816
|
const data = await response2.json();
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
1817
|
+
expect10(data.events).toEqual(
|
|
1818
|
+
expect10.arrayContaining([
|
|
1819
|
+
expect10.objectContaining({
|
|
2494
1820
|
type: "broadcast",
|
|
2495
|
-
id:
|
|
1821
|
+
id: expect10.any(String)
|
|
2496
1822
|
})
|
|
2497
1823
|
])
|
|
2498
1824
|
);
|
|
2499
1825
|
}
|
|
2500
1826
|
const response = await http.events.clear.$post();
|
|
2501
|
-
|
|
1827
|
+
expect10(response.status).toBe(200);
|
|
2502
1828
|
});
|
|
2503
|
-
|
|
1829
|
+
test10("should get actor rpcs", async (c) => {
|
|
2504
1830
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2505
1831
|
const handle = await client.counter.create(["test-rpcs"]);
|
|
2506
1832
|
const actorId = await handle.resolve();
|
|
@@ -2513,15 +1839,15 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2513
1839
|
}
|
|
2514
1840
|
});
|
|
2515
1841
|
const response = await http.rpcs.$get();
|
|
2516
|
-
|
|
1842
|
+
expect10(response.status).toBe(200);
|
|
2517
1843
|
const data = await response.json();
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
rpcs:
|
|
1844
|
+
expect10(data).toEqual(
|
|
1845
|
+
expect10.objectContaining({
|
|
1846
|
+
rpcs: expect10.arrayContaining(["increment", "getCount"])
|
|
2521
1847
|
})
|
|
2522
1848
|
);
|
|
2523
1849
|
});
|
|
2524
|
-
|
|
1850
|
+
test10.skip("should get actor database info", async (c) => {
|
|
2525
1851
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2526
1852
|
const handle = await client.counter.create(["test-db"]);
|
|
2527
1853
|
const actorId = await handle.resolve();
|
|
@@ -2534,18 +1860,18 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2534
1860
|
}
|
|
2535
1861
|
});
|
|
2536
1862
|
const response = await http.db.$get();
|
|
2537
|
-
|
|
1863
|
+
expect10(response.status).toBe(200);
|
|
2538
1864
|
const data = await response.json();
|
|
2539
|
-
|
|
2540
|
-
|
|
1865
|
+
expect10(data).toHaveProperty("enabled");
|
|
1866
|
+
expect10(typeof data.enabled).toBe("boolean");
|
|
2541
1867
|
if (data.enabled) {
|
|
2542
|
-
|
|
2543
|
-
|
|
1868
|
+
expect10(data).toHaveProperty("db");
|
|
1869
|
+
expect10(Array.isArray(data.db)).toBe(true);
|
|
2544
1870
|
} else {
|
|
2545
|
-
|
|
1871
|
+
expect10(data.db).toBe(null);
|
|
2546
1872
|
}
|
|
2547
1873
|
});
|
|
2548
|
-
|
|
1874
|
+
test10.skip("should execute database query when database is enabled", async (c) => {
|
|
2549
1875
|
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
2550
1876
|
const handle = await client.counter.create(["test-db-query"]);
|
|
2551
1877
|
const actorId = await handle.resolve();
|
|
@@ -2566,9 +1892,9 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2566
1892
|
params: []
|
|
2567
1893
|
}
|
|
2568
1894
|
});
|
|
2569
|
-
|
|
1895
|
+
expect10(queryResponse.status).toBe(200);
|
|
2570
1896
|
const queryData = await queryResponse.json();
|
|
2571
|
-
|
|
1897
|
+
expect10(queryData).toHaveProperty("result");
|
|
2572
1898
|
} else {
|
|
2573
1899
|
const queryResponse = await http.db.$post({
|
|
2574
1900
|
json: {
|
|
@@ -2576,9 +1902,9 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2576
1902
|
params: []
|
|
2577
1903
|
}
|
|
2578
1904
|
});
|
|
2579
|
-
|
|
1905
|
+
expect10(queryResponse.status).toBe(200);
|
|
2580
1906
|
const queryData = await queryResponse.json();
|
|
2581
|
-
|
|
1907
|
+
expect10(queryData).toEqual({ enabled: false });
|
|
2582
1908
|
}
|
|
2583
1909
|
});
|
|
2584
1910
|
});
|
|
@@ -2586,25 +1912,25 @@ function runActorInspectorTests(driverTestConfig) {
|
|
|
2586
1912
|
}
|
|
2587
1913
|
|
|
2588
1914
|
// src/driver-test-suite/tests/actor-metadata.ts
|
|
2589
|
-
import { describe as
|
|
1915
|
+
import { describe as describe12, expect as expect11, test as test11 } from "vitest";
|
|
2590
1916
|
function runActorMetadataTests(driverTestConfig) {
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
1917
|
+
describe12("Actor Metadata Tests", () => {
|
|
1918
|
+
describe12("Actor Name", () => {
|
|
1919
|
+
test11("should provide access to actor name", async (c) => {
|
|
2594
1920
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2595
1921
|
const handle = client.metadataActor.getOrCreate();
|
|
2596
1922
|
const actorName = await handle.getActorName();
|
|
2597
|
-
|
|
1923
|
+
expect11(actorName).toBe("metadataActor");
|
|
2598
1924
|
});
|
|
2599
|
-
|
|
1925
|
+
test11("should preserve actor name in state during onStart", async (c) => {
|
|
2600
1926
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2601
1927
|
const handle = client.metadataActor.getOrCreate();
|
|
2602
1928
|
const storedName = await handle.getStoredActorName();
|
|
2603
|
-
|
|
1929
|
+
expect11(storedName).toBe("metadataActor");
|
|
2604
1930
|
});
|
|
2605
1931
|
});
|
|
2606
|
-
|
|
2607
|
-
|
|
1932
|
+
describe12("Actor Tags", () => {
|
|
1933
|
+
test11("should provide access to tags", async (c) => {
|
|
2608
1934
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2609
1935
|
const handle = client.metadataActor.getOrCreate();
|
|
2610
1936
|
await handle.setupTestTags({
|
|
@@ -2612,12 +1938,12 @@ function runActorMetadataTests(driverTestConfig) {
|
|
|
2612
1938
|
purpose: "metadata-test"
|
|
2613
1939
|
});
|
|
2614
1940
|
const tags = await handle.getTags();
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
1941
|
+
expect11(tags).toHaveProperty("env");
|
|
1942
|
+
expect11(tags.env).toBe("test");
|
|
1943
|
+
expect11(tags).toHaveProperty("purpose");
|
|
1944
|
+
expect11(tags.purpose).toBe("metadata-test");
|
|
2619
1945
|
});
|
|
2620
|
-
|
|
1946
|
+
test11("should allow accessing individual tags", async (c) => {
|
|
2621
1947
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2622
1948
|
const handle = client.metadataActor.getOrCreate();
|
|
2623
1949
|
await handle.setupTestTags({
|
|
@@ -2627,203 +1953,205 @@ function runActorMetadataTests(driverTestConfig) {
|
|
|
2627
1953
|
const category = await handle.getTag("category");
|
|
2628
1954
|
const version = await handle.getTag("version");
|
|
2629
1955
|
const nonexistent = await handle.getTag("nonexistent");
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
1956
|
+
expect11(category).toBe("test-actor");
|
|
1957
|
+
expect11(version).toBe("1.0");
|
|
1958
|
+
expect11(nonexistent).toBeNull();
|
|
2633
1959
|
});
|
|
2634
1960
|
});
|
|
2635
|
-
|
|
2636
|
-
|
|
1961
|
+
describe12("Metadata Structure", () => {
|
|
1962
|
+
test11("should provide complete metadata object", async (c) => {
|
|
2637
1963
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2638
1964
|
const handle = client.metadataActor.getOrCreate();
|
|
2639
1965
|
await handle.setupTestTags({ type: "metadata-test" });
|
|
2640
1966
|
await handle.setupTestRegion("us-west-1");
|
|
2641
1967
|
const metadata = await handle.getMetadata();
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
1968
|
+
expect11(metadata).toHaveProperty("name");
|
|
1969
|
+
expect11(metadata.name).toBe("metadataActor");
|
|
1970
|
+
expect11(metadata).toHaveProperty("tags");
|
|
1971
|
+
expect11(metadata.tags).toHaveProperty("type");
|
|
1972
|
+
expect11(metadata.tags.type).toBe("metadata-test");
|
|
1973
|
+
expect11(metadata).toHaveProperty("region");
|
|
1974
|
+
expect11(metadata.region).toBe("us-west-1");
|
|
2649
1975
|
});
|
|
2650
1976
|
});
|
|
2651
|
-
|
|
2652
|
-
|
|
1977
|
+
describe12("Region Information", () => {
|
|
1978
|
+
test11("should retrieve region information", async (c) => {
|
|
2653
1979
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2654
1980
|
const handle = client.metadataActor.getOrCreate();
|
|
2655
1981
|
await handle.setupTestRegion("eu-central-1");
|
|
2656
1982
|
const region = await handle.getRegion();
|
|
2657
|
-
|
|
1983
|
+
expect11(region).toBe("eu-central-1");
|
|
2658
1984
|
});
|
|
2659
1985
|
});
|
|
2660
1986
|
});
|
|
2661
1987
|
}
|
|
2662
1988
|
|
|
2663
1989
|
// src/driver-test-suite/tests/actor-onstatechange.ts
|
|
2664
|
-
import { describe as
|
|
1990
|
+
import { describe as describe13, expect as expect12, test as test12 } from "vitest";
|
|
2665
1991
|
function runActorOnStateChangeTests(driverTestConfig) {
|
|
2666
|
-
|
|
2667
|
-
|
|
1992
|
+
describe13("Actor onStateChange Tests", () => {
|
|
1993
|
+
test12("triggers onStateChange when state is modified", async (c) => {
|
|
2668
1994
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2669
1995
|
const actor2 = client.onStateChangeActor.getOrCreate();
|
|
2670
1996
|
await actor2.setValue(10);
|
|
2671
1997
|
const changeCount = await actor2.getChangeCount();
|
|
2672
|
-
|
|
1998
|
+
expect12(changeCount).toBe(1);
|
|
2673
1999
|
});
|
|
2674
|
-
|
|
2000
|
+
test12("triggers onChange multiple times for multiple state changes", async (c) => {
|
|
2675
2001
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2676
2002
|
const actor2 = client.onStateChangeActor.getOrCreate();
|
|
2677
2003
|
await actor2.incrementMultiple(3);
|
|
2678
2004
|
const changeCount = await actor2.getChangeCount();
|
|
2679
|
-
|
|
2005
|
+
expect12(changeCount).toBe(3);
|
|
2680
2006
|
});
|
|
2681
|
-
|
|
2007
|
+
test12("does NOT trigger onChange for read-only actions", async (c) => {
|
|
2682
2008
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2683
2009
|
const actor2 = client.onStateChangeActor.getOrCreate();
|
|
2684
2010
|
await actor2.setValue(5);
|
|
2685
2011
|
const value = await actor2.getValue();
|
|
2686
|
-
|
|
2012
|
+
expect12(value).toBe(5);
|
|
2687
2013
|
const changeCount = await actor2.getChangeCount();
|
|
2688
|
-
|
|
2014
|
+
expect12(changeCount).toBe(1);
|
|
2689
2015
|
});
|
|
2690
|
-
|
|
2016
|
+
test12("does NOT trigger onChange for computed values", async (c) => {
|
|
2691
2017
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2692
2018
|
const actor2 = client.onStateChangeActor.getOrCreate();
|
|
2693
2019
|
await actor2.setValue(3);
|
|
2694
2020
|
{
|
|
2695
2021
|
const changeCount = await actor2.getChangeCount();
|
|
2696
|
-
|
|
2022
|
+
expect12(changeCount).toBe(1);
|
|
2697
2023
|
}
|
|
2698
2024
|
const doubled = await actor2.getDoubled();
|
|
2699
|
-
|
|
2025
|
+
expect12(doubled).toBe(6);
|
|
2700
2026
|
{
|
|
2701
2027
|
const changeCount = await actor2.getChangeCount();
|
|
2702
|
-
|
|
2028
|
+
expect12(changeCount).toBe(1);
|
|
2703
2029
|
}
|
|
2704
2030
|
});
|
|
2705
|
-
|
|
2031
|
+
test12("simple: connect, call action, dispose does NOT trigger onChange", async (c) => {
|
|
2706
2032
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2707
2033
|
const actor2 = client.onStateChangeActor.getOrCreate();
|
|
2708
2034
|
const connection = await actor2.connect();
|
|
2709
2035
|
const value = await connection.getValue();
|
|
2710
|
-
|
|
2036
|
+
expect12(value).toBe(0);
|
|
2711
2037
|
await connection.dispose();
|
|
2712
2038
|
const changeCount = await actor2.getChangeCount();
|
|
2713
|
-
|
|
2039
|
+
expect12(changeCount).toBe(0);
|
|
2714
2040
|
});
|
|
2715
2041
|
});
|
|
2716
2042
|
}
|
|
2717
2043
|
|
|
2718
2044
|
// src/driver-test-suite/tests/actor-vars.ts
|
|
2719
|
-
import { describe as
|
|
2045
|
+
import { describe as describe14, expect as expect13, test as test13 } from "vitest";
|
|
2720
2046
|
function runActorVarsTests(driverTestConfig) {
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2047
|
+
describe14("Actor Variables", () => {
|
|
2048
|
+
describe14("Static vars", () => {
|
|
2049
|
+
test13("should provide access to static vars", async (c) => {
|
|
2724
2050
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2725
2051
|
const instance = client.staticVarActor.getOrCreate();
|
|
2726
2052
|
const result = await instance.getVars();
|
|
2727
|
-
|
|
2053
|
+
expect13(result).toEqual({ counter: 42, name: "test-actor" });
|
|
2728
2054
|
const name = await instance.getName();
|
|
2729
|
-
|
|
2055
|
+
expect13(name).toBe("test-actor");
|
|
2730
2056
|
});
|
|
2731
2057
|
});
|
|
2732
|
-
|
|
2733
|
-
|
|
2058
|
+
describe14("Deep cloning of static vars", () => {
|
|
2059
|
+
test13("should deep clone static vars between actor instances", async (c) => {
|
|
2734
2060
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2735
2061
|
const instance1 = client.nestedVarActor.getOrCreate(["instance1"]);
|
|
2736
2062
|
const instance2 = client.nestedVarActor.getOrCreate(["instance2"]);
|
|
2737
2063
|
const modifiedVars = await instance1.modifyNested();
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2064
|
+
expect13(modifiedVars.nested.value).toBe("modified");
|
|
2065
|
+
expect13(modifiedVars.nested.array).toContain(4);
|
|
2066
|
+
expect13(modifiedVars.nested.obj.key).toBe("new-value");
|
|
2741
2067
|
const instance2Vars = await instance2.getVars();
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2068
|
+
expect13(instance2Vars.nested.value).toBe("original");
|
|
2069
|
+
expect13(instance2Vars.nested.array).toEqual([1, 2, 3]);
|
|
2070
|
+
expect13(instance2Vars.nested.obj.key).toBe("value");
|
|
2745
2071
|
});
|
|
2746
2072
|
});
|
|
2747
|
-
|
|
2748
|
-
|
|
2073
|
+
describe14("createVars", () => {
|
|
2074
|
+
test13("should support dynamic vars creation", async (c) => {
|
|
2749
2075
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2750
2076
|
const instance = client.dynamicVarActor.getOrCreate();
|
|
2751
2077
|
const vars = await instance.getVars();
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2078
|
+
expect13(vars).toHaveProperty("random");
|
|
2079
|
+
expect13(vars).toHaveProperty("computed");
|
|
2080
|
+
expect13(typeof vars.random).toBe("number");
|
|
2081
|
+
expect13(typeof vars.computed).toBe("string");
|
|
2082
|
+
expect13(vars.computed).toMatch(/^Actor-\d+$/);
|
|
2757
2083
|
});
|
|
2758
|
-
|
|
2084
|
+
test13("should create different vars for different instances", async (c) => {
|
|
2759
2085
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2760
2086
|
const instance1 = client.uniqueVarActor.getOrCreate(["test1"]);
|
|
2761
2087
|
const instance2 = client.uniqueVarActor.getOrCreate(["test2"]);
|
|
2762
2088
|
const vars1 = await instance1.getVars();
|
|
2763
2089
|
const vars2 = await instance2.getVars();
|
|
2764
|
-
|
|
2090
|
+
expect13(vars1.id).not.toBe(vars2.id);
|
|
2765
2091
|
});
|
|
2766
2092
|
});
|
|
2767
|
-
|
|
2768
|
-
|
|
2093
|
+
describe14("Driver Context", () => {
|
|
2094
|
+
test13("should provide access to driver context", async (c) => {
|
|
2769
2095
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2770
2096
|
const instance = client.driverCtxActor.getOrCreate();
|
|
2771
2097
|
const vars = await instance.getVars();
|
|
2772
|
-
|
|
2098
|
+
expect13(vars).toHaveProperty("hasDriverCtx");
|
|
2773
2099
|
});
|
|
2774
2100
|
});
|
|
2775
2101
|
});
|
|
2776
2102
|
}
|
|
2777
2103
|
|
|
2778
2104
|
// src/driver-test-suite/tests/manager-driver.ts
|
|
2779
|
-
import { describe as
|
|
2105
|
+
import { describe as describe15, expect as expect14, test as test14 } from "vitest";
|
|
2780
2106
|
function runManagerDriverTests(driverTestConfig) {
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2107
|
+
describe15("Manager Driver Tests", () => {
|
|
2108
|
+
describe15("Client Connection Methods", () => {
|
|
2109
|
+
test14("connect() - finds or creates a actor", async (c) => {
|
|
2784
2110
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2785
2111
|
const counterA = client.counter.getOrCreate();
|
|
2786
2112
|
await counterA.increment(5);
|
|
2787
2113
|
const counterAAgain = client.counter.getOrCreate();
|
|
2788
2114
|
const count = await counterAAgain.increment(0);
|
|
2789
|
-
|
|
2115
|
+
expect14(count).toBe(5);
|
|
2790
2116
|
const counterB = client.counter.getOrCreate(["counter-b", "testing"]);
|
|
2791
2117
|
await counterB.increment(10);
|
|
2792
2118
|
const countB = await counterB.increment(0);
|
|
2793
|
-
|
|
2119
|
+
expect14(countB).toBe(10);
|
|
2794
2120
|
});
|
|
2795
|
-
|
|
2121
|
+
test14("throws ActorAlreadyExists when creating duplicate actors", async (c) => {
|
|
2796
2122
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2797
2123
|
const uniqueKey = ["duplicate-actor-test", crypto.randomUUID()];
|
|
2798
2124
|
const counter = client.counter.getOrCreate(uniqueKey);
|
|
2799
2125
|
await counter.increment(5);
|
|
2800
2126
|
try {
|
|
2801
2127
|
await client.counter.create(uniqueKey);
|
|
2802
|
-
|
|
2128
|
+
expect14.fail("did not error on duplicate create");
|
|
2803
2129
|
} catch (err) {
|
|
2804
|
-
|
|
2130
|
+
expect14(err.group).toBe("actor");
|
|
2131
|
+
expect14(err.code).toBe("already_exists");
|
|
2805
2132
|
}
|
|
2806
2133
|
const count = await counter.increment(0);
|
|
2807
|
-
|
|
2134
|
+
expect14(count).toBe(5);
|
|
2808
2135
|
});
|
|
2809
2136
|
});
|
|
2810
|
-
|
|
2811
|
-
|
|
2137
|
+
describe15("Connection Options", () => {
|
|
2138
|
+
test14("get without create prevents actor creation", async (c) => {
|
|
2812
2139
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2813
2140
|
const nonexistentId = `nonexistent-${crypto.randomUUID()}`;
|
|
2814
2141
|
try {
|
|
2815
2142
|
await client.counter.get([nonexistentId]).resolve();
|
|
2816
|
-
|
|
2143
|
+
expect14.fail("did not error for get");
|
|
2817
2144
|
} catch (err) {
|
|
2818
|
-
|
|
2145
|
+
expect14(err.group).toBe("actor");
|
|
2146
|
+
expect14(err.code).toBe("not_found");
|
|
2819
2147
|
}
|
|
2820
2148
|
const createdCounter = client.counter.getOrCreate(nonexistentId);
|
|
2821
2149
|
await createdCounter.increment(3);
|
|
2822
2150
|
const retrievedCounter = client.counter.get(nonexistentId);
|
|
2823
2151
|
const count = await retrievedCounter.increment(0);
|
|
2824
|
-
|
|
2152
|
+
expect14(count).toBe(3);
|
|
2825
2153
|
});
|
|
2826
|
-
|
|
2154
|
+
test14("connection params are passed to actors", async (c) => {
|
|
2827
2155
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2828
2156
|
const counter = client.counter.getOrCreate(void 0, {
|
|
2829
2157
|
params: {
|
|
@@ -2834,20 +2162,20 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2834
2162
|
});
|
|
2835
2163
|
await counter.increment(1);
|
|
2836
2164
|
const count = await counter.increment(0);
|
|
2837
|
-
|
|
2165
|
+
expect14(count).toBe(1);
|
|
2838
2166
|
});
|
|
2839
2167
|
});
|
|
2840
|
-
|
|
2841
|
-
|
|
2168
|
+
describe15("Actor Creation & Retrieval", () => {
|
|
2169
|
+
test14("creates and retrieves actors by ID", async (c) => {
|
|
2842
2170
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2843
2171
|
const uniqueId = `test-counter-${crypto.randomUUID()}`;
|
|
2844
2172
|
const counter = client.counter.getOrCreate([uniqueId]);
|
|
2845
2173
|
await counter.increment(10);
|
|
2846
2174
|
const retrievedCounter = client.counter.getOrCreate([uniqueId]);
|
|
2847
2175
|
const count = await retrievedCounter.increment(0);
|
|
2848
|
-
|
|
2176
|
+
expect14(count).toBe(10);
|
|
2849
2177
|
});
|
|
2850
|
-
|
|
2178
|
+
test14("passes input to actor during creation", async (c) => {
|
|
2851
2179
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2852
2180
|
const testInput = {
|
|
2853
2181
|
name: "test-actor",
|
|
@@ -2858,17 +2186,17 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2858
2186
|
input: testInput
|
|
2859
2187
|
});
|
|
2860
2188
|
const inputs = await actor2.getInputs();
|
|
2861
|
-
|
|
2862
|
-
|
|
2189
|
+
expect14(inputs.initialInput).toEqual(testInput);
|
|
2190
|
+
expect14(inputs.onCreateInput).toEqual(testInput);
|
|
2863
2191
|
});
|
|
2864
|
-
|
|
2192
|
+
test14("input is undefined when not provided", async (c) => {
|
|
2865
2193
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2866
2194
|
const actor2 = await client.inputActor.create();
|
|
2867
2195
|
const inputs = await actor2.getInputs();
|
|
2868
|
-
|
|
2869
|
-
|
|
2196
|
+
expect14(inputs.initialInput).toBeUndefined();
|
|
2197
|
+
expect14(inputs.onCreateInput).toBeUndefined();
|
|
2870
2198
|
});
|
|
2871
|
-
|
|
2199
|
+
test14("getOrCreate passes input to actor during creation", async (c) => {
|
|
2872
2200
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2873
2201
|
const uniqueKey = [`input-test-${crypto.randomUUID()}`];
|
|
2874
2202
|
const testInput = {
|
|
@@ -2880,16 +2208,16 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2880
2208
|
createWithInput: testInput
|
|
2881
2209
|
});
|
|
2882
2210
|
const inputs = await actor2.getInputs();
|
|
2883
|
-
|
|
2884
|
-
|
|
2211
|
+
expect14(inputs.initialInput).toEqual(testInput);
|
|
2212
|
+
expect14(inputs.onCreateInput).toEqual(testInput);
|
|
2885
2213
|
const existingActor = client.inputActor.getOrCreate(uniqueKey);
|
|
2886
2214
|
const existingInputs = await existingActor.getInputs();
|
|
2887
|
-
|
|
2888
|
-
|
|
2215
|
+
expect14(existingInputs.initialInput).toEqual(testInput);
|
|
2216
|
+
expect14(existingInputs.onCreateInput).toEqual(testInput);
|
|
2889
2217
|
});
|
|
2890
2218
|
});
|
|
2891
|
-
|
|
2892
|
-
|
|
2219
|
+
describe15("Key Matching", () => {
|
|
2220
|
+
test14("matches actors only with exactly the same keys", async (c) => {
|
|
2893
2221
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2894
2222
|
const originalCounter = client.counter.getOrCreate([
|
|
2895
2223
|
"counter-match",
|
|
@@ -2903,37 +2231,37 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2903
2231
|
"us-east"
|
|
2904
2232
|
]);
|
|
2905
2233
|
const exactMatchCount = await exactMatchCounter.increment(0);
|
|
2906
|
-
|
|
2234
|
+
expect14(exactMatchCount).toBe(10);
|
|
2907
2235
|
const subsetMatchCounter = client.counter.getOrCreate([
|
|
2908
2236
|
"counter-match",
|
|
2909
2237
|
"test"
|
|
2910
2238
|
]);
|
|
2911
2239
|
const subsetMatchCount = await subsetMatchCounter.increment(0);
|
|
2912
|
-
|
|
2240
|
+
expect14(subsetMatchCount).toBe(0);
|
|
2913
2241
|
const singleKeyCounter = client.counter.getOrCreate(["counter-match"]);
|
|
2914
2242
|
const singleKeyCount = await singleKeyCounter.increment(0);
|
|
2915
|
-
|
|
2243
|
+
expect14(singleKeyCount).toBe(0);
|
|
2916
2244
|
});
|
|
2917
|
-
|
|
2245
|
+
test14("string key matches array with single string key", async (c) => {
|
|
2918
2246
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2919
2247
|
const stringKeyCounter = client.counter.getOrCreate("string-key-test");
|
|
2920
2248
|
await stringKeyCounter.increment(7);
|
|
2921
2249
|
const arrayKeyCounter = client.counter.getOrCreate(["string-key-test"]);
|
|
2922
2250
|
const count = await arrayKeyCounter.increment(0);
|
|
2923
|
-
|
|
2251
|
+
expect14(count).toBe(7);
|
|
2924
2252
|
});
|
|
2925
|
-
|
|
2253
|
+
test14("undefined key matches empty array key and no key", async (c) => {
|
|
2926
2254
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2927
2255
|
const undefinedKeyCounter = client.counter.getOrCreate(void 0);
|
|
2928
2256
|
await undefinedKeyCounter.increment(12);
|
|
2929
2257
|
const emptyArrayKeyCounter = client.counter.getOrCreate([]);
|
|
2930
2258
|
const emptyArrayCount = await emptyArrayKeyCounter.increment(0);
|
|
2931
|
-
|
|
2259
|
+
expect14(emptyArrayCount).toBe(12);
|
|
2932
2260
|
const noKeyCounter = client.counter.getOrCreate();
|
|
2933
2261
|
const noKeyCount = await noKeyCounter.increment(0);
|
|
2934
|
-
|
|
2262
|
+
expect14(noKeyCount).toBe(12);
|
|
2935
2263
|
});
|
|
2936
|
-
|
|
2264
|
+
test14("no keys does not match actors with keys", async (c) => {
|
|
2937
2265
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2938
2266
|
const keyedCounter = client.counter.getOrCreate([
|
|
2939
2267
|
"counter-with-keys",
|
|
@@ -2942,9 +2270,9 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2942
2270
|
await keyedCounter.increment(15);
|
|
2943
2271
|
const noKeysCounter = client.counter.getOrCreate();
|
|
2944
2272
|
const count = await noKeysCounter.increment(10);
|
|
2945
|
-
|
|
2273
|
+
expect14(count).toBe(10);
|
|
2946
2274
|
});
|
|
2947
|
-
|
|
2275
|
+
test14("actors with keys match actors with no keys", async (c) => {
|
|
2948
2276
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2949
2277
|
const noKeysCounter = client.counter.getOrCreate();
|
|
2950
2278
|
await noKeysCounter.increment(25);
|
|
@@ -2953,11 +2281,11 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2953
2281
|
"prod"
|
|
2954
2282
|
]);
|
|
2955
2283
|
const keyedCount = await keyedCounter.increment(0);
|
|
2956
|
-
|
|
2284
|
+
expect14(keyedCount).toBe(0);
|
|
2957
2285
|
});
|
|
2958
2286
|
});
|
|
2959
|
-
|
|
2960
|
-
|
|
2287
|
+
describe15("Multiple Actor Instances", () => {
|
|
2288
|
+
test14("creates multiple actor instances of the same type", async (c) => {
|
|
2961
2289
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2962
2290
|
const instance1 = client.counter.getOrCreate(["multi-1"]);
|
|
2963
2291
|
const instance2 = client.counter.getOrCreate(["multi-2"]);
|
|
@@ -2968,35 +2296,35 @@ function runManagerDriverTests(driverTestConfig) {
|
|
|
2968
2296
|
const retrieved1 = client.counter.getOrCreate(["multi-1"]);
|
|
2969
2297
|
const retrieved2 = client.counter.getOrCreate(["multi-2"]);
|
|
2970
2298
|
const retrieved3 = client.counter.getOrCreate(["multi-3"]);
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2299
|
+
expect14(await retrieved1.increment(0)).toBe(1);
|
|
2300
|
+
expect14(await retrieved2.increment(0)).toBe(2);
|
|
2301
|
+
expect14(await retrieved3.increment(0)).toBe(3);
|
|
2974
2302
|
});
|
|
2975
|
-
|
|
2303
|
+
test14("handles default instance with no explicit ID", async (c) => {
|
|
2976
2304
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2977
2305
|
const defaultCounter = client.counter.getOrCreate();
|
|
2978
2306
|
await defaultCounter.increment(5);
|
|
2979
2307
|
const sameDefaultCounter = client.counter.getOrCreate();
|
|
2980
2308
|
const count = await sameDefaultCounter.increment(0);
|
|
2981
|
-
|
|
2309
|
+
expect14(count).toBe(5);
|
|
2982
2310
|
});
|
|
2983
2311
|
});
|
|
2984
2312
|
});
|
|
2985
2313
|
}
|
|
2986
2314
|
|
|
2987
2315
|
// src/driver-test-suite/tests/raw-http.ts
|
|
2988
|
-
import { describe as
|
|
2316
|
+
import { describe as describe16, expect as expect15, test as test15 } from "vitest";
|
|
2989
2317
|
function runRawHttpTests(driverTestConfig) {
|
|
2990
|
-
|
|
2991
|
-
|
|
2318
|
+
describe16("raw http", () => {
|
|
2319
|
+
test15("should handle raw HTTP GET requests", async (c) => {
|
|
2992
2320
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
2993
2321
|
const actor2 = client.rawHttpActor.getOrCreate(["test"]);
|
|
2994
2322
|
const helloResponse = await actor2.fetch("api/hello");
|
|
2995
|
-
|
|
2323
|
+
expect15(helloResponse.ok).toBe(true);
|
|
2996
2324
|
const helloData = await helloResponse.json();
|
|
2997
|
-
|
|
2325
|
+
expect15(helloData).toEqual({ message: "Hello from actor!" });
|
|
2998
2326
|
});
|
|
2999
|
-
|
|
2327
|
+
test15("should handle raw HTTP POST requests with echo", async (c) => {
|
|
3000
2328
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3001
2329
|
const actor2 = client.rawHttpActor.getOrCreate(["test"]);
|
|
3002
2330
|
const testData = { test: "data", number: 123 };
|
|
@@ -3007,22 +2335,22 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3007
2335
|
},
|
|
3008
2336
|
body: JSON.stringify(testData)
|
|
3009
2337
|
});
|
|
3010
|
-
|
|
2338
|
+
expect15(echoResponse.ok).toBe(true);
|
|
3011
2339
|
const echoData = await echoResponse.json();
|
|
3012
|
-
|
|
2340
|
+
expect15(echoData).toEqual(testData);
|
|
3013
2341
|
});
|
|
3014
|
-
|
|
2342
|
+
test15("should track state across raw HTTP requests", async (c) => {
|
|
3015
2343
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3016
2344
|
const actor2 = client.rawHttpActor.getOrCreate(["state-test"]);
|
|
3017
2345
|
await actor2.fetch("api/hello");
|
|
3018
2346
|
await actor2.fetch("api/hello");
|
|
3019
2347
|
await actor2.fetch("api/state");
|
|
3020
2348
|
const stateResponse = await actor2.fetch("api/state");
|
|
3021
|
-
|
|
2349
|
+
expect15(stateResponse.ok).toBe(true);
|
|
3022
2350
|
const stateData = await stateResponse.json();
|
|
3023
|
-
|
|
2351
|
+
expect15(stateData.requestCount).toBe(4);
|
|
3024
2352
|
});
|
|
3025
|
-
|
|
2353
|
+
test15("should pass headers correctly", async (c) => {
|
|
3026
2354
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3027
2355
|
const actor2 = client.rawHttpActor.getOrCreate(["headers-test"]);
|
|
3028
2356
|
const customHeaders = {
|
|
@@ -3032,40 +2360,40 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3032
2360
|
const response = await actor2.fetch("api/headers", {
|
|
3033
2361
|
headers: customHeaders
|
|
3034
2362
|
});
|
|
3035
|
-
|
|
2363
|
+
expect15(response.ok).toBe(true);
|
|
3036
2364
|
const headers = await response.json();
|
|
3037
|
-
|
|
3038
|
-
|
|
2365
|
+
expect15(headers["x-custom-header"]).toBe("test-value");
|
|
2366
|
+
expect15(headers["x-another-header"]).toBe("another-value");
|
|
3039
2367
|
});
|
|
3040
|
-
|
|
2368
|
+
test15("should return 404 for unhandled paths", async (c) => {
|
|
3041
2369
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3042
2370
|
const actor2 = client.rawHttpActor.getOrCreate(["404-test"]);
|
|
3043
2371
|
const response = await actor2.fetch("api/nonexistent");
|
|
3044
|
-
|
|
3045
|
-
|
|
2372
|
+
expect15(response.ok).toBe(false);
|
|
2373
|
+
expect15(response.status).toBe(404);
|
|
3046
2374
|
});
|
|
3047
|
-
|
|
2375
|
+
test15("should return 404 when no onFetch handler defined", async (c) => {
|
|
3048
2376
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3049
2377
|
const actor2 = client.rawHttpNoHandlerActor.getOrCreate(["no-handler"]);
|
|
3050
2378
|
const response = await actor2.fetch("api/anything");
|
|
3051
|
-
|
|
3052
|
-
|
|
2379
|
+
expect15(response.ok).toBe(false);
|
|
2380
|
+
expect15(response.status).toBe(404);
|
|
3053
2381
|
});
|
|
3054
|
-
|
|
2382
|
+
test15("should return 500 error when onFetch returns void", async (c) => {
|
|
3055
2383
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3056
2384
|
const actor2 = client.rawHttpVoidReturnActor.getOrCreate(["void-return"]);
|
|
3057
2385
|
const response = await actor2.fetch("api/anything");
|
|
3058
|
-
|
|
3059
|
-
|
|
2386
|
+
expect15(response.ok).toBe(false);
|
|
2387
|
+
expect15(response.status).toBe(500);
|
|
3060
2388
|
try {
|
|
3061
2389
|
const errorData = await response.json();
|
|
3062
|
-
|
|
2390
|
+
expect15(errorData.message).toContain(
|
|
3063
2391
|
"onFetch handler must return a Response"
|
|
3064
2392
|
);
|
|
3065
2393
|
} catch {
|
|
3066
2394
|
}
|
|
3067
2395
|
});
|
|
3068
|
-
|
|
2396
|
+
test15("should handle different HTTP methods", async (c) => {
|
|
3069
2397
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3070
2398
|
const actor2 = client.rawHttpActor.getOrCreate(["methods-test"]);
|
|
3071
2399
|
const methods = ["GET", "POST", "PUT", "DELETE", "PATCH"];
|
|
@@ -3075,17 +2403,17 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3075
2403
|
body: ["POST", "PUT", "PATCH"].includes(method) ? JSON.stringify({ method }) : void 0
|
|
3076
2404
|
});
|
|
3077
2405
|
if (method === "POST") {
|
|
3078
|
-
|
|
2406
|
+
expect15(response.ok).toBe(true);
|
|
3079
2407
|
const data = await response.json();
|
|
3080
|
-
|
|
2408
|
+
expect15(data).toEqual({ method });
|
|
3081
2409
|
} else if (method === "GET") {
|
|
3082
|
-
|
|
2410
|
+
expect15(response.status).toBe(404);
|
|
3083
2411
|
} else {
|
|
3084
|
-
|
|
2412
|
+
expect15(response.status).toBe(404);
|
|
3085
2413
|
}
|
|
3086
2414
|
}
|
|
3087
2415
|
});
|
|
3088
|
-
|
|
2416
|
+
test15("should handle binary data", async (c) => {
|
|
3089
2417
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3090
2418
|
const actor2 = client.rawHttpActor.getOrCreate(["binary-test"]);
|
|
3091
2419
|
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
@@ -3096,82 +2424,82 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3096
2424
|
},
|
|
3097
2425
|
body: binaryData
|
|
3098
2426
|
});
|
|
3099
|
-
|
|
2427
|
+
expect15(response.ok).toBe(true);
|
|
3100
2428
|
const responseBuffer = await response.arrayBuffer();
|
|
3101
2429
|
const responseArray = new Uint8Array(responseBuffer);
|
|
3102
|
-
|
|
2430
|
+
expect15(Array.from(responseArray)).toEqual([1, 2, 3, 4, 5]);
|
|
3103
2431
|
});
|
|
3104
|
-
|
|
2432
|
+
test15("should work with Hono router using createVars", async (c) => {
|
|
3105
2433
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3106
2434
|
const actor2 = client.rawHttpHonoActor.getOrCreate(["hono-test"]);
|
|
3107
2435
|
const rootResponse = await actor2.fetch("/");
|
|
3108
|
-
|
|
2436
|
+
expect15(rootResponse.ok).toBe(true);
|
|
3109
2437
|
const rootData = await rootResponse.json();
|
|
3110
|
-
|
|
2438
|
+
expect15(rootData).toEqual({ message: "Welcome to Hono actor!" });
|
|
3111
2439
|
const usersResponse = await actor2.fetch("/users");
|
|
3112
|
-
|
|
2440
|
+
expect15(usersResponse.ok).toBe(true);
|
|
3113
2441
|
const users = await usersResponse.json();
|
|
3114
|
-
|
|
2442
|
+
expect15(users).toEqual([
|
|
3115
2443
|
{ id: 1, name: "Alice" },
|
|
3116
2444
|
{ id: 2, name: "Bob" }
|
|
3117
2445
|
]);
|
|
3118
2446
|
const userResponse = await actor2.fetch("/users/1");
|
|
3119
|
-
|
|
2447
|
+
expect15(userResponse.ok).toBe(true);
|
|
3120
2448
|
const user = await userResponse.json();
|
|
3121
|
-
|
|
2449
|
+
expect15(user).toEqual({ id: 1, name: "Alice" });
|
|
3122
2450
|
const newUser = { name: "Charlie" };
|
|
3123
2451
|
const createResponse = await actor2.fetch("/users", {
|
|
3124
2452
|
method: "POST",
|
|
3125
2453
|
headers: { "Content-Type": "application/json" },
|
|
3126
2454
|
body: JSON.stringify(newUser)
|
|
3127
2455
|
});
|
|
3128
|
-
|
|
3129
|
-
|
|
2456
|
+
expect15(createResponse.ok).toBe(true);
|
|
2457
|
+
expect15(createResponse.status).toBe(201);
|
|
3130
2458
|
const createdUser = await createResponse.json();
|
|
3131
|
-
|
|
2459
|
+
expect15(createdUser).toEqual({ id: 3, name: "Charlie" });
|
|
3132
2460
|
const updateData = { name: "Alice Updated" };
|
|
3133
2461
|
const updateResponse = await actor2.fetch("/users/1", {
|
|
3134
2462
|
method: "PUT",
|
|
3135
2463
|
headers: { "Content-Type": "application/json" },
|
|
3136
2464
|
body: JSON.stringify(updateData)
|
|
3137
2465
|
});
|
|
3138
|
-
|
|
2466
|
+
expect15(updateResponse.ok).toBe(true);
|
|
3139
2467
|
const updatedUser = await updateResponse.json();
|
|
3140
|
-
|
|
2468
|
+
expect15(updatedUser).toEqual({ id: 1, name: "Alice Updated" });
|
|
3141
2469
|
const deleteResponse = await actor2.fetch("/users/2", {
|
|
3142
2470
|
method: "DELETE"
|
|
3143
2471
|
});
|
|
3144
|
-
|
|
2472
|
+
expect15(deleteResponse.ok).toBe(true);
|
|
3145
2473
|
const deleteResult = await deleteResponse.json();
|
|
3146
|
-
|
|
2474
|
+
expect15(deleteResult).toEqual({ message: "User 2 deleted" });
|
|
3147
2475
|
const notFoundResponse = await actor2.fetch("/api/unknown");
|
|
3148
|
-
|
|
3149
|
-
|
|
2476
|
+
expect15(notFoundResponse.ok).toBe(false);
|
|
2477
|
+
expect15(notFoundResponse.status).toBe(404);
|
|
3150
2478
|
});
|
|
3151
|
-
|
|
2479
|
+
test15("should handle paths with and without leading slashes", async (c) => {
|
|
3152
2480
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3153
2481
|
const actor2 = client.rawHttpActor.getOrCreate(["path-test"]);
|
|
3154
2482
|
const responseWithoutSlash = await actor2.fetch("api/hello");
|
|
3155
|
-
|
|
2483
|
+
expect15(responseWithoutSlash.ok).toBe(true);
|
|
3156
2484
|
const dataWithoutSlash = await responseWithoutSlash.json();
|
|
3157
|
-
|
|
2485
|
+
expect15(dataWithoutSlash).toEqual({ message: "Hello from actor!" });
|
|
3158
2486
|
const responseWithSlash = await actor2.fetch("/api/hello");
|
|
3159
|
-
|
|
2487
|
+
expect15(responseWithSlash.ok).toBe(true);
|
|
3160
2488
|
const dataWithSlash = await responseWithSlash.json();
|
|
3161
|
-
|
|
2489
|
+
expect15(dataWithSlash).toEqual({ message: "Hello from actor!" });
|
|
3162
2490
|
});
|
|
3163
|
-
|
|
2491
|
+
test15("should not create double slashes in request URLs", async (c) => {
|
|
3164
2492
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3165
2493
|
const actor2 = client.rawHttpHonoActor.getOrCreate(["url-test"]);
|
|
3166
2494
|
const response = await actor2.fetch("/users");
|
|
3167
|
-
|
|
2495
|
+
expect15(response.ok).toBe(true);
|
|
3168
2496
|
const data = await response.json();
|
|
3169
|
-
|
|
2497
|
+
expect15(data).toEqual([
|
|
3170
2498
|
{ id: 1, name: "Alice" },
|
|
3171
2499
|
{ id: 2, name: "Bob" }
|
|
3172
2500
|
]);
|
|
3173
2501
|
});
|
|
3174
|
-
|
|
2502
|
+
test15("should handle forwarded requests correctly without double slashes", async (c) => {
|
|
3175
2503
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3176
2504
|
const actor2 = client.rawHttpHonoActor.getOrCreate(["forward-test"]);
|
|
3177
2505
|
const truncatedPath = "/users";
|
|
@@ -3180,14 +2508,14 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3180
2508
|
method: "GET"
|
|
3181
2509
|
});
|
|
3182
2510
|
const response = await actor2.fetch(truncatedPath, newRequest);
|
|
3183
|
-
|
|
2511
|
+
expect15(response.ok).toBe(true);
|
|
3184
2512
|
const users = await response.json();
|
|
3185
|
-
|
|
2513
|
+
expect15(users).toEqual([
|
|
3186
2514
|
{ id: 1, name: "Alice" },
|
|
3187
2515
|
{ id: 2, name: "Bob" }
|
|
3188
2516
|
]);
|
|
3189
2517
|
});
|
|
3190
|
-
|
|
2518
|
+
test15("example fix: should properly forward requests using just Request object", async (c) => {
|
|
3191
2519
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3192
2520
|
const actor2 = client.rawHttpHonoActor.getOrCreate(["forward-fix"]);
|
|
3193
2521
|
const truncatedPath = "/users/1";
|
|
@@ -3196,11 +2524,11 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3196
2524
|
method: "GET"
|
|
3197
2525
|
});
|
|
3198
2526
|
const response = await actor2.fetch(newRequest);
|
|
3199
|
-
|
|
2527
|
+
expect15(response.ok).toBe(true);
|
|
3200
2528
|
const user = await response.json();
|
|
3201
|
-
|
|
2529
|
+
expect15(user).toEqual({ id: 1, name: "Alice" });
|
|
3202
2530
|
});
|
|
3203
|
-
|
|
2531
|
+
test15("should support standard fetch API with URL and Request objects", async (c) => {
|
|
3204
2532
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3205
2533
|
const actor2 = client.rawHttpActor.getOrCreate(["fetch-api-test"]);
|
|
3206
2534
|
const url = new URL("/api/echo", "http://example.com");
|
|
@@ -3209,18 +2537,18 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3209
2537
|
headers: { "Content-Type": "application/json" },
|
|
3210
2538
|
body: JSON.stringify({ from: "URL object" })
|
|
3211
2539
|
});
|
|
3212
|
-
|
|
2540
|
+
expect15(urlResponse.ok).toBe(true);
|
|
3213
2541
|
const urlData = await urlResponse.json();
|
|
3214
|
-
|
|
2542
|
+
expect15(urlData).toEqual({ from: "URL object" });
|
|
3215
2543
|
const request = new Request("http://example.com/api/echo", {
|
|
3216
2544
|
method: "POST",
|
|
3217
2545
|
headers: { "Content-Type": "application/json" },
|
|
3218
2546
|
body: JSON.stringify({ from: "Request object" })
|
|
3219
2547
|
});
|
|
3220
2548
|
const requestResponse = await actor2.fetch(request);
|
|
3221
|
-
|
|
2549
|
+
expect15(requestResponse.ok).toBe(true);
|
|
3222
2550
|
const requestData = await requestResponse.json();
|
|
3223
|
-
|
|
2551
|
+
expect15(requestData).toEqual({ from: "Request object" });
|
|
3224
2552
|
const request2 = new Request("http://example.com/api/headers", {
|
|
3225
2553
|
method: "GET",
|
|
3226
2554
|
headers: { "X-Original": "request-header" }
|
|
@@ -3228,198 +2556,19 @@ function runRawHttpTests(driverTestConfig) {
|
|
|
3228
2556
|
const overrideResponse = await actor2.fetch(request2, {
|
|
3229
2557
|
headers: { "X-Override": "init-header" }
|
|
3230
2558
|
});
|
|
3231
|
-
|
|
2559
|
+
expect15(overrideResponse.ok).toBe(true);
|
|
3232
2560
|
const headers = await overrideResponse.json();
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
});
|
|
3236
|
-
});
|
|
3237
|
-
}
|
|
3238
|
-
|
|
3239
|
-
// src/driver-test-suite/tests/raw-http-direct-registry.ts
|
|
3240
|
-
import { describe as describe18, expect as expect17, test as test17 } from "vitest";
|
|
3241
|
-
function runRawHttpDirectRegistryTests(driverTestConfig) {
|
|
3242
|
-
describe18("raw http - direct registry access", () => {
|
|
3243
|
-
test17("should handle direct fetch requests to registry with proper headers", async (c) => {
|
|
3244
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3245
|
-
const actorQuery = {
|
|
3246
|
-
getOrCreateForKey: {
|
|
3247
|
-
name: "rawHttpActor",
|
|
3248
|
-
key: ["direct-test"]
|
|
3249
|
-
}
|
|
3250
|
-
};
|
|
3251
|
-
const response = await fetch(
|
|
3252
|
-
`${endpoint}/registry/actors/raw/http/api/hello`,
|
|
3253
|
-
{
|
|
3254
|
-
method: "GET",
|
|
3255
|
-
headers: {
|
|
3256
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery)
|
|
3257
|
-
}
|
|
3258
|
-
}
|
|
3259
|
-
);
|
|
3260
|
-
expect17(response.ok).toBe(true);
|
|
3261
|
-
expect17(response.status).toBe(200);
|
|
3262
|
-
const data = await response.json();
|
|
3263
|
-
expect17(data).toEqual({ message: "Hello from actor!" });
|
|
3264
|
-
});
|
|
3265
|
-
test17("should handle POST requests with body to registry", async (c) => {
|
|
3266
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3267
|
-
const actorQuery = {
|
|
3268
|
-
getOrCreateForKey: {
|
|
3269
|
-
name: "rawHttpActor",
|
|
3270
|
-
key: ["direct-post-test"]
|
|
3271
|
-
}
|
|
3272
|
-
};
|
|
3273
|
-
const testData = { test: "direct", number: 456 };
|
|
3274
|
-
const response = await fetch(
|
|
3275
|
-
`${endpoint}/registry/actors/raw/http/api/echo`,
|
|
3276
|
-
{
|
|
3277
|
-
method: "POST",
|
|
3278
|
-
headers: {
|
|
3279
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
3280
|
-
"Content-Type": "application/json"
|
|
3281
|
-
},
|
|
3282
|
-
body: JSON.stringify(testData)
|
|
3283
|
-
}
|
|
3284
|
-
);
|
|
3285
|
-
expect17(response.ok).toBe(true);
|
|
3286
|
-
expect17(response.status).toBe(200);
|
|
3287
|
-
const data = await response.json();
|
|
3288
|
-
expect17(data).toEqual(testData);
|
|
3289
|
-
});
|
|
3290
|
-
test17("should pass custom headers through to actor", async (c) => {
|
|
3291
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3292
|
-
const actorQuery = {
|
|
3293
|
-
getOrCreateForKey: {
|
|
3294
|
-
name: "rawHttpActor",
|
|
3295
|
-
key: ["direct-headers-test"]
|
|
3296
|
-
}
|
|
3297
|
-
};
|
|
3298
|
-
const customHeaders = {
|
|
3299
|
-
"X-Custom-Header": "direct-test-value",
|
|
3300
|
-
"X-Another-Header": "another-direct-value"
|
|
3301
|
-
};
|
|
3302
|
-
const response = await fetch(
|
|
3303
|
-
`${endpoint}/registry/actors/raw/http/api/headers`,
|
|
3304
|
-
{
|
|
3305
|
-
method: "GET",
|
|
3306
|
-
headers: {
|
|
3307
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
3308
|
-
...customHeaders
|
|
3309
|
-
}
|
|
3310
|
-
}
|
|
3311
|
-
);
|
|
3312
|
-
expect17(response.ok).toBe(true);
|
|
3313
|
-
const headers = await response.json();
|
|
3314
|
-
expect17(headers["x-custom-header"]).toBe("direct-test-value");
|
|
3315
|
-
expect17(headers["x-another-header"]).toBe("another-direct-value");
|
|
3316
|
-
});
|
|
3317
|
-
test17("should handle connection parameters for authentication", async (c) => {
|
|
3318
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3319
|
-
const actorQuery = {
|
|
3320
|
-
getOrCreateForKey: {
|
|
3321
|
-
name: "rawHttpActor",
|
|
3322
|
-
key: ["direct-auth-test"]
|
|
3323
|
-
}
|
|
3324
|
-
};
|
|
3325
|
-
const connParams = { token: "test-auth-token", userId: "user123" };
|
|
3326
|
-
const response = await fetch(
|
|
3327
|
-
`${endpoint}/registry/actors/raw/http/api/hello`,
|
|
3328
|
-
{
|
|
3329
|
-
method: "GET",
|
|
3330
|
-
headers: {
|
|
3331
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
3332
|
-
[HEADER_CONN_PARAMS]: JSON.stringify(connParams)
|
|
3333
|
-
}
|
|
3334
|
-
}
|
|
3335
|
-
);
|
|
3336
|
-
expect17(response.ok).toBe(true);
|
|
3337
|
-
const data = await response.json();
|
|
3338
|
-
expect17(data).toEqual({ message: "Hello from actor!" });
|
|
3339
|
-
});
|
|
3340
|
-
test17("should return 404 for actors without onFetch handler", async (c) => {
|
|
3341
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3342
|
-
const actorQuery = {
|
|
3343
|
-
getOrCreateForKey: {
|
|
3344
|
-
name: "rawHttpNoHandlerActor",
|
|
3345
|
-
key: ["direct-no-handler"]
|
|
3346
|
-
}
|
|
3347
|
-
};
|
|
3348
|
-
const response = await fetch(
|
|
3349
|
-
`${endpoint}/registry/actors/raw/http/api/anything`,
|
|
3350
|
-
{
|
|
3351
|
-
method: "GET",
|
|
3352
|
-
headers: {
|
|
3353
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery)
|
|
3354
|
-
}
|
|
3355
|
-
}
|
|
3356
|
-
);
|
|
3357
|
-
expect17(response.ok).toBe(false);
|
|
3358
|
-
expect17(response.status).toBe(404);
|
|
3359
|
-
});
|
|
3360
|
-
test17("should handle different HTTP methods", async (c) => {
|
|
3361
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3362
|
-
const actorQuery = {
|
|
3363
|
-
getOrCreateForKey: {
|
|
3364
|
-
name: "rawHttpActor",
|
|
3365
|
-
key: ["direct-methods-test"]
|
|
3366
|
-
}
|
|
3367
|
-
};
|
|
3368
|
-
const methods = ["GET", "POST", "PUT", "DELETE", "PATCH"];
|
|
3369
|
-
for (const method of methods) {
|
|
3370
|
-
const response = await fetch(
|
|
3371
|
-
`${endpoint}/registry/actors/raw/http/api/echo`,
|
|
3372
|
-
{
|
|
3373
|
-
method,
|
|
3374
|
-
headers: {
|
|
3375
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
3376
|
-
...method !== "GET" ? { "Content-Type": "application/json" } : {}
|
|
3377
|
-
},
|
|
3378
|
-
body: ["POST", "PUT", "PATCH"].includes(method) ? JSON.stringify({ method }) : void 0
|
|
3379
|
-
}
|
|
3380
|
-
);
|
|
3381
|
-
if (method === "POST") {
|
|
3382
|
-
expect17(response.ok).toBe(true);
|
|
3383
|
-
const data = await response.json();
|
|
3384
|
-
expect17(data).toEqual({ method });
|
|
3385
|
-
} else {
|
|
3386
|
-
expect17(response.status).toBe(404);
|
|
3387
|
-
}
|
|
3388
|
-
}
|
|
3389
|
-
});
|
|
3390
|
-
test17("should handle binary data", async (c) => {
|
|
3391
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
3392
|
-
const actorQuery = {
|
|
3393
|
-
getOrCreateForKey: {
|
|
3394
|
-
name: "rawHttpActor",
|
|
3395
|
-
key: ["direct-binary-test"]
|
|
3396
|
-
}
|
|
3397
|
-
};
|
|
3398
|
-
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
3399
|
-
const response = await fetch(
|
|
3400
|
-
`${endpoint}/registry/actors/raw/http/api/echo`,
|
|
3401
|
-
{
|
|
3402
|
-
method: "POST",
|
|
3403
|
-
headers: {
|
|
3404
|
-
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
3405
|
-
"Content-Type": "application/octet-stream"
|
|
3406
|
-
},
|
|
3407
|
-
body: binaryData
|
|
3408
|
-
}
|
|
3409
|
-
);
|
|
3410
|
-
expect17(response.ok).toBe(true);
|
|
3411
|
-
const responseBuffer = await response.arrayBuffer();
|
|
3412
|
-
const responseArray = new Uint8Array(responseBuffer);
|
|
3413
|
-
expect17(Array.from(responseArray)).toEqual([1, 2, 3, 4, 5]);
|
|
2561
|
+
expect15(headers["x-override"]).toBe("init-header");
|
|
2562
|
+
expect15(headers["x-original"]).toBe("request-header");
|
|
3414
2563
|
});
|
|
3415
2564
|
});
|
|
3416
2565
|
}
|
|
3417
2566
|
|
|
3418
2567
|
// src/driver-test-suite/tests/raw-http-request-properties.ts
|
|
3419
|
-
import { describe as
|
|
2568
|
+
import { describe as describe17, expect as expect16, test as test16 } from "vitest";
|
|
3420
2569
|
function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
3421
|
-
|
|
3422
|
-
|
|
2570
|
+
describe17("raw http request properties", () => {
|
|
2571
|
+
test16("should pass all Request properties correctly to onFetch", async (c) => {
|
|
3423
2572
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3424
2573
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3425
2574
|
const response = await actor2.fetch("test/path?foo=bar&baz=qux", {
|
|
@@ -3431,33 +2580,33 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3431
2580
|
},
|
|
3432
2581
|
body: JSON.stringify({ test: "data" })
|
|
3433
2582
|
});
|
|
3434
|
-
|
|
2583
|
+
expect16(response.ok).toBe(true);
|
|
3435
2584
|
const data = await response.json();
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
2585
|
+
expect16(data.url).toContain("/test/path?foo=bar&baz=qux");
|
|
2586
|
+
expect16(data.pathname).toBe("/test/path");
|
|
2587
|
+
expect16(data.search).toBe("?foo=bar&baz=qux");
|
|
2588
|
+
expect16(data.searchParams).toEqual({
|
|
3440
2589
|
foo: "bar",
|
|
3441
2590
|
baz: "qux"
|
|
3442
2591
|
});
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
2592
|
+
expect16(data.method).toBe("POST");
|
|
2593
|
+
expect16(data.headers["content-type"]).toBe("application/json");
|
|
2594
|
+
expect16(data.headers["x-custom-header"]).toBe("custom-value");
|
|
2595
|
+
expect16(data.headers["authorization"]).toBe("Bearer test-token");
|
|
2596
|
+
expect16(data.body).toEqual({ test: "data" });
|
|
3448
2597
|
});
|
|
3449
|
-
|
|
2598
|
+
test16("should handle GET requests with no body", async (c) => {
|
|
3450
2599
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3451
2600
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3452
2601
|
const response = await actor2.fetch("test/get", {
|
|
3453
2602
|
method: "GET"
|
|
3454
2603
|
});
|
|
3455
|
-
|
|
2604
|
+
expect16(response.ok).toBe(true);
|
|
3456
2605
|
const data = await response.json();
|
|
3457
|
-
|
|
3458
|
-
|
|
2606
|
+
expect16(data.method).toBe("GET");
|
|
2607
|
+
expect16(data.body).toBeNull();
|
|
3459
2608
|
});
|
|
3460
|
-
|
|
2609
|
+
test16("should handle different content types", async (c) => {
|
|
3461
2610
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3462
2611
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3463
2612
|
const formData = new URLSearchParams();
|
|
@@ -3470,12 +2619,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3470
2619
|
},
|
|
3471
2620
|
body: formData.toString()
|
|
3472
2621
|
});
|
|
3473
|
-
|
|
2622
|
+
expect16(formResponse.ok).toBe(true);
|
|
3474
2623
|
const formResult = await formResponse.json();
|
|
3475
|
-
|
|
2624
|
+
expect16(formResult.headers["content-type"]).toBe(
|
|
3476
2625
|
"application/x-www-form-urlencoded"
|
|
3477
2626
|
);
|
|
3478
|
-
|
|
2627
|
+
expect16(formResult.bodyText).toBe("field1=value1&field2=value2");
|
|
3479
2628
|
const textResponse = await actor2.fetch("test/text", {
|
|
3480
2629
|
method: "POST",
|
|
3481
2630
|
headers: {
|
|
@@ -3483,12 +2632,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3483
2632
|
},
|
|
3484
2633
|
body: "Hello, World!"
|
|
3485
2634
|
});
|
|
3486
|
-
|
|
2635
|
+
expect16(textResponse.ok).toBe(true);
|
|
3487
2636
|
const textResult = await textResponse.json();
|
|
3488
|
-
|
|
3489
|
-
|
|
2637
|
+
expect16(textResult.headers["content-type"]).toBe("text/plain");
|
|
2638
|
+
expect16(textResult.bodyText).toBe("Hello, World!");
|
|
3490
2639
|
});
|
|
3491
|
-
|
|
2640
|
+
test16("should preserve all header casing and values", async (c) => {
|
|
3492
2641
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3493
2642
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3494
2643
|
const response = await actor2.fetch("test/headers", {
|
|
@@ -3500,34 +2649,34 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3500
2649
|
"X-Request-ID": "12345"
|
|
3501
2650
|
}
|
|
3502
2651
|
});
|
|
3503
|
-
|
|
2652
|
+
expect16(response.ok).toBe(true);
|
|
3504
2653
|
const data = await response.json();
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
2654
|
+
expect16(data.headers["accept"]).toBe("application/json");
|
|
2655
|
+
expect16(data.headers["accept-language"]).toBe("en-US,en;q=0.9");
|
|
2656
|
+
expect16(data.headers["cache-control"]).toBe("no-cache");
|
|
2657
|
+
expect16(data.headers["user-agent"]).toBeTruthy();
|
|
2658
|
+
expect16(data.headers["x-request-id"]).toBe("12345");
|
|
3510
2659
|
});
|
|
3511
|
-
|
|
2660
|
+
test16("should handle empty and special URL paths", async (c) => {
|
|
3512
2661
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3513
2662
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3514
2663
|
const rootResponse = await actor2.fetch("");
|
|
3515
|
-
|
|
2664
|
+
expect16(rootResponse.ok).toBe(true);
|
|
3516
2665
|
const rootData = await rootResponse.json();
|
|
3517
|
-
|
|
2666
|
+
expect16(rootData.pathname).toBe("/");
|
|
3518
2667
|
const specialResponse = await actor2.fetch(
|
|
3519
2668
|
"test/path%20with%20spaces/and%2Fslashes"
|
|
3520
2669
|
);
|
|
3521
|
-
|
|
2670
|
+
expect16(specialResponse.ok).toBe(true);
|
|
3522
2671
|
const specialData = await specialResponse.json();
|
|
3523
|
-
|
|
2672
|
+
expect16(specialData.pathname).toMatch(/path.*with.*spaces.*and.*slashes/);
|
|
3524
2673
|
const fragmentResponse = await actor2.fetch("test/path#fragment");
|
|
3525
|
-
|
|
2674
|
+
expect16(fragmentResponse.ok).toBe(true);
|
|
3526
2675
|
const fragmentData = await fragmentResponse.json();
|
|
3527
|
-
|
|
3528
|
-
|
|
2676
|
+
expect16(fragmentData.pathname).toBe("/test/path");
|
|
2677
|
+
expect16(fragmentData.hash).toBe("");
|
|
3529
2678
|
});
|
|
3530
|
-
|
|
2679
|
+
test16("should handle request properties for all HTTP methods", async (c) => {
|
|
3531
2680
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3532
2681
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3533
2682
|
const methods = [
|
|
@@ -3546,33 +2695,33 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3546
2695
|
body: ["POST", "PUT", "PATCH"].includes(method) ? JSON.stringify({ method }) : void 0
|
|
3547
2696
|
});
|
|
3548
2697
|
if (method === "HEAD") {
|
|
3549
|
-
|
|
2698
|
+
expect16(response.status).toBe(200);
|
|
3550
2699
|
const text = await response.text();
|
|
3551
|
-
|
|
2700
|
+
expect16(text).toBe("");
|
|
3552
2701
|
} else if (method === "OPTIONS") {
|
|
3553
|
-
|
|
2702
|
+
expect16(response.status).toBe(204);
|
|
3554
2703
|
const text = await response.text();
|
|
3555
|
-
|
|
2704
|
+
expect16(text).toBe("");
|
|
3556
2705
|
} else {
|
|
3557
|
-
|
|
2706
|
+
expect16(response.ok).toBe(true);
|
|
3558
2707
|
const data = await response.json();
|
|
3559
|
-
|
|
2708
|
+
expect16(data.method).toBe(method);
|
|
3560
2709
|
}
|
|
3561
2710
|
}
|
|
3562
2711
|
});
|
|
3563
|
-
|
|
2712
|
+
test16("should handle complex query parameters", async (c) => {
|
|
3564
2713
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3565
2714
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3566
2715
|
const response = await actor2.fetch(
|
|
3567
2716
|
"test?key=value1&key=value2&array[]=1&array[]=2&nested[prop]=val"
|
|
3568
2717
|
);
|
|
3569
|
-
|
|
2718
|
+
expect16(response.ok).toBe(true);
|
|
3570
2719
|
const data = await response.json();
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
2720
|
+
expect16(data.searchParams.key).toBe("value2");
|
|
2721
|
+
expect16(data.searchParams["array[]"]).toBe("2");
|
|
2722
|
+
expect16(data.searchParams["nested[prop]"]).toBe("val");
|
|
3574
2723
|
});
|
|
3575
|
-
|
|
2724
|
+
test16("should handle multipart form data", async (c) => {
|
|
3576
2725
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3577
2726
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3578
2727
|
const boundary = "----RivetKitBoundary";
|
|
@@ -3594,23 +2743,23 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3594
2743
|
},
|
|
3595
2744
|
body
|
|
3596
2745
|
});
|
|
3597
|
-
|
|
2746
|
+
expect16(response.ok).toBe(true);
|
|
3598
2747
|
const data = await response.json();
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
2748
|
+
expect16(data.headers["content-type"]).toContain("multipart/form-data");
|
|
2749
|
+
expect16(data.bodyText).toContain("field1");
|
|
2750
|
+
expect16(data.bodyText).toContain("value1");
|
|
3602
2751
|
});
|
|
3603
|
-
|
|
2752
|
+
test16("should handle very long URLs", async (c) => {
|
|
3604
2753
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3605
2754
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3606
2755
|
const longValue = "x".repeat(1e3);
|
|
3607
2756
|
const response = await actor2.fetch(`test/long?param=${longValue}`);
|
|
3608
|
-
|
|
2757
|
+
expect16(response.ok).toBe(true);
|
|
3609
2758
|
const data = await response.json();
|
|
3610
|
-
|
|
3611
|
-
|
|
2759
|
+
expect16(data.searchParams.param).toBe(longValue);
|
|
2760
|
+
expect16(data.search.length).toBeGreaterThan(1e3);
|
|
3612
2761
|
});
|
|
3613
|
-
|
|
2762
|
+
test16("should handle large request bodies", async (c) => {
|
|
3614
2763
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3615
2764
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3616
2765
|
const largeArray = new Array(1e4).fill({
|
|
@@ -3625,22 +2774,22 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3625
2774
|
},
|
|
3626
2775
|
body: JSON.stringify(largeArray)
|
|
3627
2776
|
});
|
|
3628
|
-
|
|
2777
|
+
expect16(response.ok).toBe(true);
|
|
3629
2778
|
const data = await response.json();
|
|
3630
|
-
|
|
2779
|
+
expect16(data.body).toHaveLength(1e4);
|
|
3631
2780
|
});
|
|
3632
|
-
|
|
2781
|
+
test16("should handle missing content-type header", async (c) => {
|
|
3633
2782
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3634
2783
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3635
2784
|
const response = await actor2.fetch("test/no-content-type", {
|
|
3636
2785
|
method: "POST",
|
|
3637
2786
|
body: "plain text without content-type"
|
|
3638
2787
|
});
|
|
3639
|
-
|
|
2788
|
+
expect16(response.ok).toBe(true);
|
|
3640
2789
|
const data = await response.json();
|
|
3641
|
-
|
|
2790
|
+
expect16(data.bodyText).toBe("plain text without content-type");
|
|
3642
2791
|
});
|
|
3643
|
-
|
|
2792
|
+
test16("should handle empty request body", async (c) => {
|
|
3644
2793
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3645
2794
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3646
2795
|
const response = await actor2.fetch("test/empty", {
|
|
@@ -3650,12 +2799,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3650
2799
|
},
|
|
3651
2800
|
body: ""
|
|
3652
2801
|
});
|
|
3653
|
-
|
|
2802
|
+
expect16(response.ok).toBe(true);
|
|
3654
2803
|
const data = await response.json();
|
|
3655
|
-
|
|
3656
|
-
|
|
2804
|
+
expect16(data.body).toBeNull();
|
|
2805
|
+
expect16(data.bodyText).toBe("");
|
|
3657
2806
|
});
|
|
3658
|
-
|
|
2807
|
+
test16("should handle custom HTTP methods", async (c) => {
|
|
3659
2808
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3660
2809
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3661
2810
|
try {
|
|
@@ -3664,12 +2813,12 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3664
2813
|
});
|
|
3665
2814
|
if (response.ok) {
|
|
3666
2815
|
const data = await response.json();
|
|
3667
|
-
|
|
2816
|
+
expect16(data.method).toBe("CUSTOM");
|
|
3668
2817
|
}
|
|
3669
2818
|
} catch (error) {
|
|
3670
2819
|
}
|
|
3671
2820
|
});
|
|
3672
|
-
|
|
2821
|
+
test16("should handle cookies in headers", async (c) => {
|
|
3673
2822
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3674
2823
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3675
2824
|
const response = await actor2.fetch("test/cookies", {
|
|
@@ -3677,25 +2826,25 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3677
2826
|
Cookie: "session=abc123; user=test; preferences=dark_mode"
|
|
3678
2827
|
}
|
|
3679
2828
|
});
|
|
3680
|
-
|
|
2829
|
+
expect16(response.ok).toBe(true);
|
|
3681
2830
|
const data = await response.json();
|
|
3682
|
-
|
|
2831
|
+
expect16(data.headers.cookie).toBe(
|
|
3683
2832
|
"session=abc123; user=test; preferences=dark_mode"
|
|
3684
2833
|
);
|
|
3685
2834
|
});
|
|
3686
|
-
|
|
2835
|
+
test16("should handle URL encoding properly", async (c) => {
|
|
3687
2836
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3688
2837
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3689
2838
|
const response = await actor2.fetch(
|
|
3690
2839
|
"test/encoded?special=%20%21%40%23%24%25%5E%26&unicode=%E2%9C%93&email=test%40example.com"
|
|
3691
2840
|
);
|
|
3692
|
-
|
|
2841
|
+
expect16(response.ok).toBe(true);
|
|
3693
2842
|
const data = await response.json();
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
2843
|
+
expect16(data.searchParams.special).toBe(" !@#$%^&");
|
|
2844
|
+
expect16(data.searchParams.unicode).toBe("\u2713");
|
|
2845
|
+
expect16(data.searchParams.email).toBe("test@example.com");
|
|
3697
2846
|
});
|
|
3698
|
-
|
|
2847
|
+
test16("should handle concurrent requests maintaining separate contexts", async (c) => {
|
|
3699
2848
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3700
2849
|
const actor2 = client.rawHttpRequestPropertiesActor.getOrCreate(["test"]);
|
|
3701
2850
|
const requests = [
|
|
@@ -3717,24 +2866,24 @@ function runRawHttpRequestPropertiesTests(driverTestConfig) {
|
|
|
3717
2866
|
const results = await Promise.all(
|
|
3718
2867
|
responses.map((r) => r.json())
|
|
3719
2868
|
);
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
2869
|
+
expect16(results[0].searchParams.id).toBe("1");
|
|
2870
|
+
expect16(results[0].method).toBe("POST");
|
|
2871
|
+
expect16(results[0].body).toEqual({ request: 1 });
|
|
2872
|
+
expect16(results[1].searchParams.id).toBe("2");
|
|
2873
|
+
expect16(results[1].method).toBe("PUT");
|
|
2874
|
+
expect16(results[1].body).toEqual({ request: 2 });
|
|
2875
|
+
expect16(results[2].searchParams.id).toBe("3");
|
|
2876
|
+
expect16(results[2].method).toBe("DELETE");
|
|
2877
|
+
expect16(results[2].body).toBeNull();
|
|
3729
2878
|
});
|
|
3730
2879
|
});
|
|
3731
2880
|
}
|
|
3732
2881
|
|
|
3733
2882
|
// src/driver-test-suite/tests/raw-websocket.ts
|
|
3734
|
-
import { describe as
|
|
2883
|
+
import { describe as describe18, expect as expect17, test as test17 } from "vitest";
|
|
3735
2884
|
function runRawWebSocketTests(driverTestConfig) {
|
|
3736
|
-
|
|
3737
|
-
|
|
2885
|
+
describe18("raw websocket", () => {
|
|
2886
|
+
test17("should establish raw WebSocket connection", async (c) => {
|
|
3738
2887
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3739
2888
|
const actor2 = client.rawWebSocketActor.getOrCreate(["basic"]);
|
|
3740
2889
|
const ws = await actor2.websocket();
|
|
@@ -3761,11 +2910,11 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3761
2910
|
);
|
|
3762
2911
|
ws.addEventListener("close", reject);
|
|
3763
2912
|
});
|
|
3764
|
-
|
|
3765
|
-
|
|
2913
|
+
expect17(welcomeMessage.type).toBe("welcome");
|
|
2914
|
+
expect17(welcomeMessage.connectionCount).toBe(1);
|
|
3766
2915
|
ws.close();
|
|
3767
2916
|
});
|
|
3768
|
-
|
|
2917
|
+
test17("should echo messages", async (c) => {
|
|
3769
2918
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3770
2919
|
const actor2 = client.rawWebSocketActor.getOrCreate(["echo"]);
|
|
3771
2920
|
const ws = await actor2.websocket();
|
|
@@ -3791,10 +2940,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3791
2940
|
);
|
|
3792
2941
|
ws.addEventListener("close", reject);
|
|
3793
2942
|
});
|
|
3794
|
-
|
|
2943
|
+
expect17(echoMessage).toEqual(testMessage);
|
|
3795
2944
|
ws.close();
|
|
3796
2945
|
});
|
|
3797
|
-
|
|
2946
|
+
test17("should handle ping/pong protocol", async (c) => {
|
|
3798
2947
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3799
2948
|
const actor2 = client.rawWebSocketActor.getOrCreate(["ping"]);
|
|
3800
2949
|
const ws = await actor2.websocket();
|
|
@@ -3818,11 +2967,11 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3818
2967
|
});
|
|
3819
2968
|
ws.addEventListener("close", reject);
|
|
3820
2969
|
});
|
|
3821
|
-
|
|
3822
|
-
|
|
2970
|
+
expect17(pongMessage.type).toBe("pong");
|
|
2971
|
+
expect17(pongMessage.timestamp).toBeDefined();
|
|
3823
2972
|
ws.close();
|
|
3824
2973
|
});
|
|
3825
|
-
|
|
2974
|
+
test17("should track stats across connections", async (c) => {
|
|
3826
2975
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3827
2976
|
const actor1 = client.rawWebSocketActor.getOrCreate(["stats"]);
|
|
3828
2977
|
const ws1 = await actor1.websocket();
|
|
@@ -3862,15 +3011,15 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3862
3011
|
});
|
|
3863
3012
|
ws1.send(JSON.stringify({ type: "getStats" }));
|
|
3864
3013
|
const stats = await statsPromise;
|
|
3865
|
-
|
|
3866
|
-
|
|
3014
|
+
expect17(stats.connectionCount).toBe(2);
|
|
3015
|
+
expect17(stats.messageCount).toBe(4);
|
|
3867
3016
|
const actionStats = await actor1.getStats();
|
|
3868
|
-
|
|
3869
|
-
|
|
3017
|
+
expect17(actionStats.connectionCount).toBe(2);
|
|
3018
|
+
expect17(actionStats.messageCount).toBe(4);
|
|
3870
3019
|
ws1.close();
|
|
3871
3020
|
ws2.close();
|
|
3872
3021
|
});
|
|
3873
|
-
|
|
3022
|
+
test17("should handle binary data", async (c) => {
|
|
3874
3023
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3875
3024
|
const actor2 = client.rawWebSocketBinaryActor.getOrCreate(["binary"]);
|
|
3876
3025
|
const ws = await actor2.websocket();
|
|
@@ -3899,7 +3048,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3899
3048
|
const smallData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
3900
3049
|
ws.send(smallData);
|
|
3901
3050
|
const smallReversed = await receiveBinaryMessage();
|
|
3902
|
-
|
|
3051
|
+
expect17(Array.from(smallReversed)).toEqual([5, 4, 3, 2, 1]);
|
|
3903
3052
|
const largeData = new Uint8Array(1024);
|
|
3904
3053
|
for (let i = 0; i < largeData.length; i++) {
|
|
3905
3054
|
largeData[i] = i % 256;
|
|
@@ -3907,11 +3056,11 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3907
3056
|
ws.send(largeData);
|
|
3908
3057
|
const largeReversed = await receiveBinaryMessage();
|
|
3909
3058
|
for (let i = 0; i < largeData.length; i++) {
|
|
3910
|
-
|
|
3059
|
+
expect17(largeReversed[i]).toBe(largeData[largeData.length - 1 - i]);
|
|
3911
3060
|
}
|
|
3912
3061
|
ws.close();
|
|
3913
3062
|
});
|
|
3914
|
-
|
|
3063
|
+
test17("should work with custom paths", async (c) => {
|
|
3915
3064
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3916
3065
|
const actor2 = client.rawWebSocketActor.getOrCreate(["paths"]);
|
|
3917
3066
|
const ws = await actor2.websocket("custom/path");
|
|
@@ -3931,10 +3080,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3931
3080
|
{ once: true }
|
|
3932
3081
|
);
|
|
3933
3082
|
});
|
|
3934
|
-
|
|
3083
|
+
expect17(welcomeMessage.type).toBe("welcome");
|
|
3935
3084
|
ws.close();
|
|
3936
3085
|
});
|
|
3937
|
-
|
|
3086
|
+
test17("should pass connection parameters through subprotocols", async (c) => {
|
|
3938
3087
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3939
3088
|
const testParams = { userId: "test123", role: "admin" };
|
|
3940
3089
|
const actor2 = client.rawWebSocketActor.getOrCreate(["params"], {
|
|
@@ -3954,10 +3103,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3954
3103
|
});
|
|
3955
3104
|
ws.addEventListener("close", reject);
|
|
3956
3105
|
});
|
|
3957
|
-
|
|
3106
|
+
expect17(response).toBeDefined();
|
|
3958
3107
|
ws.close();
|
|
3959
3108
|
});
|
|
3960
|
-
|
|
3109
|
+
test17("should handle connection close properly", async (c) => {
|
|
3961
3110
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3962
3111
|
const actor2 = client.rawWebSocketActor.getOrCreate(["close-test"]);
|
|
3963
3112
|
const ws = await actor2.websocket();
|
|
@@ -3968,7 +3117,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3968
3117
|
});
|
|
3969
3118
|
}
|
|
3970
3119
|
const initialStats = await actor2.getStats();
|
|
3971
|
-
|
|
3120
|
+
expect17(initialStats.connectionCount).toBe(1);
|
|
3972
3121
|
const closePromise = new Promise((resolve2) => {
|
|
3973
3122
|
ws.addEventListener("close", () => resolve2(), { once: true });
|
|
3974
3123
|
});
|
|
@@ -3982,9 +3131,9 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
3982
3131
|
}
|
|
3983
3132
|
await new Promise((resolve2) => setTimeout(resolve2, 50));
|
|
3984
3133
|
}
|
|
3985
|
-
|
|
3134
|
+
expect17(finalStats == null ? void 0 : finalStats.connectionCount).toBe(0);
|
|
3986
3135
|
});
|
|
3987
|
-
|
|
3136
|
+
test17("should properly handle onWebSocket open and close events", async (c) => {
|
|
3988
3137
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
3989
3138
|
const actor2 = client.rawWebSocketActor.getOrCreate(["open-close-test"]);
|
|
3990
3139
|
const ws1 = await actor2.websocket();
|
|
@@ -4002,8 +3151,8 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4002
3151
|
);
|
|
4003
3152
|
ws1.addEventListener("close", reject);
|
|
4004
3153
|
});
|
|
4005
|
-
|
|
4006
|
-
|
|
3154
|
+
expect17(welcome1.type).toBe("welcome");
|
|
3155
|
+
expect17(welcome1.connectionCount).toBe(1);
|
|
4007
3156
|
const ws2 = await actor2.websocket();
|
|
4008
3157
|
await new Promise((resolve2, reject) => {
|
|
4009
3158
|
ws2.addEventListener("open", () => resolve2(), { once: true });
|
|
@@ -4019,10 +3168,10 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4019
3168
|
);
|
|
4020
3169
|
ws2.addEventListener("close", reject);
|
|
4021
3170
|
});
|
|
4022
|
-
|
|
4023
|
-
|
|
3171
|
+
expect17(welcome2.type).toBe("welcome");
|
|
3172
|
+
expect17(welcome2.connectionCount).toBe(2);
|
|
4024
3173
|
const midStats = await actor2.getStats();
|
|
4025
|
-
|
|
3174
|
+
expect17(midStats.connectionCount).toBe(2);
|
|
4026
3175
|
ws1.close();
|
|
4027
3176
|
await new Promise((resolve2) => {
|
|
4028
3177
|
ws1.addEventListener("close", () => resolve2(), { once: true });
|
|
@@ -4035,7 +3184,7 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4035
3184
|
}
|
|
4036
3185
|
await new Promise((resolve2) => setTimeout(resolve2, 50));
|
|
4037
3186
|
}
|
|
4038
|
-
|
|
3187
|
+
expect17(afterFirstClose == null ? void 0 : afterFirstClose.connectionCount).toBe(1);
|
|
4039
3188
|
ws2.close();
|
|
4040
3189
|
await new Promise((resolve2) => {
|
|
4041
3190
|
ws2.addEventListener("close", () => resolve2(), { once: true });
|
|
@@ -4048,9 +3197,9 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4048
3197
|
}
|
|
4049
3198
|
await new Promise((resolve2) => setTimeout(resolve2, 50));
|
|
4050
3199
|
}
|
|
4051
|
-
|
|
3200
|
+
expect17(finalStats == null ? void 0 : finalStats.connectionCount).toBe(0);
|
|
4052
3201
|
});
|
|
4053
|
-
|
|
3202
|
+
test17("should handle query parameters in websocket paths", async (c) => {
|
|
4054
3203
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4055
3204
|
const actor2 = client.rawWebSocketActor.getOrCreate(["query-params"]);
|
|
4056
3205
|
const ws = await actor2.websocket("api/v1/stream?token=abc123&user=test");
|
|
@@ -4069,302 +3218,19 @@ function runRawWebSocketTests(driverTestConfig) {
|
|
|
4069
3218
|
});
|
|
4070
3219
|
ws.send(JSON.stringify({ type: "getRequestInfo" }));
|
|
4071
3220
|
const requestInfo = await requestInfoPromise;
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
ws.close();
|
|
4076
|
-
});
|
|
4077
|
-
});
|
|
4078
|
-
}
|
|
4079
|
-
|
|
4080
|
-
// src/driver-test-suite/tests/raw-websocket-direct-registry.ts
|
|
4081
|
-
import { describe as describe21, expect as expect20, test as test20 } from "vitest";
|
|
4082
|
-
function runRawWebSocketDirectRegistryTests(driverTestConfig) {
|
|
4083
|
-
describe21("raw websocket - direct registry access", () => {
|
|
4084
|
-
test20("should establish vanilla WebSocket connection with proper subprotocols", async (c) => {
|
|
4085
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4086
|
-
const WebSocket2 = await importWebSocket();
|
|
4087
|
-
const actorQuery = {
|
|
4088
|
-
getOrCreateForKey: {
|
|
4089
|
-
name: "rawWebSocketActor",
|
|
4090
|
-
key: ["vanilla-test"]
|
|
4091
|
-
}
|
|
4092
|
-
};
|
|
4093
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4094
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4095
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
|
|
4096
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4097
|
-
queryProtocol,
|
|
4098
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4099
|
-
"rivetkit"
|
|
4100
|
-
]);
|
|
4101
|
-
await new Promise((resolve2, reject) => {
|
|
4102
|
-
ws.addEventListener("open", () => {
|
|
4103
|
-
resolve2();
|
|
4104
|
-
});
|
|
4105
|
-
ws.addEventListener("error", reject);
|
|
4106
|
-
ws.addEventListener("close", reject);
|
|
4107
|
-
});
|
|
4108
|
-
const welcomeMessage = await new Promise((resolve2, reject) => {
|
|
4109
|
-
ws.addEventListener(
|
|
4110
|
-
"message",
|
|
4111
|
-
(event) => {
|
|
4112
|
-
resolve2(JSON.parse(event.data));
|
|
4113
|
-
},
|
|
4114
|
-
{ once: true }
|
|
4115
|
-
);
|
|
4116
|
-
ws.addEventListener("close", reject);
|
|
4117
|
-
});
|
|
4118
|
-
expect20(welcomeMessage.type).toBe("welcome");
|
|
4119
|
-
expect20(welcomeMessage.connectionCount).toBe(1);
|
|
4120
|
-
ws.close();
|
|
4121
|
-
});
|
|
4122
|
-
test20("should echo messages with vanilla WebSocket", async (c) => {
|
|
4123
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4124
|
-
const WebSocket2 = await importWebSocket();
|
|
4125
|
-
const actorQuery = {
|
|
4126
|
-
getOrCreateForKey: {
|
|
4127
|
-
name: "rawWebSocketActor",
|
|
4128
|
-
key: ["vanilla-echo"]
|
|
4129
|
-
}
|
|
4130
|
-
};
|
|
4131
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4132
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4133
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
|
|
4134
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4135
|
-
queryProtocol,
|
|
4136
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4137
|
-
"rivetkit"
|
|
4138
|
-
]);
|
|
4139
|
-
await new Promise((resolve2, reject) => {
|
|
4140
|
-
ws.addEventListener("open", () => resolve2(), { once: true });
|
|
4141
|
-
ws.addEventListener("close", reject);
|
|
4142
|
-
});
|
|
4143
|
-
await new Promise((resolve2, reject) => {
|
|
4144
|
-
ws.addEventListener("message", () => resolve2(), { once: true });
|
|
4145
|
-
ws.addEventListener("close", reject);
|
|
4146
|
-
});
|
|
4147
|
-
const testMessage = { test: "vanilla", timestamp: Date.now() };
|
|
4148
|
-
ws.send(JSON.stringify(testMessage));
|
|
4149
|
-
const echoMessage = await new Promise((resolve2, reject) => {
|
|
4150
|
-
ws.addEventListener(
|
|
4151
|
-
"message",
|
|
4152
|
-
(event) => {
|
|
4153
|
-
resolve2(JSON.parse(event.data));
|
|
4154
|
-
},
|
|
4155
|
-
{ once: true }
|
|
4156
|
-
);
|
|
4157
|
-
ws.addEventListener("close", reject);
|
|
4158
|
-
});
|
|
4159
|
-
expect20(echoMessage).toEqual(testMessage);
|
|
4160
|
-
ws.close();
|
|
4161
|
-
});
|
|
4162
|
-
test20("should handle connection parameters for authentication", async (c) => {
|
|
4163
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4164
|
-
const WebSocket2 = await importWebSocket();
|
|
4165
|
-
const actorQuery = {
|
|
4166
|
-
getOrCreateForKey: {
|
|
4167
|
-
name: "rawWebSocketActor",
|
|
4168
|
-
key: ["vanilla-auth"]
|
|
4169
|
-
}
|
|
4170
|
-
};
|
|
4171
|
-
const connParams = { token: "ws-auth-token", userId: "ws-user123" };
|
|
4172
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4173
|
-
const connParamsProtocol = `conn_params.${encodeURIComponent(JSON.stringify(connParams))}`;
|
|
4174
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4175
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
|
|
4176
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4177
|
-
queryProtocol,
|
|
4178
|
-
connParamsProtocol,
|
|
4179
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4180
|
-
"rivetkit"
|
|
4181
|
-
]);
|
|
4182
|
-
await new Promise((resolve2, reject) => {
|
|
4183
|
-
ws.addEventListener("open", () => {
|
|
4184
|
-
resolve2();
|
|
4185
|
-
});
|
|
4186
|
-
ws.addEventListener("error", reject);
|
|
4187
|
-
ws.addEventListener("close", reject);
|
|
4188
|
-
});
|
|
4189
|
-
const welcomeMessage = await new Promise((resolve2, reject) => {
|
|
4190
|
-
ws.addEventListener(
|
|
4191
|
-
"message",
|
|
4192
|
-
(event) => {
|
|
4193
|
-
resolve2(JSON.parse(event.data));
|
|
4194
|
-
},
|
|
4195
|
-
{ once: true }
|
|
4196
|
-
);
|
|
4197
|
-
ws.addEventListener("close", reject);
|
|
4198
|
-
});
|
|
4199
|
-
expect20(welcomeMessage.type).toBe("welcome");
|
|
4200
|
-
ws.close();
|
|
4201
|
-
});
|
|
4202
|
-
test20("should handle custom user protocols alongside rivetkit protocols", async (c) => {
|
|
4203
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4204
|
-
const WebSocket2 = await importWebSocket();
|
|
4205
|
-
const actorQuery = {
|
|
4206
|
-
getOrCreateForKey: {
|
|
4207
|
-
name: "rawWebSocketActor",
|
|
4208
|
-
key: ["vanilla-protocols"]
|
|
4209
|
-
}
|
|
4210
|
-
};
|
|
4211
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4212
|
-
const userProtocol1 = "chat-v1";
|
|
4213
|
-
const userProtocol2 = "custom-protocol";
|
|
4214
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4215
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
|
|
4216
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4217
|
-
queryProtocol,
|
|
4218
|
-
userProtocol1,
|
|
4219
|
-
userProtocol2,
|
|
4220
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4221
|
-
"rivetkit"
|
|
4222
|
-
]);
|
|
4223
|
-
await new Promise((resolve2, reject) => {
|
|
4224
|
-
ws.addEventListener("open", () => {
|
|
4225
|
-
resolve2();
|
|
4226
|
-
});
|
|
4227
|
-
ws.addEventListener("error", reject);
|
|
4228
|
-
ws.addEventListener("close", reject);
|
|
4229
|
-
});
|
|
4230
|
-
const welcomeMessage = await new Promise((resolve2, reject) => {
|
|
4231
|
-
ws.addEventListener(
|
|
4232
|
-
"message",
|
|
4233
|
-
(event) => {
|
|
4234
|
-
resolve2(JSON.parse(event.data));
|
|
4235
|
-
},
|
|
4236
|
-
{ once: true }
|
|
4237
|
-
);
|
|
4238
|
-
ws.addEventListener("close", reject);
|
|
4239
|
-
});
|
|
4240
|
-
expect20(welcomeMessage.type).toBe("welcome");
|
|
4241
|
-
ws.close();
|
|
4242
|
-
});
|
|
4243
|
-
test20("should handle different paths for WebSocket routes", async (c) => {
|
|
4244
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4245
|
-
const WebSocket2 = await importWebSocket();
|
|
4246
|
-
const actorQuery = {
|
|
4247
|
-
getOrCreateForKey: {
|
|
4248
|
-
name: "rawWebSocketActor",
|
|
4249
|
-
key: ["vanilla-paths"]
|
|
4250
|
-
}
|
|
4251
|
-
};
|
|
4252
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4253
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4254
|
-
const paths = ["chat/room1", "updates/feed", "stream/events"];
|
|
4255
|
-
for (const path of paths) {
|
|
4256
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/${path}`;
|
|
4257
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4258
|
-
queryProtocol,
|
|
4259
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4260
|
-
"rivetkit"
|
|
4261
|
-
]);
|
|
4262
|
-
await new Promise((resolve2, reject) => {
|
|
4263
|
-
ws.addEventListener("open", () => {
|
|
4264
|
-
resolve2();
|
|
4265
|
-
});
|
|
4266
|
-
ws.addEventListener("error", reject);
|
|
4267
|
-
});
|
|
4268
|
-
const welcomeMessage = await new Promise((resolve2, reject) => {
|
|
4269
|
-
ws.addEventListener(
|
|
4270
|
-
"message",
|
|
4271
|
-
(event) => {
|
|
4272
|
-
resolve2(JSON.parse(event.data));
|
|
4273
|
-
},
|
|
4274
|
-
{ once: true }
|
|
4275
|
-
);
|
|
4276
|
-
ws.addEventListener("close", reject);
|
|
4277
|
-
});
|
|
4278
|
-
expect20(welcomeMessage.type).toBe("welcome");
|
|
4279
|
-
ws.close();
|
|
4280
|
-
}
|
|
4281
|
-
});
|
|
4282
|
-
test20("should return error for actors without onWebSocket handler", async (c) => {
|
|
4283
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4284
|
-
const WebSocket2 = await importWebSocket();
|
|
4285
|
-
const actorQuery = {
|
|
4286
|
-
getOrCreateForKey: {
|
|
4287
|
-
name: "rawWebSocketNoHandlerActor",
|
|
4288
|
-
key: ["vanilla-no-handler"]
|
|
4289
|
-
}
|
|
4290
|
-
};
|
|
4291
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4292
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4293
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
|
|
4294
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4295
|
-
queryProtocol,
|
|
4296
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4297
|
-
"rivetkit"
|
|
4298
|
-
]);
|
|
4299
|
-
await new Promise((resolve2) => {
|
|
4300
|
-
ws.addEventListener("error", () => resolve2(), { once: true });
|
|
4301
|
-
ws.addEventListener("close", () => resolve2(), { once: true });
|
|
4302
|
-
});
|
|
4303
|
-
expect20(ws.readyState).toBe(ws.CLOSED || 3);
|
|
4304
|
-
});
|
|
4305
|
-
test20("should handle binary data over vanilla WebSocket", async (c) => {
|
|
4306
|
-
const { endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4307
|
-
const WebSocket2 = await importWebSocket();
|
|
4308
|
-
const actorQuery = {
|
|
4309
|
-
getOrCreateForKey: {
|
|
4310
|
-
name: "rawWebSocketActor",
|
|
4311
|
-
key: ["vanilla-binary"]
|
|
4312
|
-
}
|
|
4313
|
-
};
|
|
4314
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4315
|
-
const wsEndpoint = endpoint.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
4316
|
-
const wsUrl = `${wsEndpoint}/registry/actors/raw/websocket/`;
|
|
4317
|
-
const ws = new WebSocket2(wsUrl, [
|
|
4318
|
-
queryProtocol,
|
|
4319
|
-
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
4320
|
-
"rivetkit"
|
|
4321
|
-
]);
|
|
4322
|
-
ws.binaryType = "arraybuffer";
|
|
4323
|
-
await new Promise((resolve2, reject) => {
|
|
4324
|
-
ws.addEventListener("open", () => resolve2(), { once: true });
|
|
4325
|
-
ws.addEventListener("close", reject);
|
|
4326
|
-
});
|
|
4327
|
-
await new Promise((resolve2, reject) => {
|
|
4328
|
-
ws.addEventListener("message", () => resolve2(), { once: true });
|
|
4329
|
-
ws.addEventListener("close", reject);
|
|
4330
|
-
});
|
|
4331
|
-
const binaryData = new Uint8Array([1, 2, 3, 4, 5]);
|
|
4332
|
-
ws.send(binaryData.buffer);
|
|
4333
|
-
const echoedData = await new Promise((resolve2, reject) => {
|
|
4334
|
-
ws.addEventListener(
|
|
4335
|
-
"message",
|
|
4336
|
-
(event) => {
|
|
4337
|
-
resolve2(event.data);
|
|
4338
|
-
},
|
|
4339
|
-
{ once: true }
|
|
4340
|
-
);
|
|
4341
|
-
ws.addEventListener("close", reject);
|
|
4342
|
-
});
|
|
4343
|
-
const echoedArray = new Uint8Array(echoedData);
|
|
4344
|
-
expect20(Array.from(echoedArray)).toEqual([1, 2, 3, 4, 5]);
|
|
4345
|
-
ws.send(JSON.stringify({ type: "binary-test", size: binaryData.length }));
|
|
4346
|
-
const echoMessage = await new Promise((resolve2, reject) => {
|
|
4347
|
-
ws.addEventListener(
|
|
4348
|
-
"message",
|
|
4349
|
-
(event) => {
|
|
4350
|
-
resolve2(JSON.parse(event.data));
|
|
4351
|
-
},
|
|
4352
|
-
{ once: true }
|
|
4353
|
-
);
|
|
4354
|
-
ws.addEventListener("close", reject);
|
|
4355
|
-
});
|
|
4356
|
-
expect20(echoMessage.type).toBe("binary-test");
|
|
4357
|
-
expect20(echoMessage.size).toBe(5);
|
|
3221
|
+
expect17(requestInfo.url).toContain("api/v1/stream");
|
|
3222
|
+
expect17(requestInfo.url).toContain("token=abc123");
|
|
3223
|
+
expect17(requestInfo.url).toContain("user=test");
|
|
4358
3224
|
ws.close();
|
|
4359
3225
|
});
|
|
4360
3226
|
});
|
|
4361
3227
|
}
|
|
4362
3228
|
|
|
4363
3229
|
// src/driver-test-suite/tests/request-access.ts
|
|
4364
|
-
import { describe as
|
|
3230
|
+
import { describe as describe19, expect as expect18, test as test18 } from "vitest";
|
|
4365
3231
|
function runRequestAccessTests(driverTestConfig) {
|
|
4366
|
-
|
|
4367
|
-
|
|
3232
|
+
describe19("Request Access in Lifecycle Hooks", () => {
|
|
3233
|
+
test18("should have access to request object in onBeforeConnect and createConnState", async (c) => {
|
|
4368
3234
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4369
3235
|
const handle = client.requestAccessActor.getOrCreate(["test-request"], {
|
|
4370
3236
|
params: { trackRequest: true }
|
|
@@ -4372,19 +3238,19 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4372
3238
|
const connection = handle.connect();
|
|
4373
3239
|
const requestInfo = await connection.getRequestInfo();
|
|
4374
3240
|
if (driverTestConfig.clientType === "http") {
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
3241
|
+
expect18(requestInfo.onBeforeConnect.hasRequest).toBe(true);
|
|
3242
|
+
expect18(requestInfo.onBeforeConnect.requestUrl).toBeDefined();
|
|
3243
|
+
expect18(requestInfo.onBeforeConnect.requestMethod).toBeDefined();
|
|
3244
|
+
expect18(requestInfo.onBeforeConnect.requestHeaders).toBeDefined();
|
|
3245
|
+
expect18(requestInfo.createConnState.hasRequest).toBe(true);
|
|
3246
|
+
expect18(requestInfo.createConnState.requestUrl).toBeDefined();
|
|
3247
|
+
expect18(requestInfo.createConnState.requestMethod).toBeDefined();
|
|
3248
|
+
expect18(requestInfo.createConnState.requestHeaders).toBeDefined();
|
|
4383
3249
|
} else {
|
|
4384
3250
|
}
|
|
4385
3251
|
await connection.dispose();
|
|
4386
3252
|
});
|
|
4387
|
-
|
|
3253
|
+
test18("should not have request when trackRequest is false", async (c) => {
|
|
4388
3254
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4389
3255
|
const handle = client.requestAccessActor.getOrCreate(
|
|
4390
3256
|
["test-no-request"],
|
|
@@ -4394,21 +3260,21 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4394
3260
|
);
|
|
4395
3261
|
const connection = handle.connect();
|
|
4396
3262
|
const requestInfo = await connection.getRequestInfo();
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
3263
|
+
expect18(requestInfo.onBeforeConnect.hasRequest).toBe(false);
|
|
3264
|
+
expect18(requestInfo.onBeforeConnect.requestUrl).toBeNull();
|
|
3265
|
+
expect18(requestInfo.onBeforeConnect.requestMethod).toBeNull();
|
|
3266
|
+
expect18(
|
|
4401
3267
|
Object.keys(requestInfo.onBeforeConnect.requestHeaders)
|
|
4402
3268
|
).toHaveLength(0);
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
3269
|
+
expect18(requestInfo.createConnState.hasRequest).toBe(false);
|
|
3270
|
+
expect18(requestInfo.createConnState.requestUrl).toBeNull();
|
|
3271
|
+
expect18(requestInfo.createConnState.requestMethod).toBeNull();
|
|
3272
|
+
expect18(
|
|
4407
3273
|
Object.keys(requestInfo.createConnState.requestHeaders)
|
|
4408
3274
|
).toHaveLength(0);
|
|
4409
3275
|
await connection.dispose();
|
|
4410
3276
|
});
|
|
4411
|
-
|
|
3277
|
+
test18("should capture request headers and method", async (c) => {
|
|
4412
3278
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
4413
3279
|
const handle = client.requestAccessActor.getOrCreate(["test-headers"], {
|
|
4414
3280
|
params: { trackRequest: true }
|
|
@@ -4416,113 +3282,24 @@ function runRequestAccessTests(driverTestConfig) {
|
|
|
4416
3282
|
const connection = handle.connect();
|
|
4417
3283
|
const requestInfo = await connection.getRequestInfo();
|
|
4418
3284
|
if (driverTestConfig.clientType === "http") {
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
3285
|
+
expect18(requestInfo.onBeforeConnect.hasRequest).toBe(true);
|
|
3286
|
+
expect18(requestInfo.onBeforeConnect.requestMethod).toBeTruthy();
|
|
3287
|
+
expect18(requestInfo.onBeforeConnect.requestUrl).toBeTruthy();
|
|
3288
|
+
expect18(requestInfo.onBeforeConnect.requestHeaders).toBeTruthy();
|
|
3289
|
+
expect18(typeof requestInfo.onBeforeConnect.requestHeaders).toBe(
|
|
4424
3290
|
"object"
|
|
4425
3291
|
);
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
3292
|
+
expect18(requestInfo.createConnState.hasRequest).toBe(true);
|
|
3293
|
+
expect18(requestInfo.createConnState.requestMethod).toBeTruthy();
|
|
3294
|
+
expect18(requestInfo.createConnState.requestUrl).toBeTruthy();
|
|
3295
|
+
expect18(requestInfo.createConnState.requestHeaders).toBeTruthy();
|
|
3296
|
+
expect18(typeof requestInfo.createConnState.requestHeaders).toBe(
|
|
4431
3297
|
"object"
|
|
4432
3298
|
);
|
|
4433
3299
|
} else {
|
|
4434
3300
|
}
|
|
4435
3301
|
await connection.dispose();
|
|
4436
3302
|
});
|
|
4437
|
-
test21("should have access to request object in onAuth", async (c) => {
|
|
4438
|
-
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4439
|
-
if (driverTestConfig.clientType === "http") {
|
|
4440
|
-
console.log("Skipping onAuth test - requires public endpoint setup");
|
|
4441
|
-
}
|
|
4442
|
-
});
|
|
4443
|
-
test21("should have access to request object in onFetch", async (c) => {
|
|
4444
|
-
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4445
|
-
const handle = client.requestAccessActor.getOrCreate(["test-fetch"]);
|
|
4446
|
-
await handle.resolve();
|
|
4447
|
-
const actorQuery = {
|
|
4448
|
-
getOrCreateForKey: {
|
|
4449
|
-
name: "requestAccessActor",
|
|
4450
|
-
key: ["test-fetch"]
|
|
4451
|
-
}
|
|
4452
|
-
};
|
|
4453
|
-
const url = `${endpoint}/registry/actors/raw/http/test-path`;
|
|
4454
|
-
const response = await fetch(url, {
|
|
4455
|
-
method: "POST",
|
|
4456
|
-
headers: {
|
|
4457
|
-
"Content-Type": "application/json",
|
|
4458
|
-
"X-Test-Header": "test-value",
|
|
4459
|
-
"X-RivetKit-Query": JSON.stringify(actorQuery)
|
|
4460
|
-
},
|
|
4461
|
-
body: JSON.stringify({ test: "data" })
|
|
4462
|
-
});
|
|
4463
|
-
if (!response.ok) {
|
|
4464
|
-
const errorText = await response.text();
|
|
4465
|
-
console.error(
|
|
4466
|
-
`HTTP request failed: ${response.status} ${response.statusText}`,
|
|
4467
|
-
errorText
|
|
4468
|
-
);
|
|
4469
|
-
}
|
|
4470
|
-
expect21(response.ok).toBe(true);
|
|
4471
|
-
const data = await response.json();
|
|
4472
|
-
expect21(data.hasRequest).toBe(true);
|
|
4473
|
-
expect21(data.requestUrl).toContain("/test-path");
|
|
4474
|
-
expect21(data.requestMethod).toBe("POST");
|
|
4475
|
-
expect21(data.requestHeaders).toBeDefined();
|
|
4476
|
-
expect21(data.requestHeaders["content-type"]).toBe(
|
|
4477
|
-
"application/json"
|
|
4478
|
-
);
|
|
4479
|
-
expect21(data.requestHeaders["x-test-header"]).toBe("test-value");
|
|
4480
|
-
});
|
|
4481
|
-
test21("should have access to request object in onWebSocket", async (c) => {
|
|
4482
|
-
const { client, endpoint } = await setupDriverTest(c, driverTestConfig);
|
|
4483
|
-
if (typeof WebSocket !== "undefined") {
|
|
4484
|
-
const handle = client.requestAccessActor.getOrCreate([
|
|
4485
|
-
"test-websocket"
|
|
4486
|
-
]);
|
|
4487
|
-
await handle.resolve();
|
|
4488
|
-
const actorQuery = {
|
|
4489
|
-
getOrCreateForKey: {
|
|
4490
|
-
name: "requestAccessActor",
|
|
4491
|
-
key: ["test-websocket"]
|
|
4492
|
-
}
|
|
4493
|
-
};
|
|
4494
|
-
const queryProtocol = `query.${encodeURIComponent(JSON.stringify(actorQuery))}`;
|
|
4495
|
-
const wsUrl = endpoint.replace("http://", "ws://").replace("https://", "wss://");
|
|
4496
|
-
const ws = new WebSocket(
|
|
4497
|
-
`${wsUrl}/registry/actors/raw/websocket/test-path`,
|
|
4498
|
-
[
|
|
4499
|
-
queryProtocol,
|
|
4500
|
-
"rivetkit"
|
|
4501
|
-
// Required protocol
|
|
4502
|
-
]
|
|
4503
|
-
);
|
|
4504
|
-
await new Promise((resolve2, reject) => {
|
|
4505
|
-
ws.onopen = () => {
|
|
4506
|
-
};
|
|
4507
|
-
ws.onmessage = (event) => {
|
|
4508
|
-
try {
|
|
4509
|
-
const data = JSON.parse(event.data);
|
|
4510
|
-
expect21(data.hasRequest).toBe(true);
|
|
4511
|
-
expect21(data.requestUrl).toContain("/test-path");
|
|
4512
|
-
expect21(data.requestMethod).toBe("GET");
|
|
4513
|
-
expect21(data.requestHeaders).toBeDefined();
|
|
4514
|
-
ws.close();
|
|
4515
|
-
resolve2();
|
|
4516
|
-
} catch (error) {
|
|
4517
|
-
reject(error);
|
|
4518
|
-
}
|
|
4519
|
-
};
|
|
4520
|
-
ws.onerror = (error) => {
|
|
4521
|
-
reject(error);
|
|
4522
|
-
};
|
|
4523
|
-
});
|
|
4524
|
-
}
|
|
4525
|
-
});
|
|
4526
3303
|
});
|
|
4527
3304
|
}
|
|
4528
3305
|
|
|
@@ -4533,11 +3310,11 @@ function runDriverTests(driverTestConfigPartial) {
|
|
|
4533
3310
|
...driverTestConfigPartial,
|
|
4534
3311
|
clientType
|
|
4535
3312
|
};
|
|
4536
|
-
|
|
3313
|
+
describe20(`client type (${clientType})`, () => {
|
|
4537
3314
|
runActorDriverTests(driverTestConfig);
|
|
4538
3315
|
runManagerDriverTests(driverTestConfig);
|
|
4539
3316
|
for (const transport of ["websocket", "sse"]) {
|
|
4540
|
-
|
|
3317
|
+
describe20(`transport (${transport})`, () => {
|
|
4541
3318
|
runActorConnTests({
|
|
4542
3319
|
...driverTestConfig,
|
|
4543
3320
|
transport
|
|
@@ -4553,13 +3330,10 @@ function runDriverTests(driverTestConfigPartial) {
|
|
|
4553
3330
|
runActorMetadataTests(driverTestConfig);
|
|
4554
3331
|
runActorOnStateChangeTests(driverTestConfig);
|
|
4555
3332
|
runActorErrorHandlingTests(driverTestConfig);
|
|
4556
|
-
runActorAuthTests(driverTestConfig);
|
|
4557
3333
|
runActorInlineClientTests(driverTestConfig);
|
|
4558
3334
|
runRawHttpTests(driverTestConfig);
|
|
4559
3335
|
runRawHttpRequestPropertiesTests(driverTestConfig);
|
|
4560
3336
|
runRawWebSocketTests(driverTestConfig);
|
|
4561
|
-
runRawHttpDirectRegistryTests(driverTestConfig);
|
|
4562
|
-
runRawWebSocketDirectRegistryTests(driverTestConfig);
|
|
4563
3337
|
runActorInspectorTests(driverTestConfig);
|
|
4564
3338
|
});
|
|
4565
3339
|
}
|
|
@@ -4571,46 +3345,64 @@ async function createTestRuntime(registryPath, driverFactory) {
|
|
|
4571
3345
|
filepath: registryPath
|
|
4572
3346
|
});
|
|
4573
3347
|
registry.config.test.enabled = true;
|
|
4574
|
-
const {
|
|
4575
|
-
let injectWebSocket;
|
|
4576
|
-
let upgradeWebSocket;
|
|
4577
|
-
const config = RunConfigSchema.parse({
|
|
3348
|
+
const {
|
|
4578
3349
|
driver,
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
3350
|
+
cleanup: driverCleanup,
|
|
3351
|
+
rivetEngine
|
|
3352
|
+
} = await driverFactory(registry);
|
|
3353
|
+
if (rivetEngine) {
|
|
3354
|
+
const cleanup = async () => {
|
|
3355
|
+
await (driverCleanup == null ? void 0 : driverCleanup());
|
|
3356
|
+
};
|
|
3357
|
+
return {
|
|
3358
|
+
endpoint: rivetEngine.endpoint,
|
|
3359
|
+
namespace: rivetEngine.namespace,
|
|
3360
|
+
runnerName: rivetEngine.runnerName,
|
|
3361
|
+
cleanup
|
|
3362
|
+
};
|
|
3363
|
+
} else {
|
|
3364
|
+
let upgradeWebSocket;
|
|
3365
|
+
const config = RunConfigSchema.parse({
|
|
3366
|
+
driver,
|
|
3367
|
+
getUpgradeWebSocket: () => upgradeWebSocket,
|
|
3368
|
+
inspector: {
|
|
3369
|
+
enabled: true,
|
|
3370
|
+
token: () => "token"
|
|
3371
|
+
}
|
|
3372
|
+
});
|
|
3373
|
+
const managerDriver = driver.manager(registry.config, config);
|
|
3374
|
+
const { router } = createManagerRouter(
|
|
3375
|
+
registry.config,
|
|
3376
|
+
config,
|
|
3377
|
+
managerDriver,
|
|
3378
|
+
false
|
|
3379
|
+
);
|
|
3380
|
+
const nodeWebSocket = createNodeWebSocket({ app: router });
|
|
3381
|
+
upgradeWebSocket = nodeWebSocket.upgradeWebSocket;
|
|
3382
|
+
const port = await getPort();
|
|
3383
|
+
const server = honoServe({
|
|
3384
|
+
fetch: router.fetch,
|
|
3385
|
+
hostname: "127.0.0.1",
|
|
3386
|
+
port
|
|
3387
|
+
});
|
|
3388
|
+
invariant(
|
|
3389
|
+
nodeWebSocket.injectWebSocket !== void 0,
|
|
3390
|
+
"should have injectWebSocket"
|
|
3391
|
+
);
|
|
3392
|
+
nodeWebSocket.injectWebSocket(server);
|
|
3393
|
+
const serverEndpoint = `http://127.0.0.1:${port}`;
|
|
3394
|
+
logger().info({ msg: "test serer listening", port });
|
|
3395
|
+
const cleanup = async () => {
|
|
3396
|
+
await new Promise((resolve2) => server.close(() => resolve2(void 0)));
|
|
3397
|
+
await (driverCleanup == null ? void 0 : driverCleanup());
|
|
3398
|
+
};
|
|
3399
|
+
return {
|
|
3400
|
+
endpoint: serverEndpoint,
|
|
3401
|
+
namespace: "default",
|
|
3402
|
+
runnerName: "rivetkit",
|
|
3403
|
+
cleanup
|
|
3404
|
+
};
|
|
3405
|
+
}
|
|
4614
3406
|
}
|
|
4615
3407
|
export {
|
|
4616
3408
|
createTestRuntime,
|