@reventlessdev/reventless-local 3.0.0-alpha.167 → 3.0.0-alpha.169

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/package.json +11 -11
  3. package/src/Platform.res +11 -1
  4. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +16 -8
  5. package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res.mjs +7 -7
  6. package/src/adapter/DomainGraphQL_Server.res +96 -0
  7. package/src/adapter/DomainGraphQL_Server.res.mjs +84 -0
  8. package/src/adapter/GraphQL_Server.res.mjs +18 -0
  9. package/src/adapter/LocalObjectStore.res +64 -0
  10. package/src/adapter/LocalObjectStore.res.mjs +55 -0
  11. package/src/adapter/PgProjectionCatchup.res +6 -1
  12. package/src/adapter/PgProjectionCatchup.res.mjs +4 -2
  13. package/src/adapter/ProjectionCheckpoint.res +11 -2
  14. package/src/adapter/ProjectionCheckpoint.res.mjs +9 -3
  15. package/tests/PluginEventDecodeTest.res +2 -0
  16. package/tests/PluginEventDecodeTest.res.mjs +2 -2
  17. package/tests/adapter/GraphQL_SchemaInspectorTest.res +52 -1
  18. package/tests/adapter/GraphQL_SchemaInspectorTest.res.mjs +39 -1
  19. package/tests/adapter/InboundTranslationMutationTest.res +139 -0
  20. package/tests/adapter/InboundTranslationMutationTest.res.mjs +132 -0
  21. package/tests/adapter/QueryDbListResolverTest.res +2 -0
  22. package/tests/adapter/QueryDbListResolverTest.res.mjs +2 -0
  23. package/tests/adapter/ServedBucketHttpTest.res +174 -0
  24. package/tests/adapter/ServedBucketHttpTest.res.mjs +177 -0
  25. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res +13 -9
  26. package/tests/components/inboundtranslationslice/InboundTranslationSliceCallbackTest.res.mjs +21 -13
  27. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res +215 -0
  28. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformFixtures.res.mjs +273 -0
  29. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformTest.res +38 -0
  30. package/tests/components/outboundtranslationslice/OutboundTranslationSlicePlatformTest.res.mjs +28 -0
  31. package/tests/components/stateviewslice/StateViewSliceFixtures.res +1 -1
  32. package/tests/components/stateviewslice/StateViewSliceFixtures.res.mjs +2 -1
  33. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res +1 -1
  34. package/tests/components/stateviewslice/StateViewSliceSubIdFixtures.res.mjs +2 -1
@@ -0,0 +1,174 @@
1
+ // End-to-end test for the local served-bucket HTTP routes on DomainGraphQL_Server
2
+ // (the dev analogue of the AWS CloudFront read path). Boots a real server on a
3
+ // private port, then exercises the full upload → store → serve loop:
4
+ // POST /__inmemory/upload → {uploadUrl, storageRef}
5
+ // PUT /{prefix}/{key} → 200 (store)
6
+ // GET /{prefix}/{key} → the stored bytes + content-type
7
+ // Talks to the server over node:http (Jest 27's VM strips global fetch), same
8
+ // as LocalAuthHttpTest.
9
+
10
+ @@warning("-44")
11
+
12
+ open JestGlobals
13
+
14
+ let _ = TestRunner.setup()
15
+
16
+ // High ephemeral port, clear of dev-server defaults and the auth HTTP test.
17
+ let port = 49322
18
+
19
+ // ── Minimal node:http helpers ───────────────────────────────────────────────
20
+
21
+ type httpRequestOptions = {
22
+ hostname: string,
23
+ port: int,
24
+ path: string,
25
+ method: string,
26
+ headers: dict<string>,
27
+ }
28
+ type httpReq
29
+ type httpRes
30
+ @module("node:http") external _request: (httpRequestOptions, httpRes => unit) => httpReq = "request"
31
+ @send external _reqWrite: (httpReq, string) => unit = "write"
32
+ @send external _reqEnd: (httpReq, @as(json`null`) _) => unit = "end"
33
+ @send external _reqOnError: (httpReq, @as("error") _, 'err => unit) => unit = "on"
34
+ @send external _resOnData: (httpRes, @as("data") _, 'chunk => unit) => unit = "on"
35
+ @send external _resOnEnd: (httpRes, @as("end") _, unit => unit) => unit = "on"
36
+ @send external _resSetEncoding: (httpRes, string) => unit = "setEncoding"
37
+ @get external _resStatusCode: httpRes => int = "statusCode"
38
+ @get external _resHeaders: httpRes => dict<string> = "headers"
39
+
40
+ let postJson = (path: string, body: dict<JSON.t>): promise<(int, JSON.t)> =>
41
+ Promise.make((resolve, reject) => {
42
+ let bodyStr = body->JSON.Encode.object->JSON.stringify
43
+ let req =
44
+ _request(
45
+ {
46
+ hostname: "localhost",
47
+ port,
48
+ path,
49
+ method: "POST",
50
+ headers: Dict.fromArray([
51
+ ("content-type", "application/json"),
52
+ ("content-length", bodyStr->String.length->Int.toString),
53
+ ]),
54
+ },
55
+ res => {
56
+ let status = _resStatusCode(res)
57
+ let buf = ref("")
58
+ res->_resSetEncoding("utf8")
59
+ res->_resOnData(chunk => buf := buf.contents ++ Obj.magic(chunk))
60
+ res->_resOnEnd(() => {
61
+ let parsed = try buf.contents->JSON.parseOrThrow catch {
62
+ | _ => JSON.Encode.null
63
+ }
64
+ resolve((status, parsed))
65
+ })
66
+ },
67
+ )
68
+ req->_reqOnError(err => reject(Obj.magic(err)))
69
+ req->_reqWrite(bodyStr)
70
+ req->_reqEnd
71
+ })
72
+
73
+ // PUT a raw (ASCII) body to a served-object path. Content-length is byte-safe
74
+ // only for ASCII payloads, which the SVG fixture below is.
75
+ let putRaw = (path: string, body: string, ~contentType: string): promise<int> =>
76
+ Promise.make((resolve, reject) => {
77
+ let req =
78
+ _request(
79
+ {
80
+ hostname: "localhost",
81
+ port,
82
+ path,
83
+ method: "PUT",
84
+ headers: Dict.fromArray([
85
+ ("content-type", contentType),
86
+ ("content-length", body->String.length->Int.toString),
87
+ ]),
88
+ },
89
+ res => {
90
+ let status = _resStatusCode(res)
91
+ res->_resOnData(_ => ())
92
+ res->_resOnEnd(() => resolve(status))
93
+ },
94
+ )
95
+ req->_reqOnError(err => reject(Obj.magic(err)))
96
+ req->_reqWrite(body)
97
+ req->_reqEnd
98
+ })
99
+
100
+ let getRaw = (path: string): promise<(int, string, string)> =>
101
+ Promise.make((resolve, reject) => {
102
+ let req =
103
+ _request(
104
+ {hostname: "localhost", port, path, method: "GET", headers: Dict.make()},
105
+ res => {
106
+ let status = _resStatusCode(res)
107
+ let contentType = _resHeaders(res)->Dict.get("content-type")->Option.getOr("")
108
+ let buf = ref("")
109
+ res->_resSetEncoding("utf8")
110
+ res->_resOnData(chunk => buf := buf.contents ++ Obj.magic(chunk))
111
+ res->_resOnEnd(() => resolve((status, buf.contents, contentType)))
112
+ },
113
+ )
114
+ req->_reqOnError(err => reject(Obj.magic(err)))
115
+ req->_reqEnd
116
+ })
117
+
118
+ let getString = (j: JSON.t, k: string): string =>
119
+ j->JSON.Decode.object->Option.flatMap(d => d->Dict.get(k))->Option.flatMap(JSON.Decode.string)->Option.getOr("")
120
+
121
+ // ── Lifecycle ────────────────────────────────────────────────────────────────
122
+
123
+ beforeAllAsync(async () => {
124
+ DomainGraphQL_Server.reset()
125
+ DomainGraphQL_Server.start(~port, ())
126
+ await Promise.make((resolve, _) => setTimeout(() => resolve(), 50)->ignore)
127
+ })
128
+
129
+ afterAll(() => {
130
+ DomainGraphQL_Server.stop()
131
+ })
132
+
133
+ // ── Tests ──────────────────────────────────────────────────────────────────
134
+
135
+ testPromise("POST /__inmemory/upload returns matching uploadUrl + storageRef under the prefix", async () => {
136
+ let (status, body) =
137
+ await postJson(
138
+ "/__inmemory/upload",
139
+ Dict.fromArray([
140
+ ("fileName", JSON.Encode.string("logo.svg")),
141
+ ("contentType", JSON.Encode.string("image/svg+xml")),
142
+ ]),
143
+ )
144
+ expect(status)->toEqual(200)
145
+ let uploadUrl = getString(body, "uploadUrl")
146
+ let storageRef = getString(body, "storageRef")
147
+ // Same same-origin ref serves as both the PUT target and the stored value.
148
+ expect(uploadUrl)->toEqual(storageRef)
149
+ expect(storageRef->String.startsWith("/uploads/"))->toEqual(true)
150
+ expect(storageRef->String.endsWith("/logo.svg"))->toEqual(true)
151
+ })
152
+
153
+ testPromise("PUT then GET round-trips the bytes and content-type", async () => {
154
+ let (_, body) =
155
+ await postJson(
156
+ "/__inmemory/upload",
157
+ Dict.fromArray([("fileName", JSON.Encode.string("pixel.svg"))]),
158
+ )
159
+ let ref = getString(body, "storageRef")
160
+ let svg = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'></svg>"
161
+
162
+ let putStatus = await putRaw(ref, svg, ~contentType="image/svg+xml")
163
+ expect(putStatus)->toEqual(200)
164
+
165
+ let (getStatus, gotBody, gotContentType) = await getRaw(ref)
166
+ expect(getStatus)->toEqual(200)
167
+ expect(gotBody)->toEqual(svg)
168
+ expect(gotContentType)->toEqual("image/svg+xml")
169
+ })
170
+
171
+ testPromise("GET a missing served object returns 404", async () => {
172
+ let (status, _, _) = await getRaw("/uploads/missing/none.svg")
173
+ expect(status)->toEqual(404)
174
+ })
@@ -0,0 +1,177 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Nodehttp from "node:http";
4
+ import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
5
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
6
+ import * as TestRunner$ReventlessLocal from "../../src/test/TestRunner.res.mjs";
7
+ import * as DomainGraphQL_Server$ReventlessLocal from "../../src/adapter/DomainGraphQL_Server.res.mjs";
8
+
9
+ TestRunner$ReventlessLocal.setup();
10
+
11
+ function postJson(path, body) {
12
+ return new Promise((resolve, reject) => {
13
+ let bodyStr = JSON.stringify(body);
14
+ let req = Nodehttp.request({
15
+ hostname: "localhost",
16
+ port: 49322,
17
+ path: path,
18
+ method: "POST",
19
+ headers: Object.fromEntries([
20
+ [
21
+ "content-type",
22
+ "application/json"
23
+ ],
24
+ [
25
+ "content-length",
26
+ bodyStr.length.toString()
27
+ ]
28
+ ])
29
+ }, res => {
30
+ let status = res.statusCode;
31
+ let buf = {
32
+ contents: ""
33
+ };
34
+ res.setEncoding("utf8");
35
+ res.on("data", chunk => {
36
+ buf.contents = buf.contents + chunk;
37
+ });
38
+ res.on("end", () => {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(buf.contents);
42
+ } catch (exn) {
43
+ parsed = null;
44
+ }
45
+ resolve([
46
+ status,
47
+ parsed
48
+ ]);
49
+ });
50
+ });
51
+ req.on("error", err => reject(err));
52
+ req.write(bodyStr);
53
+ req.end(null);
54
+ });
55
+ }
56
+
57
+ function putRaw(path, body, contentType) {
58
+ return new Promise((resolve, reject) => {
59
+ let req = Nodehttp.request({
60
+ hostname: "localhost",
61
+ port: 49322,
62
+ path: path,
63
+ method: "PUT",
64
+ headers: Object.fromEntries([
65
+ [
66
+ "content-type",
67
+ contentType
68
+ ],
69
+ [
70
+ "content-length",
71
+ body.length.toString()
72
+ ]
73
+ ])
74
+ }, res => {
75
+ let status = res.statusCode;
76
+ res.on("data", param => {});
77
+ res.on("end", () => resolve(status));
78
+ });
79
+ req.on("error", err => reject(err));
80
+ req.write(body);
81
+ req.end(null);
82
+ });
83
+ }
84
+
85
+ function getRaw(path) {
86
+ return new Promise((resolve, reject) => {
87
+ let req = Nodehttp.request({
88
+ hostname: "localhost",
89
+ port: 49322,
90
+ path: path,
91
+ method: "GET",
92
+ headers: {}
93
+ }, res => {
94
+ let status = res.statusCode;
95
+ let contentType = Stdlib_Option.getOr(res.headers["content-type"], "");
96
+ let buf = {
97
+ contents: ""
98
+ };
99
+ res.setEncoding("utf8");
100
+ res.on("data", chunk => {
101
+ buf.contents = buf.contents + chunk;
102
+ });
103
+ res.on("end", () => resolve([
104
+ status,
105
+ buf.contents,
106
+ contentType
107
+ ]));
108
+ });
109
+ req.on("error", err => reject(err));
110
+ req.end(null);
111
+ });
112
+ }
113
+
114
+ function getString(j, k) {
115
+ return Stdlib_Option.getOr(Stdlib_Option.flatMap(Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(j), d => d[k]), Stdlib_JSON.Decode.string), "");
116
+ }
117
+
118
+ globalThis.beforeAll(async () => {
119
+ DomainGraphQL_Server$ReventlessLocal.reset();
120
+ DomainGraphQL_Server$ReventlessLocal.start(49322, undefined, undefined);
121
+ return await new Promise((resolve, param) => {
122
+ setTimeout(() => resolve(), 50);
123
+ });
124
+ });
125
+
126
+ globalThis.afterAll(() => DomainGraphQL_Server$ReventlessLocal.stop());
127
+
128
+ globalThis.test("POST /__inmemory/upload returns matching uploadUrl + storageRef under the prefix", async () => {
129
+ let match = await postJson("/__inmemory/upload", Object.fromEntries([
130
+ [
131
+ "fileName",
132
+ "logo.svg"
133
+ ],
134
+ [
135
+ "contentType",
136
+ "image/svg+xml"
137
+ ]
138
+ ]));
139
+ let body = match[1];
140
+ globalThis.expect(match[0]).toEqual(200);
141
+ let uploadUrl = getString(body, "uploadUrl");
142
+ let storageRef = getString(body, "storageRef");
143
+ globalThis.expect(uploadUrl).toEqual(storageRef);
144
+ globalThis.expect(storageRef.startsWith("/uploads/")).toEqual(true);
145
+ globalThis.expect(storageRef.endsWith("/logo.svg")).toEqual(true);
146
+ });
147
+
148
+ globalThis.test("PUT then GET round-trips the bytes and content-type", async () => {
149
+ let match = await postJson("/__inmemory/upload", Object.fromEntries([[
150
+ "fileName",
151
+ "pixel.svg"
152
+ ]]));
153
+ let ref = getString(match[1], "storageRef");
154
+ let svg = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'></svg>";
155
+ let putStatus = await putRaw(ref, svg, "image/svg+xml");
156
+ globalThis.expect(putStatus).toEqual(200);
157
+ let match$1 = await getRaw(ref);
158
+ globalThis.expect(match$1[0]).toEqual(200);
159
+ globalThis.expect(match$1[1]).toEqual(svg);
160
+ globalThis.expect(match$1[2]).toEqual("image/svg+xml");
161
+ });
162
+
163
+ globalThis.test("GET a missing served object returns 404", async () => {
164
+ let match = await getRaw("/uploads/missing/none.svg");
165
+ globalThis.expect(match[0]).toEqual(404);
166
+ });
167
+
168
+ let port = 49322;
169
+
170
+ export {
171
+ port,
172
+ postJson,
173
+ putRaw,
174
+ getRaw,
175
+ getString,
176
+ }
177
+ /* Not a pure module */
@@ -34,9 +34,11 @@ describe("InboundTranslationSlice Callback", () => {
34
34
  let result = await Callback.receive(mockPublish, inputJson)
35
35
 
36
36
  switch result {
37
- | Ok(targetIds) =>
38
- expect(targetIds->Array.length)->toBe(1)
39
- expect(targetIds->Array.getUnsafe(0))->toBe("ord-1")
37
+ | Ok({requestId, targetIds, commandCount}) =>
38
+ expect(targetIds)->toEqual(["ord-1"])
39
+ expect(commandCount)->toBe(1)
40
+ // requestId keys the audit row, so the caller can correlate the response.
41
+ expect(Callback.auditLog->Dict.get(requestId)->Option.isSome)->toBe(true)
40
42
  | Error(_) => expect(true)->toBe(false)
41
43
  }
42
44
  expect(publishedCommands.contents->Array.length)->toBe(1)
@@ -67,7 +69,7 @@ describe("InboundTranslationSlice Callback", () => {
67
69
  let result = await Callback.receive(mockPublish, inputJson)
68
70
 
69
71
  switch result {
70
- | Error(msg) => expect(msg)->toBe("Unknown payment status: pending")
72
+ | Error({error}) => expect(error)->toBe("Unknown payment status: pending")
71
73
  | Ok(_) => expect(true)->toBe(false)
72
74
  }
73
75
  expect(publishedCommands.contents->Array.length)->toBe(0)
@@ -112,7 +114,7 @@ describe("InboundTranslationSlice Callback", () => {
112
114
  let result = await Callback.receive(failingPublish, inputJson)
113
115
 
114
116
  switch result {
115
- | Error(msg) => expect(msg)->toBe("publish failed")
117
+ | Error({error}) => expect(error)->toBe("publish failed")
116
118
  | Ok(_) => expect(true)->toBe(false)
117
119
  }
118
120
 
@@ -177,9 +179,9 @@ describe("InboundTranslationSlice Callback", () => {
177
179
  let result = await MultiCallback.receive(mockPublish, inputJson)
178
180
 
179
181
  switch result {
180
- | Ok(targetIds) =>
181
- expect(targetIds->Array.length)->toBe(3)
182
- expect(targetIds->Array.getUnsafe(0))->toBe("ord-1")
182
+ | Ok({targetIds, commandCount}) =>
183
+ expect(targetIds)->toEqual(["ord-1", "ord-1", "ord-1"])
184
+ expect(commandCount)->toBe(3)
183
185
  | Error(_) => expect(true)->toBe(false)
184
186
  }
185
187
  // All 3 commands published in one batch
@@ -234,7 +236,9 @@ describe("InboundTranslationSlice Callback", () => {
234
236
  let result = await EmptyCallback.receive(mockPublish, inputJson)
235
237
 
236
238
  switch result {
237
- | Ok(targetIds) => expect(targetIds->Array.length)->toBe(0)
239
+ | Ok({targetIds, commandCount}) =>
240
+ expect(targetIds)->toEqual([])
241
+ expect(commandCount)->toBe(0)
238
242
  | Error(_) => expect(true)->toBe(false)
239
243
  }
240
244
  expect(publishedCommands.contents->Array.length)->toBe(0)
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as S from "sury/src/S.res.mjs";
4
4
  import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
5
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
6
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
6
7
  import * as DcbTag$Reventless from "@reventlessdev/reventless-spec/src/components/DcbTag.res.mjs";
7
8
  import * as InboundTranslationSliceFixtures$ReventlessLocal from "./InboundTranslationSliceFixtures.res.mjs";
@@ -45,9 +46,10 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
45
46
  };
46
47
  let result = await Callback.receive(mockPublish, inputJson);
47
48
  if (result.TAG === "Ok") {
48
- let targetIds = result._0;
49
- globalThis.expect(targetIds.length).toBe(1);
50
- globalThis.expect(targetIds[0]).toBe("ord-1");
49
+ let match = result._0;
50
+ globalThis.expect(match.targetIds).toEqual(["ord-1"]);
51
+ globalThis.expect(match.commandCount).toBe(1);
52
+ globalThis.expect(Stdlib_Option.isSome(Callback.auditLog[match.requestId])).toBe(true);
51
53
  } else {
52
54
  globalThis.expect(true).toBe(false);
53
55
  }
@@ -56,8 +58,8 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
56
58
  globalThis.expect(cmd.id).toBe("ord-1");
57
59
  let auditEntries = Object.entries(Callback.auditLog);
58
60
  globalThis.expect(auditEntries.length).toBe(1);
59
- let match = auditEntries[0];
60
- let auditRow = match[1];
61
+ let match$1 = auditEntries[0];
62
+ let auditRow = match$1[1];
61
63
  globalThis.expect(auditRow.status).toBe("Success");
62
64
  globalThis.expect(auditRow.commandCount).toBe(1);
63
65
  });
@@ -77,7 +79,7 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
77
79
  if (result.TAG === "Ok") {
78
80
  globalThis.expect(true).toBe(false);
79
81
  } else {
80
- globalThis.expect(result._0).toBe("Unknown payment status: pending");
82
+ globalThis.expect(result._0.error).toBe("Unknown payment status: pending");
81
83
  }
82
84
  globalThis.expect(publishedCommands.contents.length).toBe(0);
83
85
  let auditEntries = Object.entries(Callback.auditLog);
@@ -112,7 +114,7 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
112
114
  if (result.TAG === "Ok") {
113
115
  globalThis.expect(true).toBe(false);
114
116
  } else {
115
- globalThis.expect(result._0).toBe("publish failed");
117
+ globalThis.expect(result._0.error).toBe("publish failed");
116
118
  }
117
119
  let auditEntries = Object.entries(Callback.auditLog);
118
120
  globalThis.expect(auditEntries.length).toBe(1);
@@ -173,17 +175,21 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
173
175
  };
174
176
  let result = await MultiCallback.receive(mockPublish, inputJson);
175
177
  if (result.TAG === "Ok") {
176
- let targetIds = result._0;
177
- globalThis.expect(targetIds.length).toBe(3);
178
- globalThis.expect(targetIds[0]).toBe("ord-1");
178
+ let match = result._0;
179
+ globalThis.expect(match.targetIds).toEqual([
180
+ "ord-1",
181
+ "ord-1",
182
+ "ord-1"
183
+ ]);
184
+ globalThis.expect(match.commandCount).toBe(3);
179
185
  } else {
180
186
  globalThis.expect(true).toBe(false);
181
187
  }
182
188
  globalThis.expect(publishedCommands.contents.length).toBe(3);
183
189
  let auditEntries = Object.entries(MultiCallback.auditLog);
184
190
  globalThis.expect(auditEntries.length).toBe(1);
185
- let match = auditEntries[0];
186
- let auditRow = match[1];
191
+ let match$1 = auditEntries[0];
192
+ let auditRow = match$1[1];
187
193
  globalThis.expect(auditRow.status).toBe("Success");
188
194
  globalThis.expect(auditRow.commandCount).toBe(3);
189
195
  });
@@ -226,7 +232,9 @@ globalThis.describe("InboundTranslationSlice Callback", () => {
226
232
  };
227
233
  let result = await EmptyCallback.receive(mockPublish, inputJson);
228
234
  if (result.TAG === "Ok") {
229
- globalThis.expect(result._0.length).toBe(0);
235
+ let match = result._0;
236
+ globalThis.expect(match.targetIds).toEqual([]);
237
+ globalThis.expect(match.commandCount).toBe(0);
230
238
  } else {
231
239
  globalThis.expect(true).toBe(false);
232
240
  }