@reventlessdev/reventless-local 3.0.0-alpha.152 → 3.0.0-alpha.154
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/CHANGELOG.md +14 -0
- package/package.json +10 -10
- package/src/Platform.res +40 -184
- package/src/Platform.res.mjs +54 -353
- package/src/adapter/Api/LocalGraphQL_Adapter.res +1 -11
- package/src/adapter/Api/LocalGraphQL_Adapter.res.mjs +0 -7
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res +6 -6
- package/src/adapter/CommandGenerator/CommandGeneratorResolvers_GraphQL.res.mjs +3 -5
- package/src/adapter/DomainGraphQL_Server.res +334 -132
- package/src/adapter/DomainGraphQL_Server.res.mjs +274 -126
- package/src/adapter/GraphQL_Server.res.mjs +41 -17
- package/tests/adapter/DomainGraphQL_ServerTest.res +161 -0
- package/tests/adapter/DomainGraphQL_ServerTest.res.mjs +192 -0
- package/tests/plugin/ApiFragmentRegistryBehavior_GWT.res +0 -131
- package/tests/plugin/ApiFragmentRegistryBehavior_GWT.res.mjs +0 -268
- package/tests/plugin/ApiFragmentsProjection_GWT.res +0 -108
- package/tests/plugin/ApiFragmentsProjection_GWT.res.mjs +0 -172
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as Behavior_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/Behavior_GWT.res.mjs";
|
|
4
|
-
import * as ApiFragmentRegistrySpec$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/ApiFragmentRegistrySpec.res.mjs";
|
|
5
|
-
import * as ApiFragmentRegistryBehavior$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/ApiFragmentRegistryBehavior.res.mjs";
|
|
6
|
-
|
|
7
|
-
let Test = Behavior_GWT$ReventlessGwt.MakeFromAggregate({
|
|
8
|
-
name: ApiFragmentRegistrySpec$ReventlessCore.name,
|
|
9
|
-
commandSchema: ApiFragmentRegistrySpec$ReventlessCore.commandSchema,
|
|
10
|
-
eventSchema: ApiFragmentRegistrySpec$ReventlessCore.eventSchema,
|
|
11
|
-
errorSchema: ApiFragmentRegistrySpec$ReventlessCore.errorSchema
|
|
12
|
-
})({
|
|
13
|
-
Spec: {
|
|
14
|
-
name: ApiFragmentRegistrySpec$ReventlessCore.name,
|
|
15
|
-
commandSchema: ApiFragmentRegistrySpec$ReventlessCore.commandSchema,
|
|
16
|
-
eventSchema: ApiFragmentRegistrySpec$ReventlessCore.eventSchema,
|
|
17
|
-
errorSchema: ApiFragmentRegistrySpec$ReventlessCore.errorSchema
|
|
18
|
-
},
|
|
19
|
-
initialState: ApiFragmentRegistryBehavior$ReventlessCore.initialState,
|
|
20
|
-
evolve: ApiFragmentRegistryBehavior$ReventlessCore.evolve,
|
|
21
|
-
decide: ApiFragmentRegistryBehavior$ReventlessCore.decide,
|
|
22
|
-
snapshot: undefined,
|
|
23
|
-
moduleUrl: ApiFragmentRegistryBehavior$ReventlessCore.moduleUrl
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
let fragment1 = {
|
|
27
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
28
|
-
protocol: "graphql"
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
let fragment2 = {
|
|
32
|
-
encoded: `{"types":["type Catalog_Product { id: ID!\\n name: String! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
33
|
-
protocol: "graphql"
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
function entry(pluginId, fragment, apiTarget) {
|
|
37
|
-
return {
|
|
38
|
-
pluginId: pluginId,
|
|
39
|
-
encoded: fragment.encoded,
|
|
40
|
-
protocol: fragment.protocol,
|
|
41
|
-
apiTarget: apiTarget
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
Test.describe("ApiFragmentRegistry aggregate", () => {
|
|
46
|
-
Test.test("register on empty state emits ApiFragmentRegistered + ApiSchemaComputed", () => Test.thenEvents(Test.whenCmd(Test.givenEvents([]), {
|
|
47
|
-
TAG: "RegisterApiFragment",
|
|
48
|
-
pluginId: "p1",
|
|
49
|
-
fragment: fragment1,
|
|
50
|
-
apiTarget: "Domain",
|
|
51
|
-
at: "t0"
|
|
52
|
-
}), [
|
|
53
|
-
{
|
|
54
|
-
TAG: "ApiFragmentRegistered",
|
|
55
|
-
pluginId: "p1",
|
|
56
|
-
fragment: fragment1,
|
|
57
|
-
apiTarget: "Domain",
|
|
58
|
-
at: "t0"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
TAG: "ApiSchemaComputed",
|
|
62
|
-
snapshot: [entry("p1", fragment1, "Domain")]
|
|
63
|
-
}
|
|
64
|
-
]));
|
|
65
|
-
Test.test("re-registering an identical fragment + target is idempotent (no event)", () => Test.thenNoEvent(Test.whenCmd(Test.givenEvents([{
|
|
66
|
-
TAG: "ApiFragmentRegistered",
|
|
67
|
-
pluginId: "p1",
|
|
68
|
-
fragment: fragment1,
|
|
69
|
-
apiTarget: "Domain",
|
|
70
|
-
at: "t0"
|
|
71
|
-
}]), {
|
|
72
|
-
TAG: "RegisterApiFragment",
|
|
73
|
-
pluginId: "p1",
|
|
74
|
-
fragment: fragment1,
|
|
75
|
-
apiTarget: "Domain",
|
|
76
|
-
at: "t1"
|
|
77
|
-
})));
|
|
78
|
-
Test.test("registering a changed fragment emits ApiFragmentUpdated + ApiSchemaComputed", () => Test.thenEvents(Test.whenCmd(Test.givenEvents([{
|
|
79
|
-
TAG: "ApiFragmentRegistered",
|
|
80
|
-
pluginId: "p1",
|
|
81
|
-
fragment: fragment1,
|
|
82
|
-
apiTarget: "Domain",
|
|
83
|
-
at: "t0"
|
|
84
|
-
}]), {
|
|
85
|
-
TAG: "RegisterApiFragment",
|
|
86
|
-
pluginId: "p1",
|
|
87
|
-
fragment: fragment2,
|
|
88
|
-
apiTarget: "Domain",
|
|
89
|
-
at: "t1"
|
|
90
|
-
}), [
|
|
91
|
-
{
|
|
92
|
-
TAG: "ApiFragmentUpdated",
|
|
93
|
-
pluginId: "p1",
|
|
94
|
-
previousFragment: fragment1,
|
|
95
|
-
newFragment: fragment2,
|
|
96
|
-
apiTarget: "Domain",
|
|
97
|
-
at: "t1"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
TAG: "ApiSchemaComputed",
|
|
101
|
-
snapshot: [entry("p1", fragment2, "Domain")]
|
|
102
|
-
}
|
|
103
|
-
]));
|
|
104
|
-
Test.test("retargeting a plugin with an identical fragment emits ApiFragmentUpdated (fields move APIs)", () => Test.thenEvents(Test.whenCmd(Test.givenEvents([{
|
|
105
|
-
TAG: "ApiFragmentRegistered",
|
|
106
|
-
pluginId: "p1",
|
|
107
|
-
fragment: fragment1,
|
|
108
|
-
apiTarget: "Domain",
|
|
109
|
-
at: "t0"
|
|
110
|
-
}]), {
|
|
111
|
-
TAG: "RegisterApiFragment",
|
|
112
|
-
pluginId: "p1",
|
|
113
|
-
fragment: fragment1,
|
|
114
|
-
apiTarget: "Platform",
|
|
115
|
-
at: "t1"
|
|
116
|
-
}), [
|
|
117
|
-
{
|
|
118
|
-
TAG: "ApiFragmentUpdated",
|
|
119
|
-
pluginId: "p1",
|
|
120
|
-
previousFragment: fragment1,
|
|
121
|
-
newFragment: fragment1,
|
|
122
|
-
apiTarget: "Platform",
|
|
123
|
-
at: "t1"
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
TAG: "ApiSchemaComputed",
|
|
127
|
-
snapshot: [entry("p1", fragment1, "Platform")]
|
|
128
|
-
}
|
|
129
|
-
]));
|
|
130
|
-
Test.test("registering a second plugin carries BOTH plugins in the snapshot (consistent whole-registry fold)", () => Test.thenEvents(Test.whenCmd(Test.givenEvents([{
|
|
131
|
-
TAG: "ApiFragmentRegistered",
|
|
132
|
-
pluginId: "p1",
|
|
133
|
-
fragment: fragment1,
|
|
134
|
-
apiTarget: "Domain",
|
|
135
|
-
at: "t0"
|
|
136
|
-
}]), {
|
|
137
|
-
TAG: "RegisterApiFragment",
|
|
138
|
-
pluginId: "p2",
|
|
139
|
-
fragment: fragment2,
|
|
140
|
-
apiTarget: "Platform",
|
|
141
|
-
at: "t1"
|
|
142
|
-
}), [
|
|
143
|
-
{
|
|
144
|
-
TAG: "ApiFragmentRegistered",
|
|
145
|
-
pluginId: "p2",
|
|
146
|
-
fragment: fragment2,
|
|
147
|
-
apiTarget: "Platform",
|
|
148
|
-
at: "t1"
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
TAG: "ApiSchemaComputed",
|
|
152
|
-
snapshot: [
|
|
153
|
-
entry("p1", fragment1, "Domain"),
|
|
154
|
-
entry("p2", fragment2, "Platform")
|
|
155
|
-
]
|
|
156
|
-
}
|
|
157
|
-
]));
|
|
158
|
-
Test.test("deregister emits ApiFragmentDeregistered + an empty-registry ApiSchemaComputed", () => Test.thenEvents(Test.whenCmd(Test.givenEvents([{
|
|
159
|
-
TAG: "ApiFragmentRegistered",
|
|
160
|
-
pluginId: "p1",
|
|
161
|
-
fragment: fragment1,
|
|
162
|
-
apiTarget: "Domain",
|
|
163
|
-
at: "t0"
|
|
164
|
-
}]), {
|
|
165
|
-
TAG: "DeregisterApiFragment",
|
|
166
|
-
pluginId: "p1"
|
|
167
|
-
}), [
|
|
168
|
-
{
|
|
169
|
-
TAG: "ApiFragmentDeregistered",
|
|
170
|
-
pluginId: "p1"
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
TAG: "ApiSchemaComputed",
|
|
174
|
-
snapshot: []
|
|
175
|
-
}
|
|
176
|
-
]));
|
|
177
|
-
Test.test("deregistering an absent fragment is idempotent (no event)", () => Test.thenNoEvent(Test.whenCmd(Test.givenEvents([]), {
|
|
178
|
-
TAG: "DeregisterApiFragment",
|
|
179
|
-
pluginId: "p1"
|
|
180
|
-
})));
|
|
181
|
-
Test.test("recording a push outcome emits ONLY ApiFragmentPushRecorded (no snapshot, no recompute loop)", () => Test.thenEvent(Test.whenCmd(Test.givenEvents([{
|
|
182
|
-
TAG: "ApiFragmentRegistered",
|
|
183
|
-
pluginId: "p1",
|
|
184
|
-
fragment: fragment1,
|
|
185
|
-
apiTarget: "Domain",
|
|
186
|
-
at: "t0"
|
|
187
|
-
}]), {
|
|
188
|
-
TAG: "RecordApiFragmentPush",
|
|
189
|
-
pluginId: "p1",
|
|
190
|
-
ok: true,
|
|
191
|
-
message: "",
|
|
192
|
-
at: "t1"
|
|
193
|
-
}), {
|
|
194
|
-
TAG: "ApiFragmentPushRecorded",
|
|
195
|
-
pluginId: "p1",
|
|
196
|
-
ok: true,
|
|
197
|
-
message: "",
|
|
198
|
-
at: "t1"
|
|
199
|
-
}));
|
|
200
|
-
Test.test("redelivering an identical push record is idempotent (no event)", () => Test.thenNoEvent(Test.whenCmd(Test.givenEvents([
|
|
201
|
-
{
|
|
202
|
-
TAG: "ApiFragmentRegistered",
|
|
203
|
-
pluginId: "p1",
|
|
204
|
-
fragment: fragment1,
|
|
205
|
-
apiTarget: "Domain",
|
|
206
|
-
at: "t0"
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
TAG: "ApiFragmentPushRecorded",
|
|
210
|
-
pluginId: "p1",
|
|
211
|
-
ok: true,
|
|
212
|
-
message: "",
|
|
213
|
-
at: "t1"
|
|
214
|
-
}
|
|
215
|
-
]), {
|
|
216
|
-
TAG: "RecordApiFragmentPush",
|
|
217
|
-
pluginId: "p1",
|
|
218
|
-
ok: true,
|
|
219
|
-
message: "",
|
|
220
|
-
at: "t1"
|
|
221
|
-
})));
|
|
222
|
-
Test.test("a later distinct push outcome is recorded again", () => Test.thenEvent(Test.whenCmd(Test.givenEvents([
|
|
223
|
-
{
|
|
224
|
-
TAG: "ApiFragmentRegistered",
|
|
225
|
-
pluginId: "p1",
|
|
226
|
-
fragment: fragment1,
|
|
227
|
-
apiTarget: "Domain",
|
|
228
|
-
at: "t0"
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
TAG: "ApiFragmentPushRecorded",
|
|
232
|
-
pluginId: "p1",
|
|
233
|
-
ok: true,
|
|
234
|
-
message: "",
|
|
235
|
-
at: "t1"
|
|
236
|
-
}
|
|
237
|
-
]), {
|
|
238
|
-
TAG: "RecordApiFragmentPush",
|
|
239
|
-
pluginId: "p1",
|
|
240
|
-
ok: false,
|
|
241
|
-
message: "stitch failed",
|
|
242
|
-
at: "t2"
|
|
243
|
-
}), {
|
|
244
|
-
TAG: "ApiFragmentPushRecorded",
|
|
245
|
-
pluginId: "p1",
|
|
246
|
-
ok: false,
|
|
247
|
-
message: "stitch failed",
|
|
248
|
-
at: "t2"
|
|
249
|
-
}));
|
|
250
|
-
Test.test("recording a push for an unregistered plugin is dropped (no event)", () => Test.thenNoEvent(Test.whenCmd(Test.givenEvents([]), {
|
|
251
|
-
TAG: "RecordApiFragmentPush",
|
|
252
|
-
pluginId: "p1",
|
|
253
|
-
ok: true,
|
|
254
|
-
message: "",
|
|
255
|
-
at: "t1"
|
|
256
|
-
})));
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
let P;
|
|
260
|
-
|
|
261
|
-
export {
|
|
262
|
-
P,
|
|
263
|
-
Test,
|
|
264
|
-
fragment1,
|
|
265
|
-
fragment2,
|
|
266
|
-
entry,
|
|
267
|
-
}
|
|
268
|
-
/* Test Not a pure module */
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
// Projection GWT for the ApiFragments read model — one row per plugin name holding the
|
|
2
|
-
// current fragment + push status, projected off the ApiFragmentRegistry aggregate's events
|
|
3
|
-
// (event-sourced-fragment-registries plan). Keyed by the payload pluginId (not the singleton
|
|
4
|
-
// aggregate id). ApiSchemaComputed is the reactive-push trigger only — it must NOT touch a row.
|
|
5
|
-
open ReventlessCore
|
|
6
|
-
module P = Reventless.Plugin // P.Domain / P.Platform — avoid opening apiSchemaFragment's labels
|
|
7
|
-
|
|
8
|
-
module Test = ReventlessGwt.MultiSourceProjection_GWT.Make(ApiFragmentsProjection.ApiFragmentsMapping)
|
|
9
|
-
open Test
|
|
10
|
-
open ApiFragmentRegistrySpec
|
|
11
|
-
|
|
12
|
-
let fragment1: Reventless.Plugin.apiSchemaFragment = {
|
|
13
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
14
|
-
protocol: "graphql",
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let fragment2: Reventless.Plugin.apiSchemaFragment = {
|
|
18
|
-
encoded: `{"types":["type Catalog_Product { id: ID!\\n name: String! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
19
|
-
protocol: "graphql",
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
let registeredState: ApiFragmentsReadModelSpec.state = {
|
|
23
|
-
pluginId: "p1",
|
|
24
|
-
encoded: fragment1.encoded,
|
|
25
|
-
protocol: fragment1.protocol,
|
|
26
|
-
apiTarget: P.Domain,
|
|
27
|
-
registeredAt: "t0",
|
|
28
|
-
updatedAt: "t0",
|
|
29
|
-
pushStatus: "pending",
|
|
30
|
-
pushMessage: "",
|
|
31
|
-
pushedAt: "",
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
describe("ApiFragments projection", () => {
|
|
35
|
-
test("ApiFragmentRegistered creates the row pending (registeredAt = updatedAt = event `at`)", () =>
|
|
36
|
-
givenEvents([])
|
|
37
|
-
->whenEvent(ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"}))
|
|
38
|
-
->thenStateWithId("p1", registeredState)
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
test("ApiSchemaComputed is ignored (no row change)", () =>
|
|
42
|
-
givenEvents([ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"})])
|
|
43
|
-
->whenEvent(ApiSchemaComputed({snapshot: []}))
|
|
44
|
-
->thenStateWithId("p1", registeredState)
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
test("ApiFragmentPushRecorded(ok) marks the row ok with the push time", () =>
|
|
48
|
-
givenEvents([ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"})])
|
|
49
|
-
->whenEvent(ApiFragmentPushRecorded({pluginId: "p1", ok: true, message: "", at: "t1"}))
|
|
50
|
-
->thenStateWithId("p1", {...registeredState, pushStatus: "ok", pushedAt: "t1"})
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
test("ApiFragmentPushRecorded(error) carries the message", () =>
|
|
54
|
-
givenEvents([ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"})])
|
|
55
|
-
->whenEvent(ApiFragmentPushRecorded({pluginId: "p1", ok: false, message: "stitch failed", at: "t1"}))
|
|
56
|
-
->thenStateWithId(
|
|
57
|
-
"p1",
|
|
58
|
-
{...registeredState, pushStatus: "error", pushMessage: "stitch failed", pushedAt: "t1"},
|
|
59
|
-
)
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
test("ApiFragmentUpdated replaces the fragment and resets the row to pending", () =>
|
|
63
|
-
givenEvents([
|
|
64
|
-
ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"}),
|
|
65
|
-
ApiFragmentPushRecorded({pluginId: "p1", ok: true, message: "", at: "t1"}),
|
|
66
|
-
])
|
|
67
|
-
->whenEvent(
|
|
68
|
-
ApiFragmentUpdated({
|
|
69
|
-
pluginId: "p1",
|
|
70
|
-
previousFragment: fragment1,
|
|
71
|
-
newFragment: fragment2,
|
|
72
|
-
apiTarget: P.Domain,
|
|
73
|
-
at: "t2",
|
|
74
|
-
}),
|
|
75
|
-
)
|
|
76
|
-
->thenStateWithId(
|
|
77
|
-
"p1",
|
|
78
|
-
{
|
|
79
|
-
...registeredState,
|
|
80
|
-
encoded: fragment2.encoded,
|
|
81
|
-
updatedAt: "t2",
|
|
82
|
-
pushStatus: "pending",
|
|
83
|
-
pushMessage: "",
|
|
84
|
-
pushedAt: "t1",
|
|
85
|
-
},
|
|
86
|
-
)
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
test("ApiFragmentUpdated carrying a new target moves the row to that API", () =>
|
|
90
|
-
givenEvents([ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"})])
|
|
91
|
-
->whenEvent(
|
|
92
|
-
ApiFragmentUpdated({
|
|
93
|
-
pluginId: "p1",
|
|
94
|
-
previousFragment: fragment1,
|
|
95
|
-
newFragment: fragment1,
|
|
96
|
-
apiTarget: P.Platform,
|
|
97
|
-
at: "t1",
|
|
98
|
-
}),
|
|
99
|
-
)
|
|
100
|
-
->thenStateWithId("p1", {...registeredState, apiTarget: P.Platform, updatedAt: "t1"})
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
test("ApiFragmentDeregistered removes the row", () =>
|
|
104
|
-
givenEvents([ApiFragmentRegistered({pluginId: "p1", fragment: fragment1, apiTarget: P.Domain, at: "t0"})])
|
|
105
|
-
->whenEvent(ApiFragmentDeregistered({pluginId: "p1"}))
|
|
106
|
-
->thenNoState
|
|
107
|
-
)
|
|
108
|
-
})
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
-
|
|
3
|
-
import * as ApiFragmentsProjection$ReventlessCore from "@reventlessdev/reventless-core/src/admin/ApiFragmentRegistry/ApiFragmentsProjection.res.mjs";
|
|
4
|
-
import * as MultiSourceProjection_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/MultiSourceProjection_GWT.res.mjs";
|
|
5
|
-
|
|
6
|
-
let Test = MultiSourceProjection_GWT$ReventlessGwt.Make(ApiFragmentsProjection$ReventlessCore.ApiFragmentsMapping);
|
|
7
|
-
|
|
8
|
-
let fragment1 = {
|
|
9
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
10
|
-
protocol: "graphql"
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
let fragment2 = {
|
|
14
|
-
encoded: `{"types":["type Catalog_Product { id: ID!\\n name: String! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
15
|
-
protocol: "graphql"
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
let registeredState = {
|
|
19
|
-
pluginId: "p1",
|
|
20
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
21
|
-
protocol: "graphql",
|
|
22
|
-
apiTarget: "Domain",
|
|
23
|
-
registeredAt: "t0",
|
|
24
|
-
updatedAt: "t0",
|
|
25
|
-
pushStatus: "pending",
|
|
26
|
-
pushMessage: "",
|
|
27
|
-
pushedAt: ""
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
Test.describe("ApiFragments projection", () => {
|
|
31
|
-
Test.test("ApiFragmentRegistered creates the row pending (registeredAt = updatedAt = event `at`)", undefined, () => Test.thenStateWithId(Test.whenEvent(Test.givenEvents([]), {
|
|
32
|
-
TAG: "ApiFragmentRegistered",
|
|
33
|
-
pluginId: "p1",
|
|
34
|
-
fragment: fragment1,
|
|
35
|
-
apiTarget: "Domain",
|
|
36
|
-
at: "t0"
|
|
37
|
-
}), "p1", registeredState));
|
|
38
|
-
Test.test("ApiSchemaComputed is ignored (no row change)", undefined, () => Test.thenStateWithId(Test.whenEvent(Test.givenEvents([{
|
|
39
|
-
TAG: "ApiFragmentRegistered",
|
|
40
|
-
pluginId: "p1",
|
|
41
|
-
fragment: fragment1,
|
|
42
|
-
apiTarget: "Domain",
|
|
43
|
-
at: "t0"
|
|
44
|
-
}]), {
|
|
45
|
-
TAG: "ApiSchemaComputed",
|
|
46
|
-
snapshot: []
|
|
47
|
-
}), "p1", registeredState));
|
|
48
|
-
Test.test("ApiFragmentPushRecorded(ok) marks the row ok with the push time", undefined, () => Test.thenStateWithId(Test.whenEvent(Test.givenEvents([{
|
|
49
|
-
TAG: "ApiFragmentRegistered",
|
|
50
|
-
pluginId: "p1",
|
|
51
|
-
fragment: fragment1,
|
|
52
|
-
apiTarget: "Domain",
|
|
53
|
-
at: "t0"
|
|
54
|
-
}]), {
|
|
55
|
-
TAG: "ApiFragmentPushRecorded",
|
|
56
|
-
pluginId: "p1",
|
|
57
|
-
ok: true,
|
|
58
|
-
message: "",
|
|
59
|
-
at: "t1"
|
|
60
|
-
}), "p1", {
|
|
61
|
-
pluginId: "p1",
|
|
62
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
63
|
-
protocol: "graphql",
|
|
64
|
-
apiTarget: "Domain",
|
|
65
|
-
registeredAt: "t0",
|
|
66
|
-
updatedAt: "t0",
|
|
67
|
-
pushStatus: "ok",
|
|
68
|
-
pushMessage: "",
|
|
69
|
-
pushedAt: "t1"
|
|
70
|
-
}));
|
|
71
|
-
Test.test("ApiFragmentPushRecorded(error) carries the message", undefined, () => Test.thenStateWithId(Test.whenEvent(Test.givenEvents([{
|
|
72
|
-
TAG: "ApiFragmentRegistered",
|
|
73
|
-
pluginId: "p1",
|
|
74
|
-
fragment: fragment1,
|
|
75
|
-
apiTarget: "Domain",
|
|
76
|
-
at: "t0"
|
|
77
|
-
}]), {
|
|
78
|
-
TAG: "ApiFragmentPushRecorded",
|
|
79
|
-
pluginId: "p1",
|
|
80
|
-
ok: false,
|
|
81
|
-
message: "stitch failed",
|
|
82
|
-
at: "t1"
|
|
83
|
-
}), "p1", {
|
|
84
|
-
pluginId: "p1",
|
|
85
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
86
|
-
protocol: "graphql",
|
|
87
|
-
apiTarget: "Domain",
|
|
88
|
-
registeredAt: "t0",
|
|
89
|
-
updatedAt: "t0",
|
|
90
|
-
pushStatus: "error",
|
|
91
|
-
pushMessage: "stitch failed",
|
|
92
|
-
pushedAt: "t1"
|
|
93
|
-
}));
|
|
94
|
-
Test.test("ApiFragmentUpdated replaces the fragment and resets the row to pending", undefined, () => Test.thenStateWithId(Test.whenEvent(Test.givenEvents([
|
|
95
|
-
{
|
|
96
|
-
TAG: "ApiFragmentRegistered",
|
|
97
|
-
pluginId: "p1",
|
|
98
|
-
fragment: fragment1,
|
|
99
|
-
apiTarget: "Domain",
|
|
100
|
-
at: "t0"
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
TAG: "ApiFragmentPushRecorded",
|
|
104
|
-
pluginId: "p1",
|
|
105
|
-
ok: true,
|
|
106
|
-
message: "",
|
|
107
|
-
at: "t1"
|
|
108
|
-
}
|
|
109
|
-
]), {
|
|
110
|
-
TAG: "ApiFragmentUpdated",
|
|
111
|
-
pluginId: "p1",
|
|
112
|
-
previousFragment: fragment1,
|
|
113
|
-
newFragment: fragment2,
|
|
114
|
-
apiTarget: "Domain",
|
|
115
|
-
at: "t2"
|
|
116
|
-
}), "p1", {
|
|
117
|
-
pluginId: "p1",
|
|
118
|
-
encoded: `{"types":["type Catalog_Product { id: ID!\\n name: String! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
119
|
-
protocol: "graphql",
|
|
120
|
-
apiTarget: "Domain",
|
|
121
|
-
registeredAt: "t0",
|
|
122
|
-
updatedAt: "t2",
|
|
123
|
-
pushStatus: "pending",
|
|
124
|
-
pushMessage: "",
|
|
125
|
-
pushedAt: "t1"
|
|
126
|
-
}));
|
|
127
|
-
Test.test("ApiFragmentUpdated carrying a new target moves the row to that API", undefined, () => Test.thenStateWithId(Test.whenEvent(Test.givenEvents([{
|
|
128
|
-
TAG: "ApiFragmentRegistered",
|
|
129
|
-
pluginId: "p1",
|
|
130
|
-
fragment: fragment1,
|
|
131
|
-
apiTarget: "Domain",
|
|
132
|
-
at: "t0"
|
|
133
|
-
}]), {
|
|
134
|
-
TAG: "ApiFragmentUpdated",
|
|
135
|
-
pluginId: "p1",
|
|
136
|
-
previousFragment: fragment1,
|
|
137
|
-
newFragment: fragment1,
|
|
138
|
-
apiTarget: "Platform",
|
|
139
|
-
at: "t1"
|
|
140
|
-
}), "p1", {
|
|
141
|
-
pluginId: "p1",
|
|
142
|
-
encoded: `{"types":["type Catalog_Product { id: ID! }"],"mutations":[],"queries":[],"subscriptions":[],"subscriptionSources":[]}`,
|
|
143
|
-
protocol: "graphql",
|
|
144
|
-
apiTarget: "Platform",
|
|
145
|
-
registeredAt: "t0",
|
|
146
|
-
updatedAt: "t1",
|
|
147
|
-
pushStatus: "pending",
|
|
148
|
-
pushMessage: "",
|
|
149
|
-
pushedAt: ""
|
|
150
|
-
}));
|
|
151
|
-
Test.test("ApiFragmentDeregistered removes the row", undefined, () => Test.thenNoState(Test.whenEvent(Test.givenEvents([{
|
|
152
|
-
TAG: "ApiFragmentRegistered",
|
|
153
|
-
pluginId: "p1",
|
|
154
|
-
fragment: fragment1,
|
|
155
|
-
apiTarget: "Domain",
|
|
156
|
-
at: "t0"
|
|
157
|
-
}]), {
|
|
158
|
-
TAG: "ApiFragmentDeregistered",
|
|
159
|
-
pluginId: "p1"
|
|
160
|
-
})));
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
let P;
|
|
164
|
-
|
|
165
|
-
export {
|
|
166
|
-
P,
|
|
167
|
-
Test,
|
|
168
|
-
fragment1,
|
|
169
|
-
fragment2,
|
|
170
|
-
registeredState,
|
|
171
|
-
}
|
|
172
|
-
/* Test Not a pure module */
|