@graffiti-garden/api 0.4.4 → 0.6.0
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 +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +3 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +3 -3
- package/dist/src/1-api.d.ts +95 -121
- package/dist/src/1-api.d.ts.map +1 -1
- package/dist/src/2-types.d.ts +66 -70
- package/dist/src/2-types.d.ts.map +1 -1
- package/dist/src/3-errors.d.ts +3 -0
- package/dist/src/3-errors.d.ts.map +1 -1
- package/dist/tests/crud.d.ts.map +1 -1
- package/dist/tests/discover.d.ts.map +1 -1
- package/dist/tests/index.d.ts +0 -1
- package/dist/tests/index.d.ts.map +1 -1
- package/dist/tests/orphans.d.ts.map +1 -1
- package/dist/tests/utils.d.ts +1 -1
- package/dist/tests/utils.d.ts.map +1 -1
- package/dist/tests.mjs +336 -286
- package/dist/tests.mjs.map +4 -4
- package/package.json +1 -1
- package/src/1-api.ts +99 -132
- package/src/2-types.ts +63 -70
- package/src/3-errors.ts +8 -0
- package/tests/crud.ts +58 -27
- package/tests/discover.ts +97 -48
- package/tests/index.ts +0 -1
- package/tests/orphans.ts +41 -10
- package/tests/utils.ts +2 -1
- package/dist/tests/location.d.ts +0 -3
- package/dist/tests/location.d.ts.map +0 -1
- package/tests/location.ts +0 -42
package/dist/tests.mjs
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
// tests/
|
|
2
|
-
import { it, expect, describe } from "vitest";
|
|
3
|
-
import {
|
|
1
|
+
// tests/crud.ts
|
|
2
|
+
import { it, expect, describe, beforeAll } from "vitest";
|
|
3
|
+
import {
|
|
4
|
+
GraffitiErrorNotFound,
|
|
5
|
+
GraffitiErrorSchemaMismatch,
|
|
6
|
+
GraffitiErrorInvalidSchema,
|
|
7
|
+
GraffitiErrorForbidden,
|
|
8
|
+
GraffitiErrorPatchTestFailed,
|
|
9
|
+
GraffitiErrorPatchError
|
|
10
|
+
} from "@graffiti-garden/api";
|
|
4
11
|
|
|
5
12
|
// tests/utils.ts
|
|
6
13
|
import { assert } from "vitest";
|
|
@@ -24,56 +31,13 @@ function randomPutObject() {
|
|
|
24
31
|
async function nextStreamValue(iterator) {
|
|
25
32
|
const result = await iterator.next();
|
|
26
33
|
assert(!result.done && !result.value.error, "result has no value");
|
|
34
|
+
assert(!result.value.tombstone, "result has been deleted!");
|
|
27
35
|
return result.value.value;
|
|
28
36
|
}
|
|
29
37
|
|
|
30
|
-
// tests/location.ts
|
|
31
|
-
var graffitiLocationTests = (useGraffiti) => {
|
|
32
|
-
describe.concurrent("URI and location conversion", () => {
|
|
33
|
-
it("location to uri and back", async () => {
|
|
34
|
-
const graffiti = useGraffiti();
|
|
35
|
-
const location = {
|
|
36
|
-
name: randomString(),
|
|
37
|
-
actor: randomString(),
|
|
38
|
-
source: randomString()
|
|
39
|
-
};
|
|
40
|
-
const uri = graffiti.locationToUri(location);
|
|
41
|
-
const location2 = graffiti.uriToLocation(uri);
|
|
42
|
-
expect(location).toEqual(location2);
|
|
43
|
-
});
|
|
44
|
-
it("collision resistance", async () => {
|
|
45
|
-
const graffiti = useGraffiti();
|
|
46
|
-
const location1 = {
|
|
47
|
-
name: randomString(),
|
|
48
|
-
actor: randomString(),
|
|
49
|
-
source: randomString()
|
|
50
|
-
};
|
|
51
|
-
for (const prop of ["name", "actor", "source"]) {
|
|
52
|
-
const location2 = { ...location1, [prop]: randomString() };
|
|
53
|
-
const uri1 = graffiti.locationToUri(location1);
|
|
54
|
-
const uri2 = graffiti.locationToUri(location2);
|
|
55
|
-
expect(uri1).not.toEqual(uri2);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
it("random URI should not be a valid location", async () => {
|
|
59
|
-
const graffiti = useGraffiti();
|
|
60
|
-
expect(() => graffiti.uriToLocation("")).toThrow(GraffitiErrorInvalidUri);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
};
|
|
64
|
-
|
|
65
38
|
// tests/crud.ts
|
|
66
|
-
import { it as it2, expect as expect2, describe as describe2, beforeAll } from "vitest";
|
|
67
|
-
import {
|
|
68
|
-
GraffitiErrorNotFound,
|
|
69
|
-
GraffitiErrorSchemaMismatch,
|
|
70
|
-
GraffitiErrorInvalidSchema,
|
|
71
|
-
GraffitiErrorForbidden,
|
|
72
|
-
GraffitiErrorPatchTestFailed,
|
|
73
|
-
GraffitiErrorPatchError
|
|
74
|
-
} from "@graffiti-garden/api";
|
|
75
39
|
var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
76
|
-
|
|
40
|
+
describe.concurrent(
|
|
77
41
|
"CRUD",
|
|
78
42
|
{
|
|
79
43
|
timeout: 2e4
|
|
@@ -89,66 +53,57 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
89
53
|
session = session1;
|
|
90
54
|
session2 = await useSession2();
|
|
91
55
|
});
|
|
92
|
-
|
|
56
|
+
it("put, get, delete", async () => {
|
|
93
57
|
const value = {
|
|
94
58
|
something: "hello, world~ c:"
|
|
95
59
|
};
|
|
96
60
|
const channels = [randomString(), randomString()];
|
|
97
61
|
const previous = await graffiti.put({ value, channels }, session);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
62
|
+
expect(previous.value).toEqual({});
|
|
63
|
+
expect(previous.channels).toEqual([]);
|
|
64
|
+
expect(previous.allowed).toEqual([]);
|
|
65
|
+
expect(previous.actor).toEqual(session.actor);
|
|
102
66
|
const gotten = await graffiti.get(previous, {});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
expect2(gotten.lastModified).toEqual(previous.lastModified);
|
|
67
|
+
expect(gotten.value).toEqual(value);
|
|
68
|
+
expect(gotten.channels).toEqual([]);
|
|
69
|
+
expect(gotten.allowed).toBeUndefined();
|
|
70
|
+
expect(gotten.url).toEqual(previous.url);
|
|
71
|
+
expect(gotten.actor).toEqual(previous.actor);
|
|
72
|
+
expect(gotten.lastModified).toEqual(previous.lastModified);
|
|
110
73
|
const newValue = {
|
|
111
74
|
something: "goodbye, world~ :c"
|
|
112
75
|
};
|
|
113
76
|
const beforeReplaced = await graffiti.put(
|
|
114
|
-
{
|
|
77
|
+
{
|
|
78
|
+
url: previous.url,
|
|
79
|
+
value: newValue,
|
|
80
|
+
channels: []
|
|
81
|
+
},
|
|
115
82
|
session
|
|
116
83
|
);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
expect2(beforeReplaced.source).toEqual(previous.source);
|
|
122
|
-
expect2(beforeReplaced.lastModified).toBeGreaterThanOrEqual(
|
|
84
|
+
expect(beforeReplaced.value).toEqual(value);
|
|
85
|
+
expect(beforeReplaced.url).toEqual(previous.url);
|
|
86
|
+
expect(beforeReplaced.actor).toEqual(previous.actor);
|
|
87
|
+
expect(beforeReplaced.lastModified).toBeGreaterThanOrEqual(
|
|
123
88
|
gotten.lastModified
|
|
124
89
|
);
|
|
125
90
|
const afterReplaced = await graffiti.get(previous, {});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
expect2(afterReplaced.tombstone).toEqual(false);
|
|
91
|
+
expect(afterReplaced.value).toEqual(newValue);
|
|
92
|
+
expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified);
|
|
129
93
|
const beforeDeleted = await graffiti.delete(afterReplaced, session);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
expect2(beforeDeleted.lastModified).toBeGreaterThanOrEqual(
|
|
94
|
+
expect(beforeDeleted.value).toEqual(newValue);
|
|
95
|
+
expect(beforeDeleted.lastModified).toBeGreaterThanOrEqual(
|
|
133
96
|
beforeReplaced.lastModified
|
|
134
97
|
);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
graffiti.get(
|
|
142
|
-
{
|
|
143
|
-
...putted,
|
|
144
|
-
name: randomString()
|
|
145
|
-
},
|
|
146
|
-
{}
|
|
147
|
-
)
|
|
148
|
-
).rejects.toBeInstanceOf(GraffitiErrorNotFound);
|
|
98
|
+
await expect(graffiti.get(afterReplaced, {})).rejects.toBeInstanceOf(
|
|
99
|
+
GraffitiErrorNotFound
|
|
100
|
+
);
|
|
101
|
+
await expect(graffiti.delete(beforeDeleted, session)).rejects.toThrow(
|
|
102
|
+
GraffitiErrorNotFound
|
|
103
|
+
);
|
|
149
104
|
});
|
|
150
|
-
|
|
151
|
-
await
|
|
105
|
+
it("put, delete, patch with wrong actor", async () => {
|
|
106
|
+
await expect(
|
|
152
107
|
graffiti.put(
|
|
153
108
|
{ value: {}, channels: [], actor: session2.actor },
|
|
154
109
|
session1
|
|
@@ -158,14 +113,50 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
158
113
|
{ value: {}, channels: [] },
|
|
159
114
|
session2
|
|
160
115
|
);
|
|
161
|
-
await
|
|
116
|
+
await expect(
|
|
117
|
+
graffiti.put(
|
|
118
|
+
{
|
|
119
|
+
url: putted.url,
|
|
120
|
+
value: {},
|
|
121
|
+
channels: []
|
|
122
|
+
},
|
|
123
|
+
session1
|
|
124
|
+
)
|
|
125
|
+
).rejects.toThrow(GraffitiErrorForbidden);
|
|
126
|
+
await expect(graffiti.delete(putted, session1)).rejects.toThrow(
|
|
162
127
|
GraffitiErrorForbidden
|
|
163
128
|
);
|
|
164
|
-
await
|
|
129
|
+
await expect(graffiti.patch({}, putted, session1)).rejects.toThrow(
|
|
165
130
|
GraffitiErrorForbidden
|
|
166
131
|
);
|
|
167
132
|
});
|
|
168
|
-
|
|
133
|
+
it("put, patch, delete object that is not allowed", async () => {
|
|
134
|
+
const putted = await graffiti.put(
|
|
135
|
+
{
|
|
136
|
+
value: {},
|
|
137
|
+
channels: [],
|
|
138
|
+
allowed: []
|
|
139
|
+
},
|
|
140
|
+
session1
|
|
141
|
+
);
|
|
142
|
+
await expect(
|
|
143
|
+
graffiti.put(
|
|
144
|
+
{
|
|
145
|
+
url: putted.url,
|
|
146
|
+
value: {},
|
|
147
|
+
channels: []
|
|
148
|
+
},
|
|
149
|
+
session2
|
|
150
|
+
)
|
|
151
|
+
).rejects.toThrow(GraffitiErrorNotFound);
|
|
152
|
+
await expect(graffiti.patch({}, putted, session2)).rejects.toThrow(
|
|
153
|
+
GraffitiErrorNotFound
|
|
154
|
+
);
|
|
155
|
+
await expect(graffiti.delete(putted, session2)).rejects.toThrow(
|
|
156
|
+
GraffitiErrorNotFound
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
it("put and get with schema", async () => {
|
|
169
160
|
const schema = {
|
|
170
161
|
properties: {
|
|
171
162
|
value: {
|
|
@@ -208,17 +199,17 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
208
199
|
session
|
|
209
200
|
);
|
|
210
201
|
const gotten = await graffiti.get(putted, schema);
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
202
|
+
expect(gotten.value.something).toEqual(goodValue.something);
|
|
203
|
+
expect(gotten.value.another).toEqual(goodValue.another);
|
|
204
|
+
expect(gotten.value.another[0]).toEqual(1);
|
|
205
|
+
expect(gotten.value.deeper.deepProp).toEqual(goodValue.deeper.deepProp);
|
|
215
206
|
});
|
|
216
|
-
|
|
207
|
+
it("put and get with invalid schema", async () => {
|
|
217
208
|
const putted = await graffiti.put(
|
|
218
209
|
{ value: {}, channels: [] },
|
|
219
210
|
session
|
|
220
211
|
);
|
|
221
|
-
await
|
|
212
|
+
await expect(
|
|
222
213
|
graffiti.get(putted, {
|
|
223
214
|
properties: {
|
|
224
215
|
value: {
|
|
@@ -229,7 +220,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
229
220
|
})
|
|
230
221
|
).rejects.toThrow(GraffitiErrorInvalidSchema);
|
|
231
222
|
});
|
|
232
|
-
|
|
223
|
+
it("put and get with wrong schema", async () => {
|
|
233
224
|
const putted = await graffiti.put(
|
|
234
225
|
{
|
|
235
226
|
value: {
|
|
@@ -239,7 +230,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
239
230
|
},
|
|
240
231
|
session
|
|
241
232
|
);
|
|
242
|
-
await
|
|
233
|
+
await expect(
|
|
243
234
|
graffiti.get(putted, {
|
|
244
235
|
properties: {
|
|
245
236
|
value: {
|
|
@@ -253,7 +244,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
253
244
|
})
|
|
254
245
|
).rejects.toThrow(GraffitiErrorSchemaMismatch);
|
|
255
246
|
});
|
|
256
|
-
|
|
247
|
+
it("put and get with empty access control", async () => {
|
|
257
248
|
const value = {
|
|
258
249
|
um: "hi"
|
|
259
250
|
};
|
|
@@ -264,17 +255,17 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
264
255
|
session1
|
|
265
256
|
);
|
|
266
257
|
const gotten = await graffiti.get(putted, {}, session1);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
await
|
|
258
|
+
expect(gotten.value).toEqual(value);
|
|
259
|
+
expect(gotten.allowed).toEqual(allowed);
|
|
260
|
+
expect(gotten.channels).toEqual(channels);
|
|
261
|
+
await expect(graffiti.get(putted, {})).rejects.toBeInstanceOf(
|
|
271
262
|
GraffitiErrorNotFound
|
|
272
263
|
);
|
|
273
|
-
await
|
|
264
|
+
await expect(graffiti.get(putted, {}, session2)).rejects.toBeInstanceOf(
|
|
274
265
|
GraffitiErrorNotFound
|
|
275
266
|
);
|
|
276
267
|
});
|
|
277
|
-
|
|
268
|
+
it("put and get with specific access control", async () => {
|
|
278
269
|
const value = {
|
|
279
270
|
um: "hi"
|
|
280
271
|
};
|
|
@@ -289,18 +280,18 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
289
280
|
session1
|
|
290
281
|
);
|
|
291
282
|
const gotten = await graffiti.get(putted, {}, session1);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
await
|
|
283
|
+
expect(gotten.value).toEqual(value);
|
|
284
|
+
expect(gotten.allowed).toEqual(allowed);
|
|
285
|
+
expect(gotten.channels).toEqual(channels);
|
|
286
|
+
await expect(graffiti.get(putted, {})).rejects.toBeInstanceOf(
|
|
296
287
|
GraffitiErrorNotFound
|
|
297
288
|
);
|
|
298
289
|
const gotten2 = await graffiti.get(putted, {}, session2);
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
290
|
+
expect(gotten2.value).toEqual(value);
|
|
291
|
+
expect(gotten2.allowed).toEqual([session2.actor]);
|
|
292
|
+
expect(gotten2.channels).toEqual([]);
|
|
302
293
|
});
|
|
303
|
-
|
|
294
|
+
it("patch value", async () => {
|
|
304
295
|
const value = {
|
|
305
296
|
something: "hello, world~ c:"
|
|
306
297
|
};
|
|
@@ -312,24 +303,23 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
312
303
|
]
|
|
313
304
|
};
|
|
314
305
|
const beforePatched = await graffiti.patch(patch, putted, session);
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
expect2(beforePatched.lastModified).toBeGreaterThan(putted.lastModified);
|
|
306
|
+
expect(beforePatched.value).toEqual(value);
|
|
307
|
+
expect(beforePatched.lastModified).toBeGreaterThan(putted.lastModified);
|
|
318
308
|
const gotten = await graffiti.get(putted, {});
|
|
319
|
-
|
|
309
|
+
expect(gotten.value).toEqual({
|
|
320
310
|
something: "goodbye, world~ :c"
|
|
321
311
|
});
|
|
322
|
-
|
|
312
|
+
expect(beforePatched.lastModified).toBe(gotten.lastModified);
|
|
323
313
|
await graffiti.delete(putted, session);
|
|
324
314
|
});
|
|
325
|
-
|
|
315
|
+
it("patch deleted object", async () => {
|
|
326
316
|
const putted = await graffiti.put(randomPutObject(), session);
|
|
327
317
|
const deleted = await graffiti.delete(putted, session);
|
|
328
|
-
await
|
|
318
|
+
await expect(
|
|
329
319
|
graffiti.patch({}, putted, session)
|
|
330
320
|
).rejects.toBeInstanceOf(GraffitiErrorNotFound);
|
|
331
321
|
});
|
|
332
|
-
|
|
322
|
+
it("deep patch", async () => {
|
|
333
323
|
const value = {
|
|
334
324
|
something: {
|
|
335
325
|
another: {
|
|
@@ -355,8 +345,8 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
355
345
|
session
|
|
356
346
|
);
|
|
357
347
|
const gotten = await graffiti.get(putted, {});
|
|
358
|
-
|
|
359
|
-
|
|
348
|
+
expect(beforePatch.value).toEqual(value);
|
|
349
|
+
expect(gotten.value).toEqual({
|
|
360
350
|
something: {
|
|
361
351
|
another: {
|
|
362
352
|
somethingElse: "goodbye"
|
|
@@ -364,7 +354,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
364
354
|
}
|
|
365
355
|
});
|
|
366
356
|
});
|
|
367
|
-
|
|
357
|
+
it("patch channels", async () => {
|
|
368
358
|
const channelsBefore = [randomString()];
|
|
369
359
|
const channelsAfter = [randomString()];
|
|
370
360
|
const putted = await graffiti.put(
|
|
@@ -375,12 +365,12 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
375
365
|
channels: [{ op: "replace", path: "/0", value: channelsAfter[0] }]
|
|
376
366
|
};
|
|
377
367
|
const patched = await graffiti.patch(patch, putted, session);
|
|
378
|
-
|
|
368
|
+
expect(patched.channels).toEqual(channelsBefore);
|
|
379
369
|
const gotten = await graffiti.get(putted, {}, session);
|
|
380
|
-
|
|
370
|
+
expect(gotten.channels).toEqual(channelsAfter);
|
|
381
371
|
await graffiti.delete(putted, session);
|
|
382
372
|
});
|
|
383
|
-
|
|
373
|
+
it("patch 'increment' with test", async () => {
|
|
384
374
|
const putted = await graffiti.put(
|
|
385
375
|
{
|
|
386
376
|
value: {
|
|
@@ -400,7 +390,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
400
390
|
putted,
|
|
401
391
|
session
|
|
402
392
|
);
|
|
403
|
-
|
|
393
|
+
expect(previous.value).toEqual({ counter: 1 });
|
|
404
394
|
const result = await graffiti.get(previous, {
|
|
405
395
|
properties: {
|
|
406
396
|
value: {
|
|
@@ -412,8 +402,8 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
412
402
|
}
|
|
413
403
|
}
|
|
414
404
|
});
|
|
415
|
-
|
|
416
|
-
await
|
|
405
|
+
expect(result.value.counter).toEqual(2);
|
|
406
|
+
await expect(
|
|
417
407
|
graffiti.patch(
|
|
418
408
|
{
|
|
419
409
|
value: [
|
|
@@ -426,10 +416,10 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
426
416
|
)
|
|
427
417
|
).rejects.toThrow(GraffitiErrorPatchTestFailed);
|
|
428
418
|
});
|
|
429
|
-
|
|
419
|
+
it("invalid patch", async () => {
|
|
430
420
|
const object = randomPutObject();
|
|
431
421
|
const putted = await graffiti.put(object, session);
|
|
432
|
-
await
|
|
422
|
+
await expect(
|
|
433
423
|
graffiti.patch(
|
|
434
424
|
{
|
|
435
425
|
value: [
|
|
@@ -443,7 +433,7 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
443
433
|
)
|
|
444
434
|
).rejects.toThrow(GraffitiErrorPatchError);
|
|
445
435
|
});
|
|
446
|
-
|
|
436
|
+
it("patch channels to be wrong", async () => {
|
|
447
437
|
const object = randomPutObject();
|
|
448
438
|
object.allowed = [randomString()];
|
|
449
439
|
const putted = await graffiti.put(object, session);
|
|
@@ -477,24 +467,24 @@ var graffitiCRUDTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
477
467
|
}
|
|
478
468
|
];
|
|
479
469
|
for (const patch of patches) {
|
|
480
|
-
await
|
|
470
|
+
await expect(graffiti.patch(patch, putted, session)).rejects.toThrow(
|
|
481
471
|
GraffitiErrorPatchError
|
|
482
472
|
);
|
|
483
473
|
}
|
|
484
474
|
const gotten = await graffiti.get(putted, {}, session);
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
475
|
+
expect(gotten.value).toEqual(object.value);
|
|
476
|
+
expect(gotten.channels).toEqual(object.channels);
|
|
477
|
+
expect(gotten.allowed).toEqual(object.allowed);
|
|
478
|
+
expect(gotten.lastModified).toEqual(putted.lastModified);
|
|
489
479
|
});
|
|
490
480
|
}
|
|
491
481
|
);
|
|
492
482
|
};
|
|
493
483
|
|
|
494
484
|
// tests/discover.ts
|
|
495
|
-
import { it as
|
|
485
|
+
import { it as it2, expect as expect2, describe as describe2, assert as assert2, beforeAll as beforeAll2 } from "vitest";
|
|
496
486
|
var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
497
|
-
|
|
487
|
+
describe2.concurrent("discover", { timeout: 2e4 }, () => {
|
|
498
488
|
let graffiti;
|
|
499
489
|
let session;
|
|
500
490
|
let session1;
|
|
@@ -505,63 +495,60 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
505
495
|
session = session1;
|
|
506
496
|
session2 = await useSession2();
|
|
507
497
|
});
|
|
508
|
-
|
|
498
|
+
it2("discover nothing", async () => {
|
|
509
499
|
const iterator = graffiti.discover([], {});
|
|
510
|
-
|
|
500
|
+
expect2(await iterator.next()).toHaveProperty("done", true);
|
|
511
501
|
});
|
|
512
|
-
|
|
502
|
+
it2("discover single", async () => {
|
|
513
503
|
const object = randomPutObject();
|
|
514
504
|
const putted = await graffiti.put(object, session);
|
|
515
505
|
const queryChannels = [randomString(), object.channels[0]];
|
|
516
506
|
const iterator = graffiti.discover(queryChannels, {});
|
|
517
507
|
const value = await nextStreamValue(iterator);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
expect3(value.lastModified).toEqual(putted.lastModified);
|
|
508
|
+
expect2(value.value).toEqual(object.value);
|
|
509
|
+
expect2(value.channels).toEqual([object.channels[0]]);
|
|
510
|
+
expect2(value.allowed).toBeUndefined();
|
|
511
|
+
expect2(value.actor).toEqual(session.actor);
|
|
512
|
+
expect2(value.lastModified).toEqual(putted.lastModified);
|
|
524
513
|
const result2 = await iterator.next();
|
|
525
|
-
|
|
514
|
+
expect2(result2.done).toBe(true);
|
|
526
515
|
});
|
|
527
|
-
|
|
516
|
+
it2("discover wrong channel", async () => {
|
|
528
517
|
const object = randomPutObject();
|
|
529
518
|
await graffiti.put(object, session);
|
|
530
519
|
const iterator = graffiti.discover([randomString()], {});
|
|
531
|
-
await
|
|
520
|
+
await expect2(iterator.next()).resolves.toHaveProperty("done", true);
|
|
532
521
|
});
|
|
533
|
-
|
|
522
|
+
it2("discover not allowed", async () => {
|
|
534
523
|
const object = randomPutObject();
|
|
535
524
|
object.allowed = [randomString(), randomString()];
|
|
536
525
|
const putted = await graffiti.put(object, session1);
|
|
537
526
|
const iteratorSession1 = graffiti.discover(object.channels, {}, session1);
|
|
538
527
|
const value = await nextStreamValue(iteratorSession1);
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
expect3(value.lastModified).toEqual(putted.lastModified);
|
|
528
|
+
expect2(value.value).toEqual(object.value);
|
|
529
|
+
expect2(value.channels).toEqual(object.channels);
|
|
530
|
+
expect2(value.allowed).toEqual(object.allowed);
|
|
531
|
+
expect2(value.actor).toEqual(session1.actor);
|
|
532
|
+
expect2(value.lastModified).toEqual(putted.lastModified);
|
|
545
533
|
const iteratorSession2 = graffiti.discover(object.channels, {}, session2);
|
|
546
|
-
|
|
534
|
+
expect2(await iteratorSession2.next()).toHaveProperty("done", true);
|
|
547
535
|
const iteratorNoSession = graffiti.discover(object.channels, {});
|
|
548
|
-
|
|
536
|
+
expect2(await iteratorNoSession.next()).toHaveProperty("done", true);
|
|
549
537
|
});
|
|
550
|
-
|
|
538
|
+
it2("discover allowed", async () => {
|
|
551
539
|
const object = randomPutObject();
|
|
552
540
|
object.allowed = [randomString(), session2.actor, randomString()];
|
|
553
541
|
const putted = await graffiti.put(object, session1);
|
|
554
542
|
const iteratorSession2 = graffiti.discover(object.channels, {}, session2);
|
|
555
543
|
const value = await nextStreamValue(iteratorSession2);
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
expect3(value.lastModified).toEqual(putted.lastModified);
|
|
544
|
+
expect2(value.value).toEqual(object.value);
|
|
545
|
+
expect2(value.allowed).toEqual([session2.actor]);
|
|
546
|
+
expect2(value.channels).toEqual(object.channels);
|
|
547
|
+
expect2(value.actor).toEqual(session1.actor);
|
|
548
|
+
expect2(value.lastModified).toEqual(putted.lastModified);
|
|
562
549
|
});
|
|
563
|
-
for (const prop of ["
|
|
564
|
-
|
|
550
|
+
for (const prop of ["actor", "lastModified"]) {
|
|
551
|
+
it2(`discover for ${prop}`, async () => {
|
|
565
552
|
const object1 = randomPutObject();
|
|
566
553
|
const putted1 = await graffiti.put(object1, session1);
|
|
567
554
|
const object2 = randomPutObject();
|
|
@@ -576,19 +563,19 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
576
563
|
}
|
|
577
564
|
});
|
|
578
565
|
const value = await nextStreamValue(iterator);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
await
|
|
566
|
+
expect2(value.url).toEqual(putted1.url);
|
|
567
|
+
expect2(value.url).not.toEqual(putted2.url);
|
|
568
|
+
expect2(value.value).toEqual(object1.value);
|
|
569
|
+
await expect2(iterator.next()).resolves.toHaveProperty("done", true);
|
|
583
570
|
});
|
|
584
571
|
}
|
|
585
|
-
|
|
572
|
+
it2("discover with lastModified range", async () => {
|
|
586
573
|
const object = randomPutObject();
|
|
587
574
|
const putted1 = await graffiti.put(object, session);
|
|
588
575
|
await new Promise((r) => setTimeout(r, 20));
|
|
589
576
|
const putted2 = await graffiti.put(object, session);
|
|
590
|
-
|
|
591
|
-
|
|
577
|
+
expect2(putted1.url).not.toEqual(putted2.url);
|
|
578
|
+
expect2(putted1.lastModified).toBeLessThan(putted2.lastModified);
|
|
592
579
|
const gtIterator = graffiti.discover([object.channels[0]], {
|
|
593
580
|
properties: {
|
|
594
581
|
lastModified: {
|
|
@@ -596,7 +583,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
596
583
|
}
|
|
597
584
|
}
|
|
598
585
|
});
|
|
599
|
-
|
|
586
|
+
expect2(await gtIterator.next()).toHaveProperty("done", true);
|
|
600
587
|
const gtIteratorEpsilon = graffiti.discover([object.channels[0]], {
|
|
601
588
|
properties: {
|
|
602
589
|
lastModified: {
|
|
@@ -605,8 +592,8 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
605
592
|
}
|
|
606
593
|
});
|
|
607
594
|
const value1 = await nextStreamValue(gtIteratorEpsilon);
|
|
608
|
-
|
|
609
|
-
|
|
595
|
+
expect2(value1.url).toEqual(putted2.url);
|
|
596
|
+
expect2(await gtIteratorEpsilon.next()).toHaveProperty("done", true);
|
|
610
597
|
const gteIterator = graffiti.discover(object.channels, {
|
|
611
598
|
properties: {
|
|
612
599
|
value: {},
|
|
@@ -616,8 +603,8 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
616
603
|
}
|
|
617
604
|
});
|
|
618
605
|
const value = await nextStreamValue(gteIterator);
|
|
619
|
-
|
|
620
|
-
|
|
606
|
+
expect2(value.url).toEqual(putted2.url);
|
|
607
|
+
expect2(await gteIterator.next()).toHaveProperty("done", true);
|
|
621
608
|
const gteIteratorEpsilon = graffiti.discover(object.channels, {
|
|
622
609
|
properties: {
|
|
623
610
|
lastModified: {
|
|
@@ -625,7 +612,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
625
612
|
}
|
|
626
613
|
}
|
|
627
614
|
});
|
|
628
|
-
|
|
615
|
+
expect2(await gteIteratorEpsilon.next()).toHaveProperty("done", true);
|
|
629
616
|
const ltIterator = graffiti.discover(object.channels, {
|
|
630
617
|
properties: {
|
|
631
618
|
lastModified: {
|
|
@@ -633,7 +620,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
633
620
|
}
|
|
634
621
|
}
|
|
635
622
|
});
|
|
636
|
-
|
|
623
|
+
expect2(await ltIterator.next()).toHaveProperty("done", true);
|
|
637
624
|
const ltIteratorEpsilon = graffiti.discover(object.channels, {
|
|
638
625
|
properties: {
|
|
639
626
|
lastModified: {
|
|
@@ -642,8 +629,8 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
642
629
|
}
|
|
643
630
|
});
|
|
644
631
|
const value3 = await nextStreamValue(ltIteratorEpsilon);
|
|
645
|
-
|
|
646
|
-
|
|
632
|
+
expect2(value3.url).toEqual(putted1.url);
|
|
633
|
+
expect2(await ltIteratorEpsilon.next()).toHaveProperty("done", true);
|
|
647
634
|
const lteIterator = graffiti.discover(object.channels, {
|
|
648
635
|
properties: {
|
|
649
636
|
lastModified: {
|
|
@@ -652,8 +639,8 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
652
639
|
}
|
|
653
640
|
});
|
|
654
641
|
const value2 = await nextStreamValue(lteIterator);
|
|
655
|
-
|
|
656
|
-
|
|
642
|
+
expect2(value2.url).toEqual(putted1.url);
|
|
643
|
+
expect2(await lteIterator.next()).toHaveProperty("done", true);
|
|
657
644
|
const lteIteratorEpsilon = graffiti.discover(object.channels, {
|
|
658
645
|
properties: {
|
|
659
646
|
lastModified: {
|
|
@@ -661,9 +648,9 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
661
648
|
}
|
|
662
649
|
}
|
|
663
650
|
});
|
|
664
|
-
|
|
651
|
+
expect2(await lteIteratorEpsilon.next()).toHaveProperty("done", true);
|
|
665
652
|
});
|
|
666
|
-
|
|
653
|
+
it2("discover schema allowed, as and not as owner", async () => {
|
|
667
654
|
const object = randomPutObject();
|
|
668
655
|
object.allowed = [randomString(), session2.actor, randomString()];
|
|
669
656
|
await graffiti.put(object, session1);
|
|
@@ -687,8 +674,8 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
687
674
|
session1
|
|
688
675
|
);
|
|
689
676
|
const value = await nextStreamValue(iteratorSession1);
|
|
690
|
-
|
|
691
|
-
await
|
|
677
|
+
expect2(value.value).toEqual(object.value);
|
|
678
|
+
await expect2(iteratorSession1.next()).resolves.toHaveProperty(
|
|
692
679
|
"done",
|
|
693
680
|
true
|
|
694
681
|
);
|
|
@@ -703,7 +690,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
703
690
|
},
|
|
704
691
|
session2
|
|
705
692
|
);
|
|
706
|
-
await
|
|
693
|
+
await expect2(iteratorSession2BigAllow.next()).resolves.toHaveProperty(
|
|
707
694
|
"done",
|
|
708
695
|
true
|
|
709
696
|
);
|
|
@@ -724,7 +711,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
724
711
|
},
|
|
725
712
|
session2
|
|
726
713
|
);
|
|
727
|
-
await
|
|
714
|
+
await expect2(iteratorSession2PeekOther.next()).resolves.toHaveProperty(
|
|
728
715
|
"done",
|
|
729
716
|
true
|
|
730
717
|
);
|
|
@@ -747,12 +734,12 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
747
734
|
session2
|
|
748
735
|
);
|
|
749
736
|
const value2 = await nextStreamValue(iteratorSession2SmallAllowPeekSelf);
|
|
750
|
-
|
|
751
|
-
await
|
|
737
|
+
expect2(value2.value).toEqual(object.value);
|
|
738
|
+
await expect2(
|
|
752
739
|
iteratorSession2SmallAllowPeekSelf.next()
|
|
753
740
|
).resolves.toHaveProperty("done", true);
|
|
754
741
|
});
|
|
755
|
-
|
|
742
|
+
it2("discover schema channels, as and not as owner", async () => {
|
|
756
743
|
const object = randomPutObject();
|
|
757
744
|
object.channels = [randomString(), randomString(), randomString()];
|
|
758
745
|
await graffiti.put(object, session1);
|
|
@@ -776,8 +763,8 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
776
763
|
session1
|
|
777
764
|
);
|
|
778
765
|
const value = await nextStreamValue(iteratorSession1);
|
|
779
|
-
|
|
780
|
-
await
|
|
766
|
+
expect2(value.value).toEqual(object.value);
|
|
767
|
+
await expect2(iteratorSession1.next()).resolves.toHaveProperty(
|
|
781
768
|
"done",
|
|
782
769
|
true
|
|
783
770
|
);
|
|
@@ -792,7 +779,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
792
779
|
},
|
|
793
780
|
session2
|
|
794
781
|
);
|
|
795
|
-
await
|
|
782
|
+
await expect2(iteratorSession2BigAllow.next()).resolves.toHaveProperty(
|
|
796
783
|
"done",
|
|
797
784
|
true
|
|
798
785
|
);
|
|
@@ -813,7 +800,7 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
813
800
|
},
|
|
814
801
|
session2
|
|
815
802
|
);
|
|
816
|
-
await
|
|
803
|
+
await expect2(iteratorSession2PeekOther.next()).resolves.toHaveProperty(
|
|
817
804
|
"done",
|
|
818
805
|
true
|
|
819
806
|
);
|
|
@@ -836,12 +823,12 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
836
823
|
session2
|
|
837
824
|
);
|
|
838
825
|
const value2 = await nextStreamValue(iteratorSession2SmallAllowPeekSelf);
|
|
839
|
-
|
|
840
|
-
await
|
|
826
|
+
expect2(value2.value).toEqual(object.value);
|
|
827
|
+
await expect2(
|
|
841
828
|
iteratorSession2SmallAllowPeekSelf.next()
|
|
842
829
|
).resolves.toHaveProperty("done", true);
|
|
843
830
|
});
|
|
844
|
-
|
|
831
|
+
it2("discover query for empty allowed", async () => {
|
|
845
832
|
const publicO = randomPutObject();
|
|
846
833
|
const publicSchema = {
|
|
847
834
|
not: {
|
|
@@ -855,9 +842,9 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
855
842
|
session1
|
|
856
843
|
);
|
|
857
844
|
const value = await nextStreamValue(iterator);
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
await
|
|
845
|
+
expect2(value.value).toEqual(publicO.value);
|
|
846
|
+
expect2(value.allowed).toBeUndefined();
|
|
847
|
+
await expect2(iterator.next()).resolves.toHaveProperty("done", true);
|
|
861
848
|
const restricted = randomPutObject();
|
|
862
849
|
restricted.allowed = [];
|
|
863
850
|
await graffiti.put(restricted, session1);
|
|
@@ -866,9 +853,9 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
866
853
|
publicSchema,
|
|
867
854
|
session1
|
|
868
855
|
);
|
|
869
|
-
await
|
|
856
|
+
await expect2(iterator2.next()).resolves.toHaveProperty("done", true);
|
|
870
857
|
});
|
|
871
|
-
|
|
858
|
+
it2("discover query for values", async () => {
|
|
872
859
|
const object1 = randomPutObject();
|
|
873
860
|
object1.value = { test: randomString() };
|
|
874
861
|
await graffiti.put(object1, session);
|
|
@@ -897,59 +884,84 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
897
884
|
}
|
|
898
885
|
counts.set(property, count);
|
|
899
886
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
887
|
+
expect2(counts.get("test")).toBe(2);
|
|
888
|
+
expect2(counts.get("something")).toBe(2);
|
|
889
|
+
expect2(counts.get("other")).toBe(1);
|
|
903
890
|
});
|
|
904
|
-
|
|
891
|
+
it2("discover for deleted content", async () => {
|
|
905
892
|
const object = randomPutObject();
|
|
906
893
|
const putted = await graffiti.put(object, session);
|
|
894
|
+
const iterator1 = graffiti.discover(object.channels, {});
|
|
895
|
+
const value1 = await nextStreamValue(iterator1);
|
|
896
|
+
expect2(value1.value).toEqual(object.value);
|
|
897
|
+
const returnValue = await iterator1.next();
|
|
898
|
+
assert2(returnValue.done, "value2 is not done");
|
|
907
899
|
const deleted = await graffiti.delete(putted, session);
|
|
908
900
|
const iterator = graffiti.discover(object.channels, {});
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
901
|
+
await expect2(iterator.next()).resolves.toHaveProperty("done", true);
|
|
902
|
+
const tombIterator = returnValue.value.continue();
|
|
903
|
+
const value = await tombIterator.next();
|
|
904
|
+
assert2(!value.done && !value.value.error, "value is done");
|
|
905
|
+
expect2(value.value.tombstone).toBe(true);
|
|
906
|
+
expect2(value.value.value.value).toEqual(object.value);
|
|
907
|
+
expect2(value.value.value.channels).toEqual(object.channels);
|
|
908
|
+
expect2(value.value.value.actor).toEqual(session.actor);
|
|
909
|
+
expect2(value.value.value.lastModified).toEqual(deleted.lastModified);
|
|
910
|
+
await expect2(tombIterator.next()).resolves.toHaveProperty("done", true);
|
|
916
911
|
});
|
|
917
|
-
|
|
918
|
-
for (let i = 0; i <
|
|
912
|
+
it2("discover for replaced channels", async () => {
|
|
913
|
+
for (let i = 0; i < 20; i++) {
|
|
919
914
|
const object1 = randomPutObject();
|
|
920
915
|
const putted = await graffiti.put(object1, session);
|
|
916
|
+
const iterator3 = graffiti.discover(object1.channels, {});
|
|
917
|
+
const value3 = await nextStreamValue(iterator3);
|
|
918
|
+
expect2(value3.value).toEqual(object1.value);
|
|
919
|
+
const returnValue = await iterator3.next();
|
|
920
|
+
assert2(returnValue.done, "value2 is not done");
|
|
921
921
|
const object2 = randomPutObject();
|
|
922
922
|
const replaced = await graffiti.put(
|
|
923
923
|
{
|
|
924
|
-
...
|
|
925
|
-
|
|
924
|
+
...object2,
|
|
925
|
+
url: putted.url
|
|
926
926
|
},
|
|
927
927
|
session
|
|
928
928
|
);
|
|
929
929
|
const iterator1 = graffiti.discover(object1.channels, {});
|
|
930
|
-
const value1 = await nextStreamValue(iterator1);
|
|
931
|
-
await expect3(iterator1.next()).resolves.toHaveProperty("done", true);
|
|
932
930
|
const iterator2 = graffiti.discover(object2.channels, {});
|
|
933
|
-
const
|
|
934
|
-
await expect3(iterator2.next()).resolves.toHaveProperty("done", true);
|
|
931
|
+
const tombIterator = returnValue.value.continue();
|
|
935
932
|
if (putted.lastModified === replaced.lastModified) {
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
expect3(value2.channels).toEqual(object2.channels);
|
|
946
|
-
expect3(value2.lastModified).toEqual(replaced.lastModified);
|
|
933
|
+
const value1 = await iterator1.next();
|
|
934
|
+
const value22 = await iterator2.next();
|
|
935
|
+
const value32 = await tombIterator.next();
|
|
936
|
+
expect2(value1.done || value22.done).toBe(true);
|
|
937
|
+
expect2(value1.done && value22.done).toBe(false);
|
|
938
|
+
assert2(!value32.done && !value32.value.error, "value is done");
|
|
939
|
+
expect2(value32.value.tombstone || value22.done).toBe(true);
|
|
940
|
+
expect2(value32.value.tombstone && value22.done).toBe(false);
|
|
941
|
+
continue;
|
|
947
942
|
}
|
|
943
|
+
await expect2(iterator1.next()).resolves.toHaveProperty("done", true);
|
|
944
|
+
const value4 = await tombIterator.next();
|
|
945
|
+
assert2(!value4.done && !value4.value.error, "value is done");
|
|
946
|
+
expect2(value4.value.tombstone).toBe(true);
|
|
947
|
+
expect2(value4.value.value.value).toEqual(object1.value);
|
|
948
|
+
expect2(value4.value.value.channels).toEqual(object1.channels);
|
|
949
|
+
expect2(value4.value.value.lastModified).toEqual(replaced.lastModified);
|
|
950
|
+
const value2 = await nextStreamValue(iterator2);
|
|
951
|
+
await expect2(iterator2.next()).resolves.toHaveProperty("done", true);
|
|
952
|
+
expect2(value2.value).toEqual(object2.value);
|
|
953
|
+
expect2(value2.channels).toEqual(object2.channels);
|
|
954
|
+
expect2(value2.lastModified).toEqual(replaced.lastModified);
|
|
948
955
|
}
|
|
949
956
|
});
|
|
950
|
-
|
|
957
|
+
it2("discover for patched allowed", async () => {
|
|
951
958
|
const object = randomPutObject();
|
|
952
959
|
const putted = await graffiti.put(object, session);
|
|
960
|
+
const iterator1 = graffiti.discover(object.channels, {});
|
|
961
|
+
const value1 = await nextStreamValue(iterator1);
|
|
962
|
+
expect2(value1.value).toEqual(object.value);
|
|
963
|
+
const returnValue = await iterator1.next();
|
|
964
|
+
assert2(returnValue.done, "value2 is not done");
|
|
953
965
|
await graffiti.patch(
|
|
954
966
|
{
|
|
955
967
|
allowed: [{ op: "add", path: "", value: [] }]
|
|
@@ -957,40 +969,51 @@ var graffitiDiscoverTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
957
969
|
putted,
|
|
958
970
|
session
|
|
959
971
|
);
|
|
960
|
-
const
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
972
|
+
const iterator2 = graffiti.discover(object.channels, {});
|
|
973
|
+
expect2(await iterator2.next()).toHaveProperty("done", true);
|
|
974
|
+
const iterator = returnValue.value.continue();
|
|
975
|
+
const value = await iterator.next();
|
|
976
|
+
assert2(!value.done && !value.value.error, "value is done");
|
|
977
|
+
expect2(value.value.tombstone).toBe(true);
|
|
978
|
+
expect2(value.value.value.value).toEqual(object.value);
|
|
979
|
+
expect2(value.value.value.channels).toEqual(object.channels);
|
|
980
|
+
expect2(value.value.value.allowed).toBeUndefined();
|
|
981
|
+
await expect2(iterator.next()).resolves.toHaveProperty("done", true);
|
|
967
982
|
});
|
|
968
|
-
|
|
983
|
+
it2("put concurrently and discover one", async () => {
|
|
969
984
|
const object = randomPutObject();
|
|
970
|
-
|
|
971
|
-
const putPromises = Array(
|
|
985
|
+
const putted = await graffiti.put(object, session);
|
|
986
|
+
const putPromises = Array(99).fill(0).map(
|
|
987
|
+
() => graffiti.put(
|
|
988
|
+
{
|
|
989
|
+
...object,
|
|
990
|
+
url: putted.url
|
|
991
|
+
},
|
|
992
|
+
session
|
|
993
|
+
)
|
|
994
|
+
);
|
|
972
995
|
await Promise.all(putPromises);
|
|
973
996
|
const iterator = graffiti.discover(object.channels, {});
|
|
974
997
|
let tombstoneCount = 0;
|
|
975
998
|
let valueCount = 0;
|
|
976
999
|
for await (const result of iterator) {
|
|
977
1000
|
assert2(!result.error, "result has error");
|
|
978
|
-
if (result.
|
|
1001
|
+
if (result.tombstone) {
|
|
979
1002
|
tombstoneCount++;
|
|
980
1003
|
} else {
|
|
981
1004
|
valueCount++;
|
|
982
1005
|
}
|
|
983
1006
|
}
|
|
984
|
-
|
|
985
|
-
|
|
1007
|
+
expect2(tombstoneCount).toBe(0);
|
|
1008
|
+
expect2(valueCount).toBe(1);
|
|
986
1009
|
});
|
|
987
1010
|
});
|
|
988
1011
|
};
|
|
989
1012
|
|
|
990
1013
|
// tests/orphans.ts
|
|
991
|
-
import { it as
|
|
1014
|
+
import { it as it3, expect as expect3, describe as describe3, assert as assert3, beforeAll as beforeAll3 } from "vitest";
|
|
992
1015
|
var graffitiOrphanTests = (useGraffiti, useSession1, useSession2) => {
|
|
993
|
-
|
|
1016
|
+
describe3("recoverOrphans", { timeout: 2e4 }, () => {
|
|
994
1017
|
let graffiti;
|
|
995
1018
|
let session;
|
|
996
1019
|
let session1;
|
|
@@ -1001,12 +1024,12 @@ var graffitiOrphanTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1001
1024
|
session = session1;
|
|
1002
1025
|
session2 = await useSession2();
|
|
1003
1026
|
});
|
|
1004
|
-
|
|
1027
|
+
it3("list orphans", async () => {
|
|
1005
1028
|
const existingOrphans = [];
|
|
1006
1029
|
const orphanIterator1 = graffiti.recoverOrphans({}, session);
|
|
1007
1030
|
for await (const orphan of orphanIterator1) {
|
|
1008
1031
|
if (orphan.error) continue;
|
|
1009
|
-
existingOrphans.push(orphan.value.
|
|
1032
|
+
existingOrphans.push(orphan.value.url);
|
|
1010
1033
|
}
|
|
1011
1034
|
const object = randomPutObject();
|
|
1012
1035
|
object.channels = [];
|
|
@@ -1015,19 +1038,40 @@ var graffitiOrphanTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1015
1038
|
let numResults = 0;
|
|
1016
1039
|
for await (const orphan of orphanIterator2) {
|
|
1017
1040
|
if (orphan.error) continue;
|
|
1018
|
-
|
|
1041
|
+
assert3(!orphan.tombstone, "orphan is tombstone");
|
|
1042
|
+
if (orphan.value.url === putted.url) {
|
|
1019
1043
|
numResults++;
|
|
1020
|
-
|
|
1021
|
-
expect4(orphan.value.lastModified).toBe(putted.lastModified);
|
|
1044
|
+
expect3(orphan.value.lastModified).toBe(putted.lastModified);
|
|
1022
1045
|
}
|
|
1023
1046
|
}
|
|
1024
|
-
|
|
1047
|
+
expect3(numResults).toBe(1);
|
|
1025
1048
|
});
|
|
1026
|
-
|
|
1049
|
+
it3("replaced orphan, no longer", async () => {
|
|
1027
1050
|
const object = randomPutObject();
|
|
1028
1051
|
object.channels = [];
|
|
1029
1052
|
const putOrphan = await graffiti.put(object, session);
|
|
1030
1053
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
1054
|
+
expect3(Object.keys(object.value).length).toBeGreaterThanOrEqual(1);
|
|
1055
|
+
expect3(Object.keys(object.value)[0]).toBeTypeOf("string");
|
|
1056
|
+
const iterator1 = graffiti.recoverOrphans(
|
|
1057
|
+
{
|
|
1058
|
+
properties: {
|
|
1059
|
+
value: {
|
|
1060
|
+
properties: {
|
|
1061
|
+
[Object.keys(object.value)[0]]: {
|
|
1062
|
+
type: "string"
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
1065
|
+
required: [Object.keys(object.value)[0]]
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
},
|
|
1069
|
+
session
|
|
1070
|
+
);
|
|
1071
|
+
const value1 = await nextStreamValue(iterator1);
|
|
1072
|
+
expect3(value1.value).toEqual(object.value);
|
|
1073
|
+
const returnValue = await iterator1.next();
|
|
1074
|
+
assert3(returnValue.done, "value2 is not done");
|
|
1031
1075
|
const putNotOrphan = await graffiti.put(
|
|
1032
1076
|
{
|
|
1033
1077
|
...putOrphan,
|
|
@@ -1036,28 +1080,35 @@ var graffitiOrphanTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1036
1080
|
},
|
|
1037
1081
|
session
|
|
1038
1082
|
);
|
|
1039
|
-
|
|
1040
|
-
|
|
1083
|
+
expect3(putNotOrphan.url).toBe(putOrphan.url);
|
|
1084
|
+
expect3(putNotOrphan.lastModified).toBeGreaterThan(putOrphan.lastModified);
|
|
1041
1085
|
const orphanIterator = graffiti.recoverOrphans({}, session);
|
|
1042
1086
|
let numResults = 0;
|
|
1043
1087
|
for await (const orphan of orphanIterator) {
|
|
1044
1088
|
if (orphan.error) continue;
|
|
1045
|
-
if (orphan.value.
|
|
1089
|
+
if (orphan.value.url === putOrphan.url) {
|
|
1046
1090
|
numResults++;
|
|
1047
|
-
expect4(orphan.value.tombstone).toBe(true);
|
|
1048
|
-
expect4(orphan.value.lastModified).toBe(putNotOrphan.lastModified);
|
|
1049
|
-
expect4(orphan.value.channels).toEqual([]);
|
|
1050
1091
|
}
|
|
1051
1092
|
}
|
|
1052
|
-
|
|
1093
|
+
expect3(numResults).toBe(0);
|
|
1094
|
+
const iterator2 = returnValue.value.continue();
|
|
1095
|
+
const value2 = await iterator2.next();
|
|
1096
|
+
assert3(
|
|
1097
|
+
!value2.done && !value2.value.error,
|
|
1098
|
+
"value2 is done or has error"
|
|
1099
|
+
);
|
|
1100
|
+
expect3(value2.value.tombstone).toBe(true);
|
|
1101
|
+
expect3(value2.value.value.lastModified).toBe(putNotOrphan.lastModified);
|
|
1102
|
+
expect3(value2.value.value.channels).toEqual([]);
|
|
1103
|
+
await expect3(iterator2.next()).resolves.toHaveProperty("done", true);
|
|
1053
1104
|
});
|
|
1054
1105
|
});
|
|
1055
1106
|
};
|
|
1056
1107
|
|
|
1057
1108
|
// tests/channel-stats.ts
|
|
1058
|
-
import { it as
|
|
1109
|
+
import { it as it4, expect as expect4, describe as describe4, assert as assert4, beforeAll as beforeAll4 } from "vitest";
|
|
1059
1110
|
var graffitiChannelStatsTests = (useGraffiti, useSession1, useSession2) => {
|
|
1060
|
-
|
|
1111
|
+
describe4("channel stats", { timeout: 2e4 }, () => {
|
|
1061
1112
|
let graffiti;
|
|
1062
1113
|
let session;
|
|
1063
1114
|
let session1;
|
|
@@ -1068,7 +1119,7 @@ var graffitiChannelStatsTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1068
1119
|
session = session1;
|
|
1069
1120
|
session2 = await useSession2();
|
|
1070
1121
|
});
|
|
1071
|
-
|
|
1122
|
+
it4("list channels", async () => {
|
|
1072
1123
|
const existingChannels = /* @__PURE__ */ new Map();
|
|
1073
1124
|
const channelIterator1 = graffiti.channelStats(session);
|
|
1074
1125
|
for await (const channel of channelIterator1) {
|
|
@@ -1104,12 +1155,12 @@ var graffitiChannelStatsTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1104
1155
|
([channel, count]) => !existingChannels.has(channel)
|
|
1105
1156
|
)
|
|
1106
1157
|
);
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1158
|
+
expect4(newChannels.size).toBe(3);
|
|
1159
|
+
expect4(newChannels.get(channels[0])).toBe(6);
|
|
1160
|
+
expect4(newChannels.get(channels[1])).toBe(5);
|
|
1161
|
+
expect4(newChannels.get(channels[2])).toBe(4);
|
|
1111
1162
|
});
|
|
1112
|
-
|
|
1163
|
+
it4("list channels with deleted channel", async () => {
|
|
1113
1164
|
const channels = [randomString(), randomString(), randomString()];
|
|
1114
1165
|
const before = await graffiti.put(
|
|
1115
1166
|
{
|
|
@@ -1141,17 +1192,17 @@ var graffitiChannelStatsTests = (useGraffiti, useSession1, useSession2) => {
|
|
|
1141
1192
|
"There should not be an object in channel[0]"
|
|
1142
1193
|
);
|
|
1143
1194
|
if (channel === channels[1]) {
|
|
1144
|
-
|
|
1145
|
-
|
|
1195
|
+
expect4(count).toBe(1);
|
|
1196
|
+
expect4(lastModified).toBe(before.lastModified);
|
|
1146
1197
|
got1++;
|
|
1147
1198
|
} else if (channel === channels[2]) {
|
|
1148
|
-
|
|
1149
|
-
|
|
1199
|
+
expect4(count).toBe(2);
|
|
1200
|
+
expect4(lastModified).toBe(second.lastModified);
|
|
1150
1201
|
got2++;
|
|
1151
1202
|
}
|
|
1152
1203
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1204
|
+
expect4(got1).toBe(1);
|
|
1205
|
+
expect4(got2).toBe(1);
|
|
1155
1206
|
});
|
|
1156
1207
|
});
|
|
1157
1208
|
};
|
|
@@ -1159,7 +1210,6 @@ export {
|
|
|
1159
1210
|
graffitiCRUDTests,
|
|
1160
1211
|
graffitiChannelStatsTests,
|
|
1161
1212
|
graffitiDiscoverTests,
|
|
1162
|
-
graffitiLocationTests,
|
|
1163
1213
|
graffitiOrphanTests,
|
|
1164
1214
|
nextStreamValue,
|
|
1165
1215
|
randomPutObject,
|