@roc-db/test-utils 0.2.0-pre.32 → 0.2.0-pre.34
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/index.js +311 -172
- package/dist/types/operations/applyDraft.d.ts +1 -1
- package/dist/types/operations/createBlockImage.d.ts +1 -1
- package/dist/types/operations/createBlockParagraph.d.ts +1 -1
- package/dist/types/operations/createBlockRow.d.ts +1 -1
- package/dist/types/operations/createBlockTitle.d.ts +1 -1
- package/dist/types/operations/createDraft.d.ts +1 -1
- package/dist/types/operations/createPost.d.ts +1 -1
- package/dist/types/operations/deleteBlock.d.ts +1 -1
- package/dist/types/operations/deletePost.d.ts +1 -1
- package/dist/types/operations/index.d.ts +50 -14
- package/dist/types/operations/moveBlocks.d.ts +17 -0
- package/dist/types/operations/testTransactionalEdits.d.ts +21 -0
- package/dist/types/operations/updateBlockParagraph.d.ts +1 -1
- package/dist/types/operations/updatePost.d.ts +1 -1
- package/dist/types/operations/updatePostDescription.d.ts +1 -1
- package/dist/types/operations/updatePostTitle.d.ts +1 -1
- package/dist/types/schemas/ApplyDraftMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreateBlockImageMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreateBlockParagraphMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreateBlockRowMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreateBlockTitleMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreateDraftMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreatePostMutationSchema.d.ts +4 -4
- package/dist/types/schemas/CreateUserMutationSchema.d.ts +4 -4
- package/dist/types/schemas/DeleteBlockMutationSchema.d.ts +4 -4
- package/dist/types/schemas/DeletePostMutationSchema.d.ts +4 -4
- package/dist/types/schemas/MoveBlocksMutationSchema.d.ts +51 -0
- package/dist/types/schemas/TestTransactionalEditsMutationSchema.d.ts +56 -0
- package/dist/types/schemas/UpdateBlockParagraphMutationSchema.d.ts +4 -4
- package/dist/types/schemas/UpdatePostDescriptionMutationSchema.d.ts +4 -4
- package/dist/types/schemas/UpdatePostMutationSchema.d.ts +5 -5
- package/dist/types/schemas/UpdatePostTitleMutationSchema.d.ts +4 -4
- package/dist/types/testAdapterImplementation.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -114,7 +114,7 @@ var UpdatePostMutationSchema = mutationSchemaGenerator3("updatePost", z8.object(
|
|
|
114
114
|
ref: PostRefSchema,
|
|
115
115
|
title: z8.string().optional(),
|
|
116
116
|
tags: z8.array(z8.string()).optional().default([]),
|
|
117
|
-
authorRef: UserRefSchema.optional()
|
|
117
|
+
authorRef: UserRefSchema.optional()
|
|
118
118
|
}));
|
|
119
119
|
// src/schemas/UpdatePostTitleMutationSchema.ts
|
|
120
120
|
import { mutationSchemaGenerator as mutationSchemaGenerator4 } from "roc-db";
|
|
@@ -141,7 +141,7 @@ var applyDraft = writeOperation(ApplyDraftMutationSchema, undefined, (txn) => {
|
|
|
141
141
|
const { ref } = txn.payload;
|
|
142
142
|
const versionRef = txn.createRef("PostVersion");
|
|
143
143
|
return QueryChain(Query(() => txn.applyChangeSet(ref)), Query(() => txn.patchEntity(ref, {
|
|
144
|
-
data: { appliedAt: txn.
|
|
144
|
+
data: { appliedAt: txn.timestamp }
|
|
145
145
|
})), Query((draft) => txn.childRefsOf(draft.parents.post, true)), Query((childRefs, draft) => txn.batchReadEntities([draft.parents.post, ...childRefs])), Query((childEntities) => txn.createEntity(versionRef, {
|
|
146
146
|
data: {
|
|
147
147
|
snapshot: childEntities
|
|
@@ -289,12 +289,31 @@ var deletePost = writeOperation9(DeletePostMutationSchema, undefined, (txn) => {
|
|
|
289
289
|
return Query9(() => txn.deleteEntity(ref, true));
|
|
290
290
|
});
|
|
291
291
|
|
|
292
|
-
// src/operations/
|
|
293
|
-
import {
|
|
292
|
+
// src/operations/moveBlocks.ts
|
|
293
|
+
import { Query as Query10, QueryChain as QueryChain5, writeOperation as writeOperation10 } from "roc-db";
|
|
294
|
+
|
|
295
|
+
// src/schemas/MoveBlocksMutationSchema.ts
|
|
296
|
+
import { mutationSchemaGenerator as mutationSchemaGenerator13 } from "roc-db";
|
|
294
297
|
import { z as z17 } from "zod";
|
|
295
|
-
var
|
|
298
|
+
var MoveBlocksMutationSchema = mutationSchemaGenerator13("moveBlocks", z17.object({
|
|
299
|
+
refs: z17.array(z17.union([BlockParagraphRefSchema, BlockRowRefSchema])),
|
|
300
|
+
targetPosition: z17.number().min(0)
|
|
301
|
+
}).strict(), undefined, true);
|
|
302
|
+
|
|
303
|
+
// src/operations/moveBlocks.ts
|
|
304
|
+
var moveBlocks = writeOperation10(MoveBlocksMutationSchema, undefined, (txn) => {
|
|
305
|
+
const { refs } = txn.payload;
|
|
306
|
+
return QueryChain5(Query10(() => txn.batchReadEntities(refs)), Query10((items) => {
|
|
307
|
+
return "todo";
|
|
308
|
+
}));
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// src/operations/readEntity.ts
|
|
312
|
+
import { NotFoundError, Query as Query11, QueryChain as QueryChain6, readOperation } from "roc-db";
|
|
313
|
+
import { z as z18 } from "zod";
|
|
314
|
+
var readEntity = readOperation("readEntity", z18.string(), z18.union([PostSchema, BlockImageSchema, BlockParagraphSchema]), (txn) => {
|
|
296
315
|
const ref = txn.payload;
|
|
297
|
-
return
|
|
316
|
+
return QueryChain6(Query11(() => txn.readEntity(ref)), Query11((entity) => {
|
|
298
317
|
if (!entity) {
|
|
299
318
|
throw new NotFoundError(ref);
|
|
300
319
|
}
|
|
@@ -303,36 +322,94 @@ var readEntity = readOperation("readEntity", z17.string(), z17.union([PostSchema
|
|
|
303
322
|
});
|
|
304
323
|
|
|
305
324
|
// src/operations/readPost.ts
|
|
306
|
-
import { Query as
|
|
325
|
+
import { Query as Query12, readOperation as readOperation2 } from "roc-db";
|
|
307
326
|
var readPost = readOperation2("readPost", PostRefSchema, PostSchema, (txn) => {
|
|
308
327
|
const ref = txn.payload;
|
|
309
|
-
return
|
|
328
|
+
return Query12(() => txn.readEntity(ref, true));
|
|
310
329
|
});
|
|
311
330
|
|
|
331
|
+
// src/operations/testTransactionalEdits.ts
|
|
332
|
+
import { Query as Query13, QueryChain as QueryChain7, writeOperation as writeOperation11 } from "roc-db";
|
|
333
|
+
|
|
334
|
+
// src/schemas/TestTransactionalEditsMutationSchema.ts
|
|
335
|
+
import { mutationSchemaGenerator as mutationSchemaGenerator14 } from "roc-db";
|
|
336
|
+
import { z as z19 } from "zod";
|
|
337
|
+
var TestTransactionalEditsMutationSchema = mutationSchemaGenerator14("testTransactionalEdits", z19.object({
|
|
338
|
+
name: z19.string().optional(),
|
|
339
|
+
post1ref: PostRefSchema.optional(),
|
|
340
|
+
post2ref: PostRefSchema.optional()
|
|
341
|
+
}).strict());
|
|
342
|
+
|
|
343
|
+
// src/operations/testTransactionalEdits.ts
|
|
344
|
+
import { expect } from "bun:test";
|
|
345
|
+
var TestCreatePatchDeleteInSameTransaction = (txn, name) => {
|
|
346
|
+
const postRef = txn.createRef("Post");
|
|
347
|
+
QueryChain7(Query13(() => txn.createEntity(postRef, { data: { name } })), Query13(() => txn.patchEntity(postRef, { data: { foo: "bar" } })), Query13((post) => {
|
|
348
|
+
expect(post.data.name).toBe(name);
|
|
349
|
+
expect(post.data.foo).toBe("bar");
|
|
350
|
+
}), Query13(() => txn.patchEntity(postRef, { data: { foo: null, bar: "foo" } })), Query13((post) => {
|
|
351
|
+
expect(post.data.name).toBe(name);
|
|
352
|
+
expect(post.data.foo).toBeUndefined();
|
|
353
|
+
expect(post.data.bar).toBe("foo");
|
|
354
|
+
expect(txn.log).toHaveLength(1);
|
|
355
|
+
expect(txn.log.get(postRef)[0]).toBe("create");
|
|
356
|
+
}), Query13((post) => txn.deleteEntity(postRef)), Query13((res) => {
|
|
357
|
+
expect(res).toBe(1);
|
|
358
|
+
expect(txn.log).toHaveLength(0);
|
|
359
|
+
}));
|
|
360
|
+
};
|
|
361
|
+
var TestUpdateAndDeleteInSameTransaction = (txn, ref) => {
|
|
362
|
+
return QueryChain7(Query13(() => txn.patchEntity(ref, { data: { foo: "bar" } })), Query13((post) => {
|
|
363
|
+
expect(post.data.foo).toBe("bar");
|
|
364
|
+
}), Query13(() => txn.patchEntity(ref, { data: { foo: null, bar: "foo" } })), Query13((post) => {
|
|
365
|
+
expect(post.data.foo).toBeUndefined();
|
|
366
|
+
expect(post.data.bar).toBe("foo");
|
|
367
|
+
expect(txn.log).toHaveLength(1);
|
|
368
|
+
expect(txn.log.get(ref)[0]).toBe("update");
|
|
369
|
+
}), Query13((post) => txn.deleteEntity(ref)), Query13((res) => {
|
|
370
|
+
expect(res).toBe(1);
|
|
371
|
+
expect(txn.log).toHaveLength(1);
|
|
372
|
+
expect(txn.log.get(ref)[0]).toBe("delete");
|
|
373
|
+
}));
|
|
374
|
+
};
|
|
375
|
+
var TestCreateOnExistingRef = (txn) => {
|
|
376
|
+
const ref = txn.createRef("Post");
|
|
377
|
+
return QueryChain7(Query13(() => txn.createEntity(ref, { data: { foo: "bar" } })), Query13(() => txn.createEntity(ref, { data: { foo: "bar" } })));
|
|
378
|
+
};
|
|
379
|
+
var testTransactionalEdits = writeOperation11(TestTransactionalEditsMutationSchema, PostSchema, (txn) => {
|
|
380
|
+
const { name, post1ref, post2ref } = txn.payload;
|
|
381
|
+
if (name)
|
|
382
|
+
return TestCreatePatchDeleteInSameTransaction(txn, name);
|
|
383
|
+
if (post1ref)
|
|
384
|
+
return TestUpdateAndDeleteInSameTransaction(txn, post1ref);
|
|
385
|
+
if (post2ref)
|
|
386
|
+
return TestCreateOnExistingRef(txn);
|
|
387
|
+
}, {});
|
|
388
|
+
|
|
312
389
|
// src/operations/updateBlockParagraph.ts
|
|
313
|
-
import { Query as
|
|
390
|
+
import { Query as Query14, writeOperation as writeOperation12 } from "roc-db";
|
|
314
391
|
|
|
315
392
|
// src/schemas/UpdateBlockParagraphMutationSchema.ts
|
|
316
|
-
import { mutationSchemaGenerator as
|
|
317
|
-
import { z as
|
|
318
|
-
var UpdateBlockParagraphMutationSchema =
|
|
393
|
+
import { mutationSchemaGenerator as mutationSchemaGenerator15 } from "roc-db";
|
|
394
|
+
import { z as z20 } from "zod";
|
|
395
|
+
var UpdateBlockParagraphMutationSchema = mutationSchemaGenerator15("updateBlockParagraph", z20.object({
|
|
319
396
|
ref: BlockParagraphRefSchema,
|
|
320
|
-
content:
|
|
397
|
+
content: z20.string()
|
|
321
398
|
}));
|
|
322
399
|
|
|
323
400
|
// src/operations/updateBlockParagraph.ts
|
|
324
|
-
var updateBlockParagraph =
|
|
401
|
+
var updateBlockParagraph = writeOperation12(UpdateBlockParagraphMutationSchema, BlockParagraphRefSchema, (txn) => {
|
|
325
402
|
const { ref, content } = txn.payload;
|
|
326
|
-
return
|
|
403
|
+
return Query14(() => txn.patchEntity(ref, {
|
|
327
404
|
data: { content }
|
|
328
405
|
}));
|
|
329
406
|
});
|
|
330
407
|
|
|
331
408
|
// src/operations/updatePost.ts
|
|
332
|
-
import { Query as
|
|
333
|
-
var updatePost =
|
|
409
|
+
import { Query as Query15, writeOperation as writeOperation13 } from "roc-db";
|
|
410
|
+
var updatePost = writeOperation13(UpdatePostMutationSchema, PostSchema, (txn) => {
|
|
334
411
|
const { ref, authorRef, ...data } = txn.payload;
|
|
335
|
-
return
|
|
412
|
+
return Query15(() => txn.updateEntity(ref, {
|
|
336
413
|
data,
|
|
337
414
|
parents: { author: authorRef },
|
|
338
415
|
children: { blocks: [] }
|
|
@@ -340,24 +417,24 @@ var updatePost = writeOperation11(UpdatePostMutationSchema, PostSchema, (txn) =>
|
|
|
340
417
|
});
|
|
341
418
|
|
|
342
419
|
// src/operations/updatePostDescription.ts
|
|
343
|
-
import { Query as
|
|
420
|
+
import { Query as Query16, writeOperation as writeOperation14 } from "roc-db";
|
|
344
421
|
|
|
345
422
|
// src/schemas/UpdatePostDescriptionMutationSchema.ts
|
|
346
|
-
import { mutationSchemaGenerator as
|
|
347
|
-
import { z as
|
|
348
|
-
var UpdatePostDescriptionMutationSchema =
|
|
423
|
+
import { mutationSchemaGenerator as mutationSchemaGenerator16 } from "roc-db";
|
|
424
|
+
import { z as z21 } from "zod";
|
|
425
|
+
var UpdatePostDescriptionMutationSchema = mutationSchemaGenerator16("updatePostDescription", z21.object({ ref: PostRefSchema, description: z21.string() }));
|
|
349
426
|
|
|
350
427
|
// src/operations/updatePostDescription.ts
|
|
351
|
-
var updatePostDescription =
|
|
428
|
+
var updatePostDescription = writeOperation14(UpdatePostDescriptionMutationSchema, PostSchema, (txn) => {
|
|
352
429
|
const { ref, description } = txn.payload;
|
|
353
|
-
return
|
|
430
|
+
return Query16(() => txn.patchEntity(ref, { data: { description } }));
|
|
354
431
|
}, { debounce: 10, changeSetOnly: true });
|
|
355
432
|
|
|
356
433
|
// src/operations/updatePostTitle.ts
|
|
357
|
-
import { Query as
|
|
358
|
-
var updatePostTitle =
|
|
434
|
+
import { Query as Query17, writeOperation as writeOperation15 } from "roc-db";
|
|
435
|
+
var updatePostTitle = writeOperation15(UpdatePostTitleMutationSchema, PostSchema, (txn) => {
|
|
359
436
|
const { ref, title } = txn.payload;
|
|
360
|
-
return
|
|
437
|
+
return Query17(() => txn.patchEntity(ref, { data: { title } }));
|
|
361
438
|
}, { debounce: 10 });
|
|
362
439
|
|
|
363
440
|
// src/operations/index.ts
|
|
@@ -371,199 +448,261 @@ var operations = [
|
|
|
371
448
|
createPost,
|
|
372
449
|
deleteBlock,
|
|
373
450
|
deletePost,
|
|
451
|
+
moveBlocks,
|
|
374
452
|
readEntity,
|
|
375
453
|
readPost,
|
|
454
|
+
testTransactionalEdits,
|
|
376
455
|
updateBlockParagraph,
|
|
377
456
|
updatePost,
|
|
378
457
|
updatePostDescription,
|
|
379
458
|
updatePostTitle
|
|
380
459
|
];
|
|
381
460
|
// src/testAdapterImplementation.ts
|
|
382
|
-
import { beforeAll, describe, expect, test } from "bun:test";
|
|
461
|
+
import { beforeAll, describe, expect as expect2, test } from "bun:test";
|
|
383
462
|
import { BadRequestError, NotFoundError as NotFoundError2 } from "roc-db";
|
|
384
|
-
var prepareChangeSetTest = async (adapter) => {
|
|
385
|
-
const [post] = await adapter.createPost({
|
|
463
|
+
var prepareChangeSetTest = async (adapter, adapter2) => {
|
|
464
|
+
const [post, createPostMutation] = await adapter.createPost({
|
|
386
465
|
title: "Title 1",
|
|
387
466
|
slug: "title-1",
|
|
388
467
|
tags: ["Foo", "Bar"]
|
|
389
468
|
});
|
|
390
|
-
|
|
469
|
+
expect2(createPostMutation.log).toStrictEqual([[post.ref, "create"]]);
|
|
470
|
+
const [draft, createDraftMutation] = await adapter.createDraft({
|
|
391
471
|
postRef: post.ref
|
|
392
472
|
});
|
|
473
|
+
expect2(createDraftMutation.log).toStrictEqual([[draft.ref, "create"]]);
|
|
393
474
|
const changeSetAdapter = adapter.changeSet(draft.ref);
|
|
394
|
-
const [
|
|
475
|
+
const [
|
|
476
|
+
{ block: blockParagraph1, updatedParent: updatedPost },
|
|
477
|
+
createBlockParagraphMutation
|
|
478
|
+
] = await changeSetAdapter.createBlockParagraph({
|
|
395
479
|
parentRef: post.ref
|
|
396
480
|
});
|
|
397
|
-
|
|
481
|
+
expect2(updatedPost.children.blocks).toStrictEqual([blockParagraph1.ref]);
|
|
482
|
+
expect2(updatedPost.children.blocks).toHaveLength(1);
|
|
483
|
+
expect2(createBlockParagraphMutation.log[0][2].children.blocks).toStrictEqual([]);
|
|
484
|
+
const readPost1 = await changeSetAdapter.readEntity(post.ref);
|
|
485
|
+
expect2(readPost1.children.blocks).toHaveLength(1);
|
|
486
|
+
const [{ block: blockRow, updatedParent: updatedPost2 }, mutation] = await changeSetAdapter.createBlockRow({
|
|
398
487
|
parentRef: post.ref
|
|
399
488
|
});
|
|
400
|
-
|
|
489
|
+
expect2(updatedPost2.children.blocks).toHaveLength(2);
|
|
490
|
+
const readPost2 = await changeSetAdapter.readEntity(post.ref);
|
|
491
|
+
expect2(readPost2.children.blocks).toHaveLength(2);
|
|
492
|
+
const [{ block: blockParagraph2, updatedParent: updatedBlockRow }] = await changeSetAdapter.createBlockParagraph({
|
|
401
493
|
parentRef: blockRow.ref
|
|
402
494
|
});
|
|
495
|
+
const readPost3 = await changeSetAdapter.readEntity(post.ref);
|
|
496
|
+
expect2(readPost3.children.blocks).toHaveLength(2);
|
|
403
497
|
return {
|
|
404
498
|
postRef: post.ref,
|
|
405
499
|
draftRef: draft.ref,
|
|
406
500
|
changeSetAdapter,
|
|
407
501
|
blockParagraph1,
|
|
408
502
|
blockParagraph2,
|
|
409
|
-
blockRow,
|
|
410
|
-
|
|
503
|
+
blockRow: updatedBlockRow,
|
|
504
|
+
draft,
|
|
505
|
+
post: readPost3
|
|
411
506
|
};
|
|
412
507
|
};
|
|
413
|
-
var testAdapterImplementation = (adapterConstructor,
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
operations,
|
|
417
|
-
entities,
|
|
418
|
-
session: { identityRef: "User/42" },
|
|
419
|
-
...engineArgsAdapter1
|
|
420
|
-
});
|
|
421
|
-
const adapter2 = adapterConstructor({
|
|
508
|
+
var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
|
|
509
|
+
let createAdapter = async () => {
|
|
510
|
+
return adapterConstructor({
|
|
422
511
|
operations,
|
|
423
512
|
entities,
|
|
424
513
|
session: { identityRef: "User/42" },
|
|
425
|
-
...
|
|
514
|
+
...await generateArgs()
|
|
426
515
|
});
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
expect(post).toMatchZodSchema(PostSchema);
|
|
443
|
-
expect(post.data.title).toBe("Title 1");
|
|
444
|
-
expect(post.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
445
|
-
expect(createPostMutation).toMatchZodSchema(CreatePostMutationSchema);
|
|
446
|
-
});
|
|
447
|
-
test("read (readEntity function)", async () => {
|
|
448
|
-
const readPostRes = await adapter1.readPost(postRef);
|
|
449
|
-
expect(readPostRes.data.title).toStrictEqual("Title 1");
|
|
450
|
-
expect(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
451
|
-
expect(readPostRes).toMatchZodSchema(PostSchema);
|
|
452
|
-
});
|
|
453
|
-
test("read not found (readEntity function)", async () => {
|
|
454
|
-
expect(() => adapter1.readPost("Post/999")).toThrow(NotFoundError2);
|
|
455
|
-
});
|
|
456
|
-
test("update (updateEntity function)", async () => {
|
|
457
|
-
const [post2] = await adapter1.updatePost({
|
|
458
|
-
ref: postRef,
|
|
459
|
-
title: "Title 2",
|
|
460
|
-
tags: ["Foo"]
|
|
461
|
-
});
|
|
462
|
-
expect(post2.data.tags).toStrictEqual(["Foo"]);
|
|
463
|
-
expect(post2.data.title).toBe("Title 2");
|
|
464
|
-
expect(post2).toMatchZodSchema(PostSchema);
|
|
465
|
-
});
|
|
466
|
-
test("updateTitle (patchEntity function + debounce)", async () => {
|
|
467
|
-
const [update1, mutation1] = await adapter1.updatePostTitle({
|
|
468
|
-
ref: postRef,
|
|
469
|
-
title: "Title 3"
|
|
470
|
-
});
|
|
471
|
-
expect(update1).toMatchZodSchema(PostSchema);
|
|
472
|
-
expect(mutation1).toMatchZodSchema(UpdatePostTitleMutationSchema);
|
|
473
|
-
const [update2, mutation2] = await adapter1.updatePostTitle({
|
|
474
|
-
ref: postRef,
|
|
475
|
-
title: "Title 4"
|
|
476
|
-
});
|
|
477
|
-
expect(update2).toMatchZodSchema(PostSchema);
|
|
478
|
-
expect(mutation2).toMatchZodSchema(UpdatePostTitleMutationSchema);
|
|
479
|
-
expect(mutation1.ref).toBe(mutation2.ref);
|
|
480
|
-
expect(mutation2.timestamp >= mutation1.timestamp).toBeTrue();
|
|
516
|
+
};
|
|
517
|
+
let adapter1, adapter2;
|
|
518
|
+
beforeAll(async () => {
|
|
519
|
+
adapter1 = await createAdapter();
|
|
520
|
+
adapter2 = await createAdapter();
|
|
521
|
+
});
|
|
522
|
+
describe("Post CRUD", () => {
|
|
523
|
+
let postRef;
|
|
524
|
+
let post;
|
|
525
|
+
let createPostMutation;
|
|
526
|
+
beforeAll(async () => {
|
|
527
|
+
const createPostRes = await adapter1.createPost({
|
|
528
|
+
title: "Title 1",
|
|
529
|
+
slug: "title-1",
|
|
530
|
+
tags: ["Foo", "Bar"]
|
|
481
531
|
});
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
532
|
+
post = createPostRes[0];
|
|
533
|
+
postRef = createPostRes[0].ref;
|
|
534
|
+
createPostMutation = createPostRes[1];
|
|
535
|
+
});
|
|
536
|
+
test("create (createEntity function)", async () => {
|
|
537
|
+
expect2(post).toMatchZodSchema(PostSchema);
|
|
538
|
+
expect2(post.data.title).toBe("Title 1");
|
|
539
|
+
expect2(post.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
540
|
+
expect2(createPostMutation).toMatchZodSchema(CreatePostMutationSchema);
|
|
541
|
+
});
|
|
542
|
+
test("read (readEntity function)", async () => {
|
|
543
|
+
const readPostRes = await adapter1.readPost(postRef);
|
|
544
|
+
expect2(readPostRes.data.title).toStrictEqual("Title 1");
|
|
545
|
+
expect2(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
546
|
+
expect2(readPostRes).toMatchZodSchema(PostSchema);
|
|
547
|
+
});
|
|
548
|
+
test("read not found (readEntity function)", async () => {
|
|
549
|
+
expect2(() => adapter1.readPost("Post/999")).toThrow(NotFoundError2);
|
|
550
|
+
});
|
|
551
|
+
test.todo("update (updateEntity function)", async () => {
|
|
552
|
+
const [post2] = await adapter1.updatePost({
|
|
553
|
+
ref: postRef,
|
|
554
|
+
title: "Title 2",
|
|
555
|
+
tags: ["Foo"]
|
|
487
556
|
});
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
557
|
+
expect2(post2.data.tags).toStrictEqual(["Foo"]);
|
|
558
|
+
expect2(post2.data.title).toBe("Title 2");
|
|
559
|
+
expect2(post2).toMatchZodSchema(PostSchema);
|
|
560
|
+
});
|
|
561
|
+
test("updateTitle (patchEntity function + debounce)", async () => {
|
|
562
|
+
const [update1, mutation1] = await adapter1.updatePostTitle({
|
|
563
|
+
ref: postRef,
|
|
564
|
+
title: "Title 3"
|
|
492
565
|
});
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
566
|
+
expect2(update1).toMatchZodSchema(PostSchema);
|
|
567
|
+
expect2(mutation1).toMatchZodSchema(UpdatePostTitleMutationSchema);
|
|
568
|
+
const [update2, mutation2] = await adapter1.updatePostTitle({
|
|
569
|
+
ref: postRef,
|
|
570
|
+
title: "Title 4"
|
|
498
571
|
});
|
|
572
|
+
expect2(update2).toMatchZodSchema(PostSchema);
|
|
573
|
+
expect2(mutation2).toMatchZodSchema(UpdatePostTitleMutationSchema);
|
|
574
|
+
expect2(mutation1.ref).toBe(mutation2.ref);
|
|
575
|
+
expect2(mutation2.timestamp >= mutation1.timestamp).toBeTrue();
|
|
576
|
+
});
|
|
577
|
+
test("updatePostDescription without changeSetAdapter fails with BadRequestError", async () => {
|
|
578
|
+
expect2(() => adapter1.updatePostDescription({
|
|
579
|
+
ref: postRef,
|
|
580
|
+
description: "Description 1"
|
|
581
|
+
})).toThrow(BadRequestError);
|
|
499
582
|
});
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
583
|
+
test("delete (deleteEntity function)", async () => {
|
|
584
|
+
const currentPost = await adapter1.readPost(postRef);
|
|
585
|
+
expect2(currentPost.ref).toBe(postRef);
|
|
586
|
+
const [count, mutation] = await adapter1.deletePost(postRef);
|
|
587
|
+
expect2(count).toBe(1);
|
|
588
|
+
expect2(mutation.log).toStrictEqual([
|
|
589
|
+
[postRef, "delete", currentPost]
|
|
590
|
+
]);
|
|
591
|
+
expect2(() => adapter1.readPost(postRef)).toThrow(NotFoundError2);
|
|
592
|
+
});
|
|
593
|
+
test("sync mutation", async () => {
|
|
594
|
+
const res = await adapter2.syncOptimisticMutation(createPostMutation);
|
|
595
|
+
expect2(res[0]).toStrictEqual(post);
|
|
596
|
+
expect2(res[1]).toStrictEqual(createPostMutation);
|
|
597
|
+
expect2(() => adapter2.syncOptimisticMutation(createPostMutation)).toThrowError(BadRequestError);
|
|
598
|
+
});
|
|
599
|
+
test("create, patch and delete the same item within the same transaction", async () => {
|
|
600
|
+
const [post1] = await adapter1.createPost({ title: "Post 1" });
|
|
601
|
+
const [post2] = await adapter1.createPost({ title: "Post 1" });
|
|
602
|
+
const [currentPost, mutation] = await adapter1.testTransactionalEdits({
|
|
603
|
+
name: "Test"
|
|
512
604
|
});
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
605
|
+
expect2(mutation.log).toHaveLength(0);
|
|
606
|
+
const [, mutation2] = await adapter1.testTransactionalEdits({
|
|
607
|
+
post1ref: post1.ref
|
|
516
608
|
});
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
609
|
+
expect2(mutation2.log).toHaveLength(1);
|
|
610
|
+
expect2(mutation2.log[0][1]).toBe("delete");
|
|
611
|
+
expect2(() => adapter1.testTransactionalEdits({
|
|
612
|
+
post2ref: post2.ref
|
|
613
|
+
})).toThrow(BadRequestError);
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
describe("changeSet", () => {
|
|
617
|
+
let postRef, draftRef, changeSetAdapter, blockParagraph1, post, blockRow, blockParagraph2, draft;
|
|
618
|
+
beforeAll(async () => {
|
|
619
|
+
({
|
|
620
|
+
postRef,
|
|
621
|
+
draftRef,
|
|
622
|
+
changeSetAdapter,
|
|
623
|
+
blockParagraph1,
|
|
624
|
+
post,
|
|
625
|
+
blockRow,
|
|
626
|
+
blockParagraph2,
|
|
627
|
+
draft
|
|
628
|
+
} = await prepareChangeSetTest(adapter1, adapter2));
|
|
629
|
+
});
|
|
630
|
+
test("create (createEntity function w/changeSetRef)", async () => {
|
|
631
|
+
expect2(blockParagraph1).toMatchZodSchema(BlockParagraphSchema);
|
|
632
|
+
expect2(post).toMatchZodSchema(PostSchema);
|
|
633
|
+
});
|
|
634
|
+
test("read (readEntity function w/changeSetRef)", async () => {
|
|
635
|
+
const read = await changeSetAdapter.readEntity(blockParagraph1.ref);
|
|
636
|
+
expect2(read).toMatchZodSchema(BlockParagraphSchema);
|
|
637
|
+
});
|
|
638
|
+
test("update (patchEntity function w/changeSetRef)", async () => {
|
|
639
|
+
const [updatedBlock] = await changeSetAdapter.updateBlockParagraph({
|
|
640
|
+
ref: blockParagraph1.ref,
|
|
641
|
+
content: "Hello, world!"
|
|
520
642
|
});
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
643
|
+
expect2(updatedBlock).toMatchZodSchema(BlockParagraphSchema);
|
|
644
|
+
});
|
|
645
|
+
test("move (batchReadEntities function)", async () => {
|
|
646
|
+
const res = await changeSetAdapter.moveBlocks({
|
|
647
|
+
refs: [blockParagraph1.ref],
|
|
648
|
+
targetPosition: 1
|
|
527
649
|
});
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
]
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
650
|
+
});
|
|
651
|
+
test("delete (with cascade delete)", async () => {
|
|
652
|
+
const postUpdated = await changeSetAdapter.readEntity(postRef);
|
|
653
|
+
const blockParagraph1Update = await changeSetAdapter.readEntity(blockParagraph1.ref);
|
|
654
|
+
const blockRowUpdated = await changeSetAdapter.readEntity(blockRow.ref);
|
|
655
|
+
const [count, mutation] = await changeSetAdapter.deletePost(postRef);
|
|
656
|
+
expect2(count).toBe(4);
|
|
657
|
+
expect2(mutation.log).toStrictEqual([
|
|
658
|
+
[blockParagraph1.ref, "delete", blockParagraph1Update],
|
|
659
|
+
[blockParagraph2.ref, "delete", blockParagraph2],
|
|
660
|
+
[blockRow.ref, "delete", blockRowUpdated],
|
|
661
|
+
[postRef, "delete", postUpdated]
|
|
662
|
+
]);
|
|
663
|
+
await expect2(() => changeSetAdapter.readEntity(blockParagraph1.ref)).toThrow(NotFoundError2);
|
|
664
|
+
await expect2(() => changeSetAdapter.updateBlockParagraph({
|
|
665
|
+
ref: blockParagraph1.ref,
|
|
666
|
+
content: "Foo"
|
|
667
|
+
})).toThrow(NotFoundError2);
|
|
668
|
+
});
|
|
669
|
+
test("pageMutations", async () => {
|
|
670
|
+
const res = await changeSetAdapter.pageMutations({
|
|
671
|
+
changeSetRef: draftRef
|
|
542
672
|
});
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
673
|
+
expect2(res.length).toBeGreaterThan(0);
|
|
674
|
+
expect2(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
|
|
675
|
+
});
|
|
676
|
+
test("pageMutations run again", async () => {
|
|
677
|
+
const res = await changeSetAdapter.pageMutations({
|
|
678
|
+
changeSetRef: draftRef
|
|
549
679
|
});
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
680
|
+
expect2(res.length).toBeGreaterThan(0);
|
|
681
|
+
expect2(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
|
|
682
|
+
});
|
|
683
|
+
test("applyDraft", async () => {
|
|
684
|
+
const { draftRef: draftRef2 } = await prepareChangeSetTest(adapter1);
|
|
685
|
+
const [version, mutation] = await adapter1.applyDraft({
|
|
686
|
+
ref: draftRef2
|
|
556
687
|
});
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
688
|
+
});
|
|
689
|
+
test("init adapter2", async () => {
|
|
690
|
+
const adapterA = await createAdapter();
|
|
691
|
+
const adapterB = await createAdapter();
|
|
692
|
+
const { draftRef: draftRef2 } = await prepareChangeSetTest(adapterA, adapterB);
|
|
693
|
+
const mutations = await adapterA.pageMutations({
|
|
694
|
+
changeSetRef: draftRef2
|
|
564
695
|
});
|
|
696
|
+
const allMutationsAdapter1 = await adapterA.pageMutations({});
|
|
697
|
+
const allMutationsAdapter2 = await adapterB.pageMutations({});
|
|
698
|
+
expect2(allMutationsAdapter1).not.toBeEmpty();
|
|
699
|
+
expect2(allMutationsAdapter2).toBeEmpty();
|
|
700
|
+
const res = await adapterB.loadOptimisticMutations(allMutationsAdapter1);
|
|
701
|
+
const allMutationsAdapter2after = await adapterB.pageMutations({});
|
|
702
|
+
expect2(allMutationsAdapter2after.length).toBe(allMutationsAdapter1.length);
|
|
703
|
+
const res2 = await adapterB.loadOptimisticMutations(allMutationsAdapter1);
|
|
565
704
|
});
|
|
566
|
-
};
|
|
705
|
+
});
|
|
567
706
|
};
|
|
568
707
|
// src/inMemoryAdapter.ts
|
|
569
708
|
import { createInMemoryAdapter } from "@roc-db/in-memory";
|
|
@@ -5,7 +5,7 @@ export declare const createBlockParagrah: import("roc-db").WriteOperation<"creat
|
|
|
5
5
|
payload: {
|
|
6
6
|
parentRef: `Post/${string}` | `BlockRow/${string}`;
|
|
7
7
|
};
|
|
8
|
-
log: [
|
|
8
|
+
log: any[];
|
|
9
9
|
debounceCount: number;
|
|
10
10
|
identityRef: string;
|
|
11
11
|
name: "createBlockParagraph";
|
|
@@ -5,7 +5,7 @@ export declare const createBlockRow: import("roc-db").WriteOperation<"createBloc
|
|
|
5
5
|
payload: {
|
|
6
6
|
parentRef: `Post/${string}` | `BlockRow/${string}`;
|
|
7
7
|
};
|
|
8
|
-
log: [
|
|
8
|
+
log: any[];
|
|
9
9
|
debounceCount: number;
|
|
10
10
|
identityRef: string;
|
|
11
11
|
name: "createBlockRow";
|
|
@@ -5,7 +5,7 @@ export declare const createBlockTitle: import("roc-db").WriteOperation<"createBl
|
|
|
5
5
|
payload: {
|
|
6
6
|
parentRef: `Post/${string}` | `BlockRow/${string}`;
|
|
7
7
|
};
|
|
8
|
-
log: [
|
|
8
|
+
log: any[];
|
|
9
9
|
debounceCount: number;
|
|
10
10
|
identityRef: string;
|
|
11
11
|
name: "createBlockTitle";
|