@graffiti-garden/api 0.1.7 → 0.1.9
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/dist/src/2-types.d.ts +7 -3
- package/dist/src/2-types.d.ts.map +1 -1
- package/dist/tests/index.js +1 -1
- package/dist/tests/src/crud.d.ts.map +1 -1
- package/dist/tests/src/discover.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/2-types.ts +14 -5
- package/tests/src/crud.ts +412 -411
- package/tests/src/discover.ts +531 -511
package/tests/src/crud.ts
CHANGED
|
@@ -19,457 +19,458 @@ export const graffitiCRUDTests = (
|
|
|
19
19
|
useSession1: () => GraffitiSession,
|
|
20
20
|
useSession2: () => GraffitiSession,
|
|
21
21
|
) => {
|
|
22
|
-
describe(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified);
|
|
67
|
-
expect(afterReplaced.tombstone).toEqual(false);
|
|
68
|
-
|
|
69
|
-
// Delete it
|
|
70
|
-
const beforeDeleted = await graffiti.delete(afterReplaced, session);
|
|
71
|
-
expect(beforeDeleted.tombstone).toEqual(true);
|
|
72
|
-
expect(beforeDeleted.value).toEqual(newValue);
|
|
73
|
-
expect(beforeDeleted.lastModified).toBeGreaterThan(
|
|
74
|
-
beforeReplaced.lastModified,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
// Try to get it and fail
|
|
78
|
-
await expect(graffiti.get(afterReplaced, {})).rejects.toThrow(
|
|
79
|
-
GraffitiErrorNotFound,
|
|
80
|
-
);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("put, get, delete with wrong actor", async () => {
|
|
84
|
-
const graffiti = useGraffiti();
|
|
85
|
-
const session1 = useSession1();
|
|
86
|
-
const session2 = useSession2();
|
|
87
|
-
|
|
88
|
-
await expect(
|
|
89
|
-
graffiti.put(
|
|
90
|
-
{ value: {}, channels: [], actor: session2.actor },
|
|
91
|
-
session1,
|
|
92
|
-
),
|
|
93
|
-
).rejects.toThrow(GraffitiErrorForbidden);
|
|
22
|
+
describe(
|
|
23
|
+
"CRUD",
|
|
24
|
+
() => {
|
|
25
|
+
it("put, get, delete", async () => {
|
|
26
|
+
const graffiti = useGraffiti();
|
|
27
|
+
const session = useSession1();
|
|
28
|
+
const value = {
|
|
29
|
+
something: "hello, world~ c:",
|
|
30
|
+
};
|
|
31
|
+
const channels = [randomString(), randomString()];
|
|
32
|
+
|
|
33
|
+
// Put the object
|
|
34
|
+
const previous = await graffiti.put({ value, channels }, session);
|
|
35
|
+
expect(previous.value).toEqual({});
|
|
36
|
+
expect(previous.channels).toEqual([]);
|
|
37
|
+
expect(previous.allowed).toBeUndefined();
|
|
38
|
+
expect(previous.actor).toEqual(session.actor);
|
|
39
|
+
|
|
40
|
+
// Get it back
|
|
41
|
+
const gotten = await graffiti.get(previous, {});
|
|
42
|
+
expect(gotten.value).toEqual(value);
|
|
43
|
+
expect(gotten.channels).toEqual([]);
|
|
44
|
+
expect(gotten.allowed).toBeUndefined();
|
|
45
|
+
expect(gotten.name).toEqual(previous.name);
|
|
46
|
+
expect(gotten.actor).toEqual(previous.actor);
|
|
47
|
+
expect(gotten.source).toEqual(previous.source);
|
|
48
|
+
expect(gotten.lastModified).toEqual(previous.lastModified);
|
|
49
|
+
|
|
50
|
+
// Replace it
|
|
51
|
+
const newValue = {
|
|
52
|
+
something: "goodbye, world~ :c",
|
|
53
|
+
};
|
|
54
|
+
const beforeReplaced = await graffiti.put(
|
|
55
|
+
{ ...previous, value: newValue, channels: [] },
|
|
56
|
+
session,
|
|
57
|
+
);
|
|
58
|
+
expect(beforeReplaced.value).toEqual(value);
|
|
59
|
+
expect(beforeReplaced.tombstone).toEqual(true);
|
|
60
|
+
expect(beforeReplaced.name).toEqual(previous.name);
|
|
61
|
+
expect(beforeReplaced.actor).toEqual(previous.actor);
|
|
62
|
+
expect(beforeReplaced.source).toEqual(previous.source);
|
|
63
|
+
expect(beforeReplaced.lastModified).toBeGreaterThanOrEqual(
|
|
64
|
+
gotten.lastModified,
|
|
65
|
+
);
|
|
94
66
|
|
|
95
|
-
|
|
96
|
-
graffiti.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
67
|
+
// Get it again
|
|
68
|
+
const afterReplaced = await graffiti.get(previous, {});
|
|
69
|
+
expect(afterReplaced.value).toEqual(newValue);
|
|
70
|
+
expect(afterReplaced.lastModified).toEqual(beforeReplaced.lastModified);
|
|
71
|
+
expect(afterReplaced.tombstone).toEqual(false);
|
|
72
|
+
|
|
73
|
+
// Delete it
|
|
74
|
+
const beforeDeleted = await graffiti.delete(afterReplaced, session);
|
|
75
|
+
expect(beforeDeleted.tombstone).toEqual(true);
|
|
76
|
+
expect(beforeDeleted.value).toEqual(newValue);
|
|
77
|
+
expect(beforeDeleted.lastModified).toBeGreaterThanOrEqual(
|
|
78
|
+
beforeReplaced.lastModified,
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Try to get it and fail
|
|
82
|
+
await expect(graffiti.get(afterReplaced, {})).rejects.toThrow(
|
|
83
|
+
GraffitiErrorNotFound,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("put, get, delete with wrong actor", async () => {
|
|
88
|
+
const graffiti = useGraffiti();
|
|
89
|
+
const session1 = useSession1();
|
|
90
|
+
const session2 = useSession2();
|
|
91
|
+
|
|
92
|
+
await expect(
|
|
93
|
+
graffiti.put(
|
|
94
|
+
{ value: {}, channels: [], actor: session2.actor },
|
|
95
|
+
session1,
|
|
96
|
+
),
|
|
97
|
+
).rejects.toThrow(GraffitiErrorForbidden);
|
|
98
|
+
|
|
99
|
+
const putted = await graffiti.put(
|
|
100
|
+
{ value: {}, channels: [] },
|
|
101
|
+
session2,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
await expect(graffiti.delete(putted, session1)).rejects.toThrow(
|
|
105
|
+
GraffitiErrorForbidden,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
await expect(graffiti.patch({}, putted, session1)).rejects.toThrow(
|
|
109
|
+
GraffitiErrorForbidden,
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("put and get with schema", async () => {
|
|
114
|
+
const graffiti = useGraffiti();
|
|
115
|
+
const session = useSession1();
|
|
116
|
+
|
|
117
|
+
const schema = {
|
|
118
|
+
properties: {
|
|
119
|
+
value: {
|
|
120
|
+
properties: {
|
|
121
|
+
something: {
|
|
122
|
+
type: "string",
|
|
123
|
+
},
|
|
124
|
+
another: {
|
|
125
|
+
type: "integer",
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
101
129
|
},
|
|
102
|
-
|
|
103
|
-
),
|
|
104
|
-
).rejects.toThrow(GraffitiErrorForbidden);
|
|
130
|
+
} as const;
|
|
105
131
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
132
|
+
const goodValue = {
|
|
133
|
+
something: "hello",
|
|
134
|
+
another: 42,
|
|
135
|
+
} as const;
|
|
136
|
+
|
|
137
|
+
const putted = await graffiti.put<typeof schema>(
|
|
109
138
|
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
actor: session2.actor,
|
|
139
|
+
value: goodValue,
|
|
140
|
+
channels: [],
|
|
113
141
|
},
|
|
114
|
-
|
|
115
|
-
)
|
|
116
|
-
).rejects.toThrow(GraffitiErrorForbidden);
|
|
117
|
-
});
|
|
142
|
+
session,
|
|
143
|
+
);
|
|
118
144
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
const gotten = await graffiti.get(putted, schema);
|
|
146
|
+
expect(gotten.value.something).toEqual(goodValue.something);
|
|
147
|
+
expect(gotten.value.another).toEqual(goodValue.another);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("put and get with invalid schema", async () => {
|
|
151
|
+
const graffiti = useGraffiti();
|
|
152
|
+
const session = useSession1();
|
|
122
153
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
154
|
+
const putted = await graffiti.put({ value: {}, channels: [] }, session);
|
|
155
|
+
await expect(
|
|
156
|
+
graffiti.get(putted, {
|
|
126
157
|
properties: {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
another: {
|
|
131
|
-
type: "integer",
|
|
158
|
+
value: {
|
|
159
|
+
//@ts-ignore
|
|
160
|
+
type: "asdf",
|
|
132
161
|
},
|
|
133
162
|
},
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{
|
|
145
|
-
value: goodValue,
|
|
146
|
-
channels: [],
|
|
147
|
-
},
|
|
148
|
-
session,
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const gotten = await graffiti.get(putted, schema);
|
|
152
|
-
expect(gotten.value.something).toEqual(goodValue.something);
|
|
153
|
-
expect(gotten.value.another).toEqual(goodValue.another);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it("put and get with invalid schema", async () => {
|
|
157
|
-
const graffiti = useGraffiti();
|
|
158
|
-
const session = useSession1();
|
|
159
|
-
|
|
160
|
-
const putted = await graffiti.put({ value: {}, channels: [] }, session);
|
|
161
|
-
await expect(
|
|
162
|
-
graffiti.get(putted, {
|
|
163
|
-
properties: {
|
|
163
|
+
}),
|
|
164
|
+
).rejects.toThrow(GraffitiErrorInvalidSchema);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("put and get with wrong schema", async () => {
|
|
168
|
+
const graffiti = useGraffiti();
|
|
169
|
+
const session = useSession1();
|
|
170
|
+
|
|
171
|
+
const putted = await graffiti.put(
|
|
172
|
+
{
|
|
164
173
|
value: {
|
|
165
|
-
|
|
166
|
-
type: "asdf",
|
|
174
|
+
hello: "world",
|
|
167
175
|
},
|
|
176
|
+
channels: [],
|
|
168
177
|
},
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it("put and get with wrong schema", async () => {
|
|
174
|
-
const graffiti = useGraffiti();
|
|
175
|
-
const session = useSession1();
|
|
176
|
-
|
|
177
|
-
const putted = await graffiti.put(
|
|
178
|
-
{
|
|
179
|
-
value: {
|
|
180
|
-
hello: "world",
|
|
181
|
-
},
|
|
182
|
-
channels: [],
|
|
183
|
-
},
|
|
184
|
-
session,
|
|
185
|
-
);
|
|
178
|
+
session,
|
|
179
|
+
);
|
|
186
180
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
181
|
+
await expect(
|
|
182
|
+
graffiti.get(putted, {
|
|
183
|
+
properties: {
|
|
184
|
+
value: {
|
|
185
|
+
properties: {
|
|
186
|
+
hello: {
|
|
187
|
+
type: "number",
|
|
188
|
+
},
|
|
194
189
|
},
|
|
195
190
|
},
|
|
196
191
|
},
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
).rejects.toThrow(GraffitiErrorSchemaMismatch);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it("put and get with empty access control", async () => {
|
|
203
|
-
const graffiti = useGraffiti();
|
|
204
|
-
const session1 = useSession1();
|
|
205
|
-
const session2 = useSession2();
|
|
206
|
-
|
|
207
|
-
const value = {
|
|
208
|
-
um: "hi",
|
|
209
|
-
};
|
|
210
|
-
const allowed = [randomString()];
|
|
211
|
-
const channels = [randomString()];
|
|
212
|
-
const putted = await graffiti.put({ value, allowed, channels }, session1);
|
|
213
|
-
|
|
214
|
-
// Get it with authenticated session
|
|
215
|
-
const gotten = await graffiti.get(putted, {}, session1);
|
|
216
|
-
expect(gotten.value).toEqual(value);
|
|
217
|
-
expect(gotten.allowed).toEqual(allowed);
|
|
218
|
-
expect(gotten.channels).toEqual(channels);
|
|
219
|
-
|
|
220
|
-
// But not without session
|
|
221
|
-
await expect(graffiti.get(putted, {})).rejects.toThrow();
|
|
222
|
-
|
|
223
|
-
// Or the wrong session
|
|
224
|
-
await expect(graffiti.get(putted, {}, session2)).rejects.toThrow();
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it("put and get with specific access control", async () => {
|
|
228
|
-
const graffiti = useGraffiti();
|
|
229
|
-
const session1 = useSession1();
|
|
230
|
-
const session2 = useSession2();
|
|
231
|
-
|
|
232
|
-
const value = {
|
|
233
|
-
um: "hi",
|
|
234
|
-
};
|
|
235
|
-
const allowed = [randomString(), session2.actor, randomString()];
|
|
236
|
-
const channels = [randomString()];
|
|
237
|
-
const putted = await graffiti.put(
|
|
238
|
-
{
|
|
239
|
-
value,
|
|
240
|
-
allowed,
|
|
241
|
-
channels,
|
|
242
|
-
},
|
|
243
|
-
session1,
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
// Get it with authenticated session
|
|
247
|
-
const gotten = await graffiti.get(putted, {}, session1);
|
|
248
|
-
expect(gotten.value).toEqual(value);
|
|
249
|
-
expect(gotten.allowed).toEqual(allowed);
|
|
250
|
-
expect(gotten.channels).toEqual(channels);
|
|
251
|
-
|
|
252
|
-
// But not without session
|
|
253
|
-
await expect(graffiti.get(putted, {})).rejects.toThrow();
|
|
254
|
-
|
|
255
|
-
const gotten2 = await graffiti.get(putted, {}, session2);
|
|
256
|
-
expect(gotten2.value).toEqual(value);
|
|
257
|
-
// They should only see that is is private to them
|
|
258
|
-
expect(gotten2.allowed).toEqual([session2.actor]);
|
|
259
|
-
// And not see any channels
|
|
260
|
-
expect(gotten2.channels).toEqual([]);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
it("patch value", async () => {
|
|
264
|
-
const graffiti = useGraffiti();
|
|
265
|
-
const session = useSession1();
|
|
266
|
-
|
|
267
|
-
const value = {
|
|
268
|
-
something: "hello, world~ c:",
|
|
269
|
-
};
|
|
270
|
-
const putted = await graffiti.put({ value, channels: [] }, session);
|
|
271
|
-
|
|
272
|
-
const patch: GraffitiPatch = {
|
|
273
|
-
value: [
|
|
274
|
-
{ op: "replace", path: "/something", value: "goodbye, world~ :c" },
|
|
275
|
-
],
|
|
276
|
-
};
|
|
277
|
-
const beforePatched = await graffiti.patch(patch, putted, session);
|
|
278
|
-
expect(beforePatched.value).toEqual(value);
|
|
279
|
-
expect(beforePatched.tombstone).toBe(true);
|
|
280
|
-
|
|
281
|
-
const gotten = await graffiti.get(putted, {});
|
|
282
|
-
expect(gotten.value).toEqual({
|
|
283
|
-
something: "goodbye, world~ :c",
|
|
192
|
+
}),
|
|
193
|
+
).rejects.toThrow(GraffitiErrorSchemaMismatch);
|
|
284
194
|
});
|
|
285
|
-
expect(beforePatched.lastModified).toBe(gotten.lastModified);
|
|
286
195
|
|
|
287
|
-
|
|
288
|
-
|
|
196
|
+
it("put and get with empty access control", async () => {
|
|
197
|
+
const graffiti = useGraffiti();
|
|
198
|
+
const session1 = useSession1();
|
|
199
|
+
const session2 = useSession2();
|
|
200
|
+
|
|
201
|
+
const value = {
|
|
202
|
+
um: "hi",
|
|
203
|
+
};
|
|
204
|
+
const allowed = [randomString()];
|
|
205
|
+
const channels = [randomString()];
|
|
206
|
+
const putted = await graffiti.put(
|
|
207
|
+
{ value, allowed, channels },
|
|
208
|
+
session1,
|
|
209
|
+
);
|
|
289
210
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
211
|
+
// Get it with authenticated session
|
|
212
|
+
const gotten = await graffiti.get(putted, {}, session1);
|
|
213
|
+
expect(gotten.value).toEqual(value);
|
|
214
|
+
expect(gotten.allowed).toEqual(allowed);
|
|
215
|
+
expect(gotten.channels).toEqual(channels);
|
|
293
216
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
},
|
|
300
|
-
};
|
|
301
|
-
const putted = await graffiti.put(
|
|
302
|
-
{ value: value, channels: [] },
|
|
303
|
-
session,
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
const beforePatch = await graffiti.patch(
|
|
307
|
-
{
|
|
308
|
-
value: [
|
|
309
|
-
{
|
|
310
|
-
op: "replace",
|
|
311
|
-
path: "/something/another/somethingElse",
|
|
312
|
-
value: "goodbye",
|
|
313
|
-
},
|
|
314
|
-
],
|
|
315
|
-
},
|
|
316
|
-
putted,
|
|
317
|
-
session,
|
|
318
|
-
);
|
|
319
|
-
const gotten = await graffiti.get(putted, {});
|
|
320
|
-
|
|
321
|
-
expect(beforePatch.value).toEqual(value);
|
|
322
|
-
expect(gotten.value).toEqual({
|
|
323
|
-
something: {
|
|
324
|
-
another: {
|
|
325
|
-
somethingElse: "goodbye",
|
|
326
|
-
},
|
|
327
|
-
},
|
|
217
|
+
// But not without session
|
|
218
|
+
await expect(graffiti.get(putted, {})).rejects.toThrow();
|
|
219
|
+
|
|
220
|
+
// Or the wrong session
|
|
221
|
+
await expect(graffiti.get(putted, {}, session2)).rejects.toThrow();
|
|
328
222
|
});
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
};
|
|
346
|
-
const patched = await graffiti.patch(patch, putted, session);
|
|
347
|
-
expect(patched.channels).toEqual(channelsBefore);
|
|
348
|
-
const gotten = await graffiti.get(putted, {}, session);
|
|
349
|
-
expect(gotten.channels).toEqual(channelsAfter);
|
|
350
|
-
await graffiti.delete(putted, session);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it("patch 'increment' with test", async () => {
|
|
354
|
-
const graffiti = useGraffiti();
|
|
355
|
-
const session = useSession1();
|
|
356
|
-
|
|
357
|
-
const putted = await graffiti.put(
|
|
358
|
-
{
|
|
359
|
-
value: {
|
|
360
|
-
counter: 1,
|
|
223
|
+
|
|
224
|
+
it("put and get with specific access control", async () => {
|
|
225
|
+
const graffiti = useGraffiti();
|
|
226
|
+
const session1 = useSession1();
|
|
227
|
+
const session2 = useSession2();
|
|
228
|
+
|
|
229
|
+
const value = {
|
|
230
|
+
um: "hi",
|
|
231
|
+
};
|
|
232
|
+
const allowed = [randomString(), session2.actor, randomString()];
|
|
233
|
+
const channels = [randomString()];
|
|
234
|
+
const putted = await graffiti.put(
|
|
235
|
+
{
|
|
236
|
+
value,
|
|
237
|
+
allowed,
|
|
238
|
+
channels,
|
|
361
239
|
},
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
240
|
+
session1,
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
// Get it with authenticated session
|
|
244
|
+
const gotten = await graffiti.get(putted, {}, session1);
|
|
245
|
+
expect(gotten.value).toEqual(value);
|
|
246
|
+
expect(gotten.allowed).toEqual(allowed);
|
|
247
|
+
expect(gotten.channels).toEqual(channels);
|
|
248
|
+
|
|
249
|
+
// But not without session
|
|
250
|
+
await expect(graffiti.get(putted, {})).rejects.toThrow();
|
|
251
|
+
|
|
252
|
+
const gotten2 = await graffiti.get(putted, {}, session2);
|
|
253
|
+
expect(gotten2.value).toEqual(value);
|
|
254
|
+
// They should only see that is is private to them
|
|
255
|
+
expect(gotten2.allowed).toEqual([session2.actor]);
|
|
256
|
+
// And not see any channels
|
|
257
|
+
expect(gotten2.channels).toEqual([]);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it("patch value", async () => {
|
|
261
|
+
const graffiti = useGraffiti();
|
|
262
|
+
const session = useSession1();
|
|
366
263
|
|
|
367
|
-
|
|
368
|
-
|
|
264
|
+
const value = {
|
|
265
|
+
something: "hello, world~ c:",
|
|
266
|
+
};
|
|
267
|
+
const putted = await graffiti.put({ value, channels: [] }, session);
|
|
268
|
+
|
|
269
|
+
const patch: GraffitiPatch = {
|
|
369
270
|
value: [
|
|
370
|
-
{ op: "
|
|
371
|
-
{ op: "replace", path: "/counter", value: 2 },
|
|
271
|
+
{ op: "replace", path: "/something", value: "goodbye, world~ :c" },
|
|
372
272
|
],
|
|
373
|
-
}
|
|
374
|
-
putted,
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
273
|
+
};
|
|
274
|
+
const beforePatched = await graffiti.patch(patch, putted, session);
|
|
275
|
+
expect(beforePatched.value).toEqual(value);
|
|
276
|
+
expect(beforePatched.tombstone).toBe(true);
|
|
277
|
+
|
|
278
|
+
const gotten = await graffiti.get(putted, {});
|
|
279
|
+
expect(gotten.value).toEqual({
|
|
280
|
+
something: "goodbye, world~ :c",
|
|
281
|
+
});
|
|
282
|
+
expect(beforePatched.lastModified).toBe(gotten.lastModified);
|
|
283
|
+
|
|
284
|
+
await graffiti.delete(putted, session);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it("deep patch", async () => {
|
|
288
|
+
const graffiti = useGraffiti();
|
|
289
|
+
const session = useSession1();
|
|
290
|
+
|
|
291
|
+
const value = {
|
|
292
|
+
something: {
|
|
293
|
+
another: {
|
|
294
|
+
somethingElse: "hello",
|
|
385
295
|
},
|
|
386
296
|
},
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
|
|
297
|
+
};
|
|
298
|
+
const putted = await graffiti.put(
|
|
299
|
+
{ value: value, channels: [] },
|
|
300
|
+
session,
|
|
301
|
+
);
|
|
390
302
|
|
|
391
|
-
|
|
392
|
-
graffiti.patch(
|
|
303
|
+
const beforePatch = await graffiti.patch(
|
|
393
304
|
{
|
|
394
305
|
value: [
|
|
395
|
-
{
|
|
396
|
-
|
|
306
|
+
{
|
|
307
|
+
op: "replace",
|
|
308
|
+
path: "/something/another/somethingElse",
|
|
309
|
+
value: "goodbye",
|
|
310
|
+
},
|
|
397
311
|
],
|
|
398
312
|
},
|
|
399
313
|
putted,
|
|
400
314
|
session,
|
|
401
|
-
)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
315
|
+
);
|
|
316
|
+
const gotten = await graffiti.get(putted, {});
|
|
317
|
+
|
|
318
|
+
expect(beforePatch.value).toEqual(value);
|
|
319
|
+
expect(gotten.value).toEqual({
|
|
320
|
+
something: {
|
|
321
|
+
another: {
|
|
322
|
+
somethingElse: "goodbye",
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it("patch channels", async () => {
|
|
329
|
+
const graffiti = useGraffiti();
|
|
330
|
+
const session = useSession1();
|
|
331
|
+
|
|
332
|
+
const channelsBefore = [randomString()];
|
|
333
|
+
const channelsAfter = [randomString()];
|
|
334
|
+
|
|
335
|
+
const putted = await graffiti.put(
|
|
336
|
+
{ value: {}, channels: channelsBefore },
|
|
337
|
+
session,
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
const patch: GraffitiPatch = {
|
|
341
|
+
channels: [{ op: "replace", path: "/0", value: channelsAfter[0] }],
|
|
342
|
+
};
|
|
343
|
+
const patched = await graffiti.patch(patch, putted, session);
|
|
344
|
+
expect(patched.channels).toEqual(channelsBefore);
|
|
345
|
+
const gotten = await graffiti.get(putted, {}, session);
|
|
346
|
+
expect(gotten.channels).toEqual(channelsAfter);
|
|
347
|
+
await graffiti.delete(putted, session);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it("patch 'increment' with test", async () => {
|
|
351
|
+
const graffiti = useGraffiti();
|
|
352
|
+
const session = useSession1();
|
|
353
|
+
|
|
354
|
+
const putted = await graffiti.put(
|
|
355
|
+
{
|
|
356
|
+
value: {
|
|
357
|
+
counter: 1,
|
|
358
|
+
},
|
|
359
|
+
channels: [],
|
|
360
|
+
},
|
|
361
|
+
session,
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
const previous = await graffiti.patch(
|
|
413
365
|
{
|
|
414
366
|
value: [
|
|
415
|
-
{ op: "
|
|
416
|
-
{ op: "
|
|
367
|
+
{ op: "test", path: "/counter", value: 1 },
|
|
368
|
+
{ op: "replace", path: "/counter", value: 2 },
|
|
417
369
|
],
|
|
418
370
|
},
|
|
419
371
|
putted,
|
|
420
372
|
session,
|
|
421
|
-
),
|
|
422
|
-
).rejects.toThrow(GraffitiErrorPatchError);
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
it("patch channels to be wrong", async () => {
|
|
426
|
-
const graffiti = useGraffiti();
|
|
427
|
-
const session = useSession1();
|
|
428
|
-
const object = randomPutObject();
|
|
429
|
-
object.allowed = [randomString()];
|
|
430
|
-
const putted = await graffiti.put(object, session);
|
|
431
|
-
|
|
432
|
-
const patches: GraffitiPatch[] = [
|
|
433
|
-
{
|
|
434
|
-
channels: [{ op: "replace", path: "", value: null }],
|
|
435
|
-
},
|
|
436
|
-
{
|
|
437
|
-
channels: [{ op: "replace", path: "", value: {} }],
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
channels: [{ op: "replace", path: "", value: ["hello", ["hi"]] }],
|
|
441
|
-
},
|
|
442
|
-
{
|
|
443
|
-
channels: [{ op: "add", path: "/0", value: 1 }],
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
value: [{ op: "replace", path: "", value: "not an object" }],
|
|
447
|
-
},
|
|
448
|
-
{
|
|
449
|
-
value: [{ op: "replace", path: "", value: null }],
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
value: [{ op: "replace", path: "", value: [] }],
|
|
453
|
-
},
|
|
454
|
-
{
|
|
455
|
-
allowed: [{ op: "replace", path: "", value: {} }],
|
|
456
|
-
},
|
|
457
|
-
{
|
|
458
|
-
allowed: [{ op: "replace", path: "", value: ["hello", ["hi"]] }],
|
|
459
|
-
},
|
|
460
|
-
];
|
|
461
|
-
|
|
462
|
-
for (const patch of patches) {
|
|
463
|
-
await expect(graffiti.patch(patch, putted, session)).rejects.toThrow(
|
|
464
|
-
GraffitiErrorPatchError,
|
|
465
373
|
);
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
374
|
+
expect(previous.value).toEqual({ counter: 1 });
|
|
375
|
+
const result = await graffiti.get(previous, {
|
|
376
|
+
properties: {
|
|
377
|
+
value: {
|
|
378
|
+
properties: {
|
|
379
|
+
counter: {
|
|
380
|
+
type: "integer",
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
});
|
|
386
|
+
expect(result.value.counter).toEqual(2);
|
|
387
|
+
|
|
388
|
+
await expect(
|
|
389
|
+
graffiti.patch(
|
|
390
|
+
{
|
|
391
|
+
value: [
|
|
392
|
+
{ op: "test", path: "/counter", value: 1 },
|
|
393
|
+
{ op: "replace", path: "/counter", value: 3 },
|
|
394
|
+
],
|
|
395
|
+
},
|
|
396
|
+
putted,
|
|
397
|
+
session,
|
|
398
|
+
),
|
|
399
|
+
).rejects.toThrow(GraffitiErrorPatchTestFailed);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it("invalid patch", async () => {
|
|
403
|
+
const graffiti = useGraffiti();
|
|
404
|
+
const session = useSession1();
|
|
405
|
+
const object = randomPutObject();
|
|
406
|
+
const putted = await graffiti.put(object, session);
|
|
407
|
+
|
|
408
|
+
await expect(
|
|
409
|
+
graffiti.patch(
|
|
410
|
+
{
|
|
411
|
+
value: [
|
|
412
|
+
{ op: "add", path: "/root", value: [] },
|
|
413
|
+
{ op: "add", path: "/root/2", value: 2 }, // out of bounds
|
|
414
|
+
],
|
|
415
|
+
},
|
|
416
|
+
putted,
|
|
417
|
+
session,
|
|
418
|
+
),
|
|
419
|
+
).rejects.toThrow(GraffitiErrorPatchError);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it("patch channels to be wrong", async () => {
|
|
423
|
+
const graffiti = useGraffiti();
|
|
424
|
+
const session = useSession1();
|
|
425
|
+
const object = randomPutObject();
|
|
426
|
+
object.allowed = [randomString()];
|
|
427
|
+
const putted = await graffiti.put(object, session);
|
|
428
|
+
|
|
429
|
+
const patches: GraffitiPatch[] = [
|
|
430
|
+
{
|
|
431
|
+
channels: [{ op: "replace", path: "", value: null }],
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
channels: [{ op: "replace", path: "", value: {} }],
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
channels: [{ op: "replace", path: "", value: ["hello", ["hi"]] }],
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
channels: [{ op: "add", path: "/0", value: 1 }],
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
value: [{ op: "replace", path: "", value: "not an object" }],
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
value: [{ op: "replace", path: "", value: null }],
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
value: [{ op: "replace", path: "", value: [] }],
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
allowed: [{ op: "replace", path: "", value: {} }],
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
allowed: [{ op: "replace", path: "", value: ["hello", ["hi"]] }],
|
|
456
|
+
},
|
|
457
|
+
];
|
|
458
|
+
|
|
459
|
+
for (const patch of patches) {
|
|
460
|
+
await expect(graffiti.patch(patch, putted, session)).rejects.toThrow(
|
|
461
|
+
GraffitiErrorPatchError,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
const gotten = await graffiti.get(putted, {}, session);
|
|
466
|
+
expect(gotten.value).toEqual(object.value);
|
|
467
|
+
expect(gotten.channels).toEqual(object.channels);
|
|
468
|
+
expect(gotten.allowed).toEqual(object.allowed);
|
|
469
|
+
expect(gotten.lastModified).toEqual(putted.lastModified);
|
|
470
|
+
});
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
timeout: 20000,
|
|
474
|
+
},
|
|
475
|
+
);
|
|
475
476
|
};
|