gt-sanity 0.0.6 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/index.d.mts +95 -73
  3. package/dist/index.d.ts +95 -73
  4. package/dist/index.js +6233 -1162
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +6292 -1193
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +9 -4
  9. package/src/adapter/core.ts +41 -4
  10. package/src/adapter/getLocales.ts +2 -2
  11. package/src/components/TranslationsProvider.tsx +942 -0
  12. package/src/components/page/BatchProgress.tsx +27 -0
  13. package/src/components/page/ImportAllDialog.tsx +51 -0
  14. package/src/components/page/ImportMissingDialog.tsx +55 -0
  15. package/src/components/page/TranslateAllDialog.tsx +55 -0
  16. package/src/components/page/TranslationsTable.tsx +81 -0
  17. package/src/components/page/TranslationsTool.tsx +299 -837
  18. package/src/components/shared/BaseTranslationWrapper.tsx +82 -0
  19. package/src/components/shared/LocaleCheckbox.tsx +47 -0
  20. package/src/components/shared/SingleDocumentView.tsx +108 -0
  21. package/src/components/tab/TranslationView.tsx +379 -0
  22. package/src/components/tab/TranslationsTab.tsx +25 -0
  23. package/src/configuration/baseDocumentLevelConfig/documentLevelPatch.ts +6 -9
  24. package/src/configuration/baseDocumentLevelConfig/helpers/createI18nDocAndPatchMetadata.ts +5 -24
  25. package/src/configuration/baseDocumentLevelConfig/helpers/patchI18nDoc.ts +3 -23
  26. package/src/configuration/baseDocumentLevelConfig/index.ts +16 -68
  27. package/src/configuration/baseFieldLevelConfig.ts +15 -50
  28. package/src/index.ts +29 -43
  29. package/src/sanity-api/findDocuments.ts +44 -0
  30. package/src/sanity-api/publishDocuments.ts +49 -0
  31. package/src/sanity-api/resolveRefs.ts +146 -0
  32. package/src/serialization/BaseDocumentMerger.ts +138 -0
  33. package/src/serialization/BaseSerializationConfig.ts +220 -0
  34. package/src/serialization/__tests__/BaseDocumentDeserializer/__snapshots__/documentLevelDeserialization.test.ts.snap +189 -0
  35. package/src/serialization/__tests__/BaseDocumentDeserializer/__snapshots__/fieldLevelDeserialization.test.ts.snap +107 -0
  36. package/src/serialization/__tests__/BaseDocumentDeserializer/baseDeserialization.test.ts +397 -0
  37. package/src/serialization/__tests__/BaseDocumentDeserializer/documentLevelDeserialization.test.ts +107 -0
  38. package/src/serialization/__tests__/BaseDocumentDeserializer/fieldLevelDeserialization.test.ts +107 -0
  39. package/src/serialization/__tests__/BaseDocumentMerger/__snapshots__/documentLevelMerge.test.ts.snap +193 -0
  40. package/src/serialization/__tests__/BaseDocumentMerger/__snapshots__/fieldLevelMerge.test.ts.snap +97 -0
  41. package/src/serialization/__tests__/BaseDocumentMerger/baseMerge.test.ts +36 -0
  42. package/src/serialization/__tests__/BaseDocumentMerger/documentLevelMerge.test.ts +96 -0
  43. package/src/serialization/__tests__/BaseDocumentMerger/fieldLevelMerge.test.ts +142 -0
  44. package/src/serialization/__tests__/BaseDocumentMerger/utils.ts +52 -0
  45. package/src/serialization/__tests__/BaseDocumentSerializer/__snapshots__/documentInlineMarks.test.ts.snap +39 -0
  46. package/src/serialization/__tests__/BaseDocumentSerializer/__snapshots__/documentLevelSerialization.test.ts.snap +8 -0
  47. package/src/serialization/__tests__/BaseDocumentSerializer/__snapshots__/fieldLevelSerialization.test.ts.snap +8 -0
  48. package/src/serialization/__tests__/BaseDocumentSerializer/baseSerialization.test.ts +345 -0
  49. package/src/serialization/__tests__/BaseDocumentSerializer/documentInlineMarks.test.ts +53 -0
  50. package/src/serialization/__tests__/BaseDocumentSerializer/documentLevelSerialization.test.ts +120 -0
  51. package/src/serialization/__tests__/BaseDocumentSerializer/fieldLevelSerialization.test.ts +153 -0
  52. package/src/serialization/__tests__/BaseDocumentSerializer/utils.ts +27 -0
  53. package/src/serialization/__tests__/README +2 -0
  54. package/src/serialization/__tests__/__fixtures__/annotationAndInlineBlocks.json +140 -0
  55. package/src/serialization/__tests__/__fixtures__/customStyles.json +62 -0
  56. package/src/serialization/__tests__/__fixtures__/documentInlineMarks.json +70 -0
  57. package/src/serialization/__tests__/__fixtures__/documentLevelArticle.json +185 -0
  58. package/src/serialization/__tests__/__fixtures__/fieldLevelArticle.json +107 -0
  59. package/src/serialization/__tests__/__fixtures__/inlineDocumentLevelArticle.json +134 -0
  60. package/src/serialization/__tests__/__fixtures__/inlineSchema.ts +270 -0
  61. package/src/serialization/__tests__/__fixtures__/messy-html.html +26 -0
  62. package/src/serialization/__tests__/__fixtures__/nestedLanguageFields.json +54 -0
  63. package/src/serialization/__tests__/__fixtures__/schema.ts +310 -0
  64. package/src/serialization/__tests__/global.setup.ts +40 -0
  65. package/src/serialization/__tests__/helpers.ts +132 -0
  66. package/src/serialization/data.ts +82 -0
  67. package/src/serialization/deserialize/BaseDocumentDeserializer.ts +171 -0
  68. package/src/serialization/deserialize/helpers.ts +42 -0
  69. package/src/serialization/helpers.ts +18 -0
  70. package/src/serialization/index.ts +11 -0
  71. package/src/serialization/serialize/fieldFilters.ts +124 -0
  72. package/src/serialization/serialize/index.ts +284 -0
  73. package/src/serialization/types.ts +41 -0
  74. package/src/translation/importDocument.ts +4 -5
  75. package/src/translation/uploadFiles.ts +1 -1
  76. package/src/types.ts +3 -19
  77. package/src/utils/batchProcessor.ts +111 -0
  78. package/src/utils/importUtils.ts +95 -0
  79. package/src/utils/serialize.ts +25 -5
  80. package/src/utils/shared.ts +1 -1
  81. package/src/adapter/index.ts +0 -13
  82. package/src/components/NewTask.tsx +0 -251
  83. package/src/components/TaskView.tsx +0 -257
  84. package/src/components/TranslationContext.tsx +0 -24
  85. package/src/components/TranslationView.tsx +0 -114
  86. package/src/components/TranslationsTab.tsx +0 -181
  87. /package/src/components/{LanguageStatus.tsx → shared/LanguageStatus.tsx} +0 -0
  88. /package/src/components/{ProgressBar.tsx → shared/ProgressBar.tsx} +0 -0
@@ -0,0 +1,107 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Global test of working field-level functionality and snapshot match 1`] = `
4
+ {
5
+ "_id": "drafts.2947533e-1ea5-4116-955b-339608d3445d",
6
+ "_rev": "l58oha-n06-1s4-f6i-74g6cuakl",
7
+ "_type": "fieldLevelArticle",
8
+ "config": {
9
+ "en": {
10
+ "_type": "objectField",
11
+ "nestedArrayField": [
12
+ {
13
+ "_key": "f49b4d7e3e51",
14
+ "_type": "block",
15
+ "children": [
16
+ {
17
+ "_key": "randomKey-16",
18
+ "_type": "span",
19
+ "marks": [],
20
+ "text": "This is block text 1 level deep",
21
+ },
22
+ ],
23
+ "markDefs": [],
24
+ "style": "normal",
25
+ },
26
+ ],
27
+ "objectAsField": {
28
+ "_type": "childObjectField",
29
+ "content": [
30
+ {
31
+ "_key": "869168fe3a2a",
32
+ "_type": "block",
33
+ "children": [
34
+ {
35
+ "_key": "randomKey-14",
36
+ "_type": "span",
37
+ "marks": [],
38
+ "text": "This is block text 2 levels deep",
39
+ },
40
+ ],
41
+ "markDefs": [],
42
+ "style": "normal",
43
+ },
44
+ ],
45
+ "title": "This is one level deeper",
46
+ },
47
+ "title": "This is an object nested in a document",
48
+ },
49
+ },
50
+ "content": {
51
+ "en": [
52
+ {
53
+ "_key": "e2a39d768ff8",
54
+ "_type": "block",
55
+ "children": [
56
+ {
57
+ "_key": "randomKey-18",
58
+ "_type": "span",
59
+ "marks": [],
60
+ "text": "This is block text at the top level.",
61
+ },
62
+ ],
63
+ "markDefs": [],
64
+ "style": "normal",
65
+ },
66
+ {
67
+ "_key": "271b0c6ee984",
68
+ "_type": "objectField",
69
+ "objectAsField": {
70
+ "_type": "childObjectField",
71
+ "content": [
72
+ {
73
+ "_key": "4f24f6fbfae7",
74
+ "_type": "block",
75
+ "children": [
76
+ {
77
+ "_key": "randomKey-24",
78
+ "_type": "span",
79
+ "marks": [],
80
+ "text": "This is block text in a nested object in an object in top-level block text.",
81
+ },
82
+ ],
83
+ "markDefs": [],
84
+ "style": "normal",
85
+ },
86
+ ],
87
+ "title": "This is a nested object in an object in top-level block text.",
88
+ },
89
+ "title": "This is an object in top-level block text.",
90
+ },
91
+ ],
92
+ },
93
+ "snippet": {
94
+ "en": "This is text in my text field",
95
+ },
96
+ "tags": {
97
+ "en": [
98
+ "tag 1",
99
+ "tag 2",
100
+ "tag 3",
101
+ ],
102
+ },
103
+ "title": {
104
+ "en": "My Field-Level Article",
105
+ },
106
+ }
107
+ `;
@@ -0,0 +1,397 @@
1
+ import { readFileSync } from 'fs';
2
+ import {
3
+ PortableTextBlock,
4
+ PortableTextObject,
5
+ PortableTextSpan,
6
+ PortableTextTextBlock,
7
+ } from 'sanity';
8
+ import { beforeEach, expect, test, vi } from 'vitest';
9
+ import {
10
+ BaseDocumentDeserializer,
11
+ BaseDocumentSerializer,
12
+ customBlockDeserializers,
13
+ defaultStopTypes,
14
+ } from '../../index';
15
+ import {
16
+ annotationAndInlineBlocks,
17
+ documentLevelArticle,
18
+ inlineDocumentLevelArticle,
19
+ inlineSchema,
20
+ schema,
21
+ } from '../BaseDocumentSerializer/utils';
22
+ import {
23
+ addedBlockDeserializers,
24
+ addedCustomDeserializers,
25
+ addedCustomSerializers,
26
+ getDeserialized,
27
+ } from '../helpers';
28
+
29
+ const customStyles = require('../__fixtures__/customStyles');
30
+
31
+ let mockTestKey = 0;
32
+
33
+ vi.mock('@portabletext/block-tools', async () => {
34
+ const originalModule = await vi.importActual<
35
+ typeof import('@portabletext/block-tools')
36
+ >('@portabletext/block-tools');
37
+ return {
38
+ ...originalModule,
39
+ //not ideal but vi.mock('@portabletext/block-tools/src/util/randomKey.ts' is not working
40
+ htmlToBlocks: (html: string, blockContentType: any, options: any) => {
41
+ const blocks = originalModule.htmlToBlocks(
42
+ html,
43
+ blockContentType,
44
+ options
45
+ );
46
+ const newBlocks = blocks.map((block) => {
47
+ const newChildren = (
48
+ block as unknown as PortableTextTextBlock<
49
+ PortableTextSpan | PortableTextObject
50
+ >
51
+ ).children.map((child) => {
52
+ return { ...child, _key: `randomKey-${mockTestKey++}` };
53
+ });
54
+ return {
55
+ ...block,
56
+ children: newChildren,
57
+ _key: `randomKey-${mockTestKey++}`,
58
+ };
59
+ });
60
+ return newBlocks;
61
+ },
62
+ };
63
+ });
64
+
65
+ beforeEach(() => {
66
+ mockTestKey = 0;
67
+ });
68
+
69
+ test('Contains id of original document', () => {
70
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
71
+ const id = deserialized._id;
72
+ expect(id).toEqual(documentLevelArticle._id);
73
+ });
74
+
75
+ test('Contains rev of original document', () => {
76
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
77
+ const rev = deserialized._rev;
78
+ expect(rev).toEqual(documentLevelArticle._rev);
79
+ });
80
+
81
+ test('Contains type of original document', () => {
82
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
83
+ const type = deserialized._type;
84
+ expect(type).toEqual(documentLevelArticle._type);
85
+ });
86
+
87
+ /*
88
+ * CUSTOM SETTINGS
89
+ */
90
+
91
+ test('Custom deserialization should manifest at all levels', () => {
92
+ const serialized = BaseDocumentSerializer(schema).serializeDocument(
93
+ documentLevelArticle,
94
+ 'document',
95
+ 'en',
96
+ defaultStopTypes,
97
+ addedCustomSerializers
98
+ );
99
+
100
+ const deserialized = BaseDocumentDeserializer.deserializeDocument(
101
+ serialized.content,
102
+ addedCustomDeserializers,
103
+ customBlockDeserializers
104
+ );
105
+ expect(deserialized.config.title).toEqual(documentLevelArticle.config.title);
106
+ expect(deserialized.config._type).toEqual(documentLevelArticle.config._type);
107
+
108
+ const origArrayObj = documentLevelArticle.content.find(
109
+ (b: Record<string, any>) => b._type === 'objectField'
110
+ );
111
+ const deserializedArrayObj = deserialized.content.find(
112
+ (b: Record<string, any>) => b._type === 'objectField'
113
+ );
114
+
115
+ expect(deserializedArrayObj.title).toEqual(origArrayObj.title);
116
+ expect(deserializedArrayObj._key).toEqual(origArrayObj._key);
117
+ });
118
+
119
+ test('Content with custom styles deserializes correctly and maintains style', () => {
120
+ vi.spyOn(console, 'warn').mockImplementation(() => {});
121
+
122
+ const customStyledDocument = {
123
+ ...documentLevelArticle,
124
+ ...customStyles,
125
+ };
126
+
127
+ const serialized = BaseDocumentSerializer(schema).serializeDocument(
128
+ customStyledDocument,
129
+ 'document'
130
+ );
131
+
132
+ const deserialized = BaseDocumentDeserializer.deserializeDocument(
133
+ serialized.content
134
+ );
135
+ const origCustomStyleBlock = customStyledDocument.content.find(
136
+ (b: Record<string, any>) => b._type === 'block' && b.style === 'custom1'
137
+ );
138
+ const origCustomStyleListItem = customStyledDocument.content.find(
139
+ (b: Record<string, any>) =>
140
+ b._type === 'block' && b.listItem === 'number' && b.style === 'custom1'
141
+ );
142
+ const deserializedCustomStyleBlock = deserialized.content.find(
143
+ (b: Record<string, any>) => b._type === 'block' && b.style === 'custom1'
144
+ );
145
+ const deserializedCustomStyleListItem = deserialized.content.find(
146
+ (b: Record<string, any>) =>
147
+ b._type === 'block' && b.listItem === 'number' && b.style === 'custom1'
148
+ );
149
+
150
+ expect(deserializedCustomStyleBlock.children[0].text).toEqual(
151
+ origCustomStyleBlock.children[0].text
152
+ );
153
+
154
+ expect(deserializedCustomStyleListItem.children[0].text).toEqual(
155
+ origCustomStyleListItem.children[0].text
156
+ );
157
+ });
158
+
159
+ //test -- unhandled annotations and inlines don't break when they get deserialized back
160
+ test('Handled inline objects should be accurately deserialized', () => {
161
+ const inlineDocument = {
162
+ ...documentLevelArticle,
163
+ ...annotationAndInlineBlocks,
164
+ };
165
+
166
+ const serialized = BaseDocumentSerializer(schema).serializeDocument(
167
+ inlineDocument,
168
+ 'document',
169
+ 'en',
170
+ defaultStopTypes,
171
+ addedCustomSerializers
172
+ );
173
+
174
+ const deserialized = BaseDocumentDeserializer.deserializeDocument(
175
+ serialized.content,
176
+ addedCustomDeserializers,
177
+ addedBlockDeserializers
178
+ );
179
+
180
+ const getInlineObj = (
181
+ content: PortableTextBlock[],
182
+ level: number | undefined = undefined
183
+ ) => {
184
+ let child: Record<string, any> = {};
185
+ const blocks = content.filter((block: PortableTextBlock) => {
186
+ if (level) {
187
+ return block.level === level;
188
+ }
189
+ return !block.level;
190
+ });
191
+
192
+ blocks.forEach((block: PortableTextBlock) => {
193
+ if (block.children && Array.isArray(block.children)) {
194
+ child = block.children.find((span: Record<string, any>) => {
195
+ if (level) {
196
+ return span._type === 'childObjectField' && block.level === level;
197
+ }
198
+ return span._type === 'childObjectField' && !block.level;
199
+ });
200
+ }
201
+ });
202
+
203
+ return child;
204
+ };
205
+ const origInlineObject = getInlineObj(inlineDocument.content);
206
+ const origInlineListObject = getInlineObj(inlineDocument.content, 1);
207
+
208
+ const deserializedInlineObject = getInlineObj(deserialized.content);
209
+ const deserializedInlineListObject = getInlineObj(deserialized.content, 1);
210
+
211
+ expect(deserializedInlineObject.title).toEqual(origInlineObject.title);
212
+ expect(deserializedInlineObject._type).toEqual(origInlineObject._type);
213
+
214
+ expect(deserializedInlineListObject.title).toEqual(
215
+ origInlineListObject.title
216
+ );
217
+ expect(deserializedInlineListObject._type).toEqual(
218
+ origInlineListObject._type
219
+ );
220
+ });
221
+
222
+ test('Handled annotations should be accurately deserialized', () => {
223
+ const inlineDocument = {
224
+ ...documentLevelArticle,
225
+ ...annotationAndInlineBlocks,
226
+ };
227
+
228
+ const serialized = BaseDocumentSerializer(schema).serializeDocument(
229
+ inlineDocument,
230
+ 'document',
231
+ 'en',
232
+ defaultStopTypes,
233
+ addedCustomSerializers
234
+ );
235
+
236
+ const deserialized = BaseDocumentDeserializer.deserializeDocument(
237
+ serialized.content,
238
+ addedCustomDeserializers,
239
+ addedBlockDeserializers
240
+ );
241
+
242
+ let origAnnotation: Record<string, any> | null = null;
243
+ let deserializedAnnotation: Record<string, any> | null = null;
244
+
245
+ inlineDocument.content.forEach((block: PortableTextBlock) => {
246
+ if (block.children && Array.isArray(block.children)) {
247
+ block.children.forEach((span: Record<string, any>) => {
248
+ if (span.marks && span.marks.length) {
249
+ origAnnotation = span;
250
+ }
251
+ });
252
+ }
253
+ });
254
+
255
+ deserialized.content.forEach((block: PortableTextBlock) => {
256
+ if (block.children && Array.isArray(block.children)) {
257
+ block.children.forEach((span: Record<string, any>) => {
258
+ if (span.marks && span.marks.length) {
259
+ deserializedAnnotation = span;
260
+ }
261
+ });
262
+ }
263
+ });
264
+
265
+ expect(deserializedAnnotation!.text).toEqual(origAnnotation!.text);
266
+ });
267
+
268
+ /*
269
+ * STYLE TAGS
270
+ */
271
+ test('Deserialized content should preserve style tags', () => {
272
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
273
+ const origH1 = documentLevelArticle.content.find(
274
+ (block: PortableTextBlock) => block.style === 'h1'
275
+ );
276
+ const deserializedH1 = deserialized.content.find(
277
+ (block: PortableTextBlock) => block.style === 'h1'
278
+ );
279
+ const origH2 = documentLevelArticle.content.find(
280
+ (block: PortableTextBlock) => block.style === 'h2'
281
+ );
282
+ const deserializedH2 = deserialized.content.find(
283
+ (block: PortableTextBlock) => block.style === 'h2'
284
+ );
285
+ expect(deserializedH1).toBeDefined();
286
+ expect(deserializedH2).toBeDefined();
287
+ expect(deserializedH1._key).toEqual(origH1._key);
288
+ expect(deserializedH2._key).toEqual(origH2._key);
289
+ expect(deserializedH1.children[0].text).toEqual(origH1.children[0].text);
290
+ expect(deserializedH2.children[0].text).toEqual(origH2.children[0].text);
291
+ });
292
+
293
+ /*
294
+ * LIST ITEMS
295
+ */
296
+ test('Deserialized list items should preserve level, style and tag', () => {
297
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
298
+ const origListItem = documentLevelArticle.content.find(
299
+ (block: PortableTextBlock) =>
300
+ block.listItem === 'bullet' && block.style === 'h2'
301
+ );
302
+ const deserializedListItem = deserialized.content.find(
303
+ (block: PortableTextBlock) =>
304
+ block.listItem === 'bullet' && block.style === 'h2'
305
+ );
306
+ const origNestedListItem = documentLevelArticle.content.find(
307
+ (block: PortableTextBlock) =>
308
+ block.listItem === 'bullet' && block.level === 2
309
+ );
310
+ const deserializedNestedListItem = deserialized.content.find(
311
+ (block: PortableTextBlock) =>
312
+ block.listItem === 'bullet' && block.level === 2
313
+ );
314
+ expect(deserializedListItem).toBeDefined();
315
+ expect(deserializedNestedListItem).toBeDefined();
316
+ expect(deserializedListItem._key).toEqual(origListItem._key);
317
+ expect(deserializedNestedListItem._key).toEqual(origNestedListItem._key);
318
+ expect(deserializedListItem.children[0].text).toEqual(
319
+ origListItem.children[0].text
320
+ );
321
+ expect(deserializedNestedListItem.children[0].text).toEqual(
322
+ origNestedListItem.children[0].text
323
+ );
324
+ });
325
+
326
+ /*
327
+ * MESSY INPUT
328
+ */
329
+ test('&nbsp; whitespace should not be escaped', () => {
330
+ vi.spyOn(console, 'debug').mockImplementation(() => {});
331
+
332
+ const content = readFileSync(
333
+ 'src/serialization/__tests__/__fixtures__/messy-html.html',
334
+ {
335
+ encoding: 'utf-8',
336
+ }
337
+ );
338
+ const result = BaseDocumentDeserializer.deserializeDocument(content);
339
+ expect(result.title).toEqual('Här är artikel titeln');
340
+ expect(result.content[1].nestedArrayField[0].title).toEqual(
341
+ 'Det här är en dragspels titeln'
342
+ );
343
+ });
344
+
345
+ /*
346
+ * V2 functionality -- be able to operate without a strict schema
347
+ */
348
+ test('Content with anonymous inline objects deserializes all fields, at any depth', () => {
349
+ vi.spyOn(console, 'debug').mockImplementation(() => {});
350
+
351
+ const serialized = BaseDocumentSerializer(inlineSchema).serializeDocument(
352
+ inlineDocumentLevelArticle,
353
+ 'document'
354
+ );
355
+
356
+ const deserialized = BaseDocumentDeserializer.deserializeDocument(
357
+ serialized.content
358
+ );
359
+ //object in field
360
+ expect(deserialized.tabs.config.title).toEqual(
361
+ inlineDocumentLevelArticle.tabs.config.title
362
+ );
363
+
364
+ //array in object in object
365
+ expect(
366
+ deserialized.tabs.config.objectAsField.content[0].children[0].text
367
+ ).toEqual(
368
+ inlineDocumentLevelArticle.tabs.config.objectAsField.content[0].children[0]
369
+ .text
370
+ );
371
+
372
+ //arrays
373
+ expect(deserialized.tabs.content).toBeInstanceOf(Array);
374
+ expect(deserialized.tabs.content.map((block: any) => block._key)).toEqual(
375
+ inlineDocumentLevelArticle.tabs.content.map((block: any) => block._key)
376
+ );
377
+
378
+ //object in array
379
+ const origObj = inlineDocumentLevelArticle.tabs.content.find(
380
+ (block: any) => block._type === 'objectField'
381
+ );
382
+ const deserializedObj = deserialized.tabs.content.find(
383
+ (block: any) => block._type === 'objectField'
384
+ );
385
+
386
+ expect(deserializedObj.title).toEqual(origObj.title);
387
+ expect(deserializedObj.objectAsField.content[0].children[0].text).toEqual(
388
+ origObj.objectAsField.content[0].children[0].text
389
+ );
390
+
391
+ //anonymous object in array
392
+ const origArray = inlineDocumentLevelArticle.tabs.arrayWithAnonymousObjects;
393
+ const deserializedArray = deserialized.tabs.arrayWithAnonymousObjects;
394
+ expect(deserializedArray.length).toEqual(origArray.length);
395
+ expect(deserializedArray[0]._key).toEqual(origArray[0]._key);
396
+ expect(Object.keys(deserializedArray[0])).not.toContain('span');
397
+ });
@@ -0,0 +1,107 @@
1
+ import { PortableTextBlock } from 'sanity';
2
+ import { expect, test } from 'vitest';
3
+ import { documentLevelArticle } from '../BaseDocumentSerializer/utils';
4
+ import { getDeserialized, toPlainText } from '../helpers';
5
+
6
+ test('Global test of working doc-level functionality and snapshot match', () => {
7
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
8
+ expect(deserialized).toMatchSnapshot();
9
+ });
10
+
11
+ /*
12
+ * Top-level plain text
13
+ */
14
+
15
+ test('String and text types get deserialized correctly at top-level -- document level', () => {
16
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
17
+ expect(deserialized.title).toEqual(documentLevelArticle.title);
18
+ expect(deserialized.snippet).toEqual(documentLevelArticle.snippet);
19
+ });
20
+
21
+ /*
22
+ * Presence and accuracy of fields in "vanilla" deserialization -- objects
23
+ */
24
+ test('Nested object contains accurate values -- document level', () => {
25
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
26
+ const origTitle = documentLevelArticle.config.title;
27
+ const deserializedTitle = deserialized.config.title;
28
+ expect(origTitle).toEqual(deserializedTitle);
29
+
30
+ const origBlockText = documentLevelArticle.config.nestedArrayField;
31
+ const deserializedBlockText = deserialized.config.nestedArrayField;
32
+
33
+ const origKeys = origBlockText.map((block: PortableTextBlock) => block._key);
34
+ const deserializedKeys = deserializedBlockText.map(
35
+ (block: PortableTextBlock) => block._key
36
+ );
37
+
38
+ expect(deserializedKeys.sort()).toEqual(origKeys.sort());
39
+ expect(toPlainText(deserializedBlockText)).toEqual(
40
+ toPlainText(origBlockText)
41
+ );
42
+ });
43
+
44
+ test('Nested object in an object contains accurate values -- document level', () => {
45
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
46
+ const origNestedObject = documentLevelArticle.config.objectAsField;
47
+ const deserializedNestedObject = deserialized.config.objectAsField;
48
+
49
+ expect(origNestedObject.title).toEqual(deserializedNestedObject.title);
50
+
51
+ const origKeys = origNestedObject.content.map(
52
+ (block: PortableTextBlock) => block._key
53
+ );
54
+ const deserializedKeys = deserializedNestedObject.content.map(
55
+ (block: PortableTextBlock) => block._key
56
+ );
57
+
58
+ expect(origKeys.sort()).toEqual(deserializedKeys.sort());
59
+ expect(toPlainText(deserializedNestedObject.content)).toEqual(
60
+ toPlainText(origNestedObject.content)
61
+ );
62
+ });
63
+
64
+ /*
65
+ * Presence and accuracy of fields in vanilla deserialization -- arrays
66
+ */
67
+
68
+ test('Array contains all serializable blocks with keys, in order -- document level', () => {
69
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
70
+ const origKeys = documentLevelArticle.content.map(
71
+ (block: PortableTextBlock) => block._key
72
+ );
73
+ const deserializedKeys = deserialized.content.map(
74
+ (block: PortableTextBlock) => block._key
75
+ );
76
+ expect(deserializedKeys.sort()).toEqual(origKeys.sort());
77
+ });
78
+
79
+ test('Array contains top-level block text -- document level', () => {
80
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
81
+ expect(toPlainText(deserialized.content)).toEqual(
82
+ toPlainText(documentLevelArticle.content)
83
+ );
84
+ });
85
+
86
+ test('Object in array contains accurate values in nested object -- document level', () => {
87
+ const deserialized = getDeserialized(documentLevelArticle, 'document');
88
+ const origTitle = documentLevelArticle.content.find(
89
+ (block: Record<string, any>) => block._type === 'objectField'
90
+ ).objectAsField.title;
91
+ const deserializedTitle = deserialized.content.find(
92
+ (block: Record<string, any>) => block._type === 'objectField'
93
+ ).objectAsField.title;
94
+ expect(deserializedTitle).toEqual(origTitle);
95
+
96
+ const origBlockText = toPlainText(
97
+ documentLevelArticle.content.find(
98
+ (block: Record<string, any>) => block._type === 'objectField'
99
+ ).objectAsField.content
100
+ ).trim();
101
+ const deserializedBlockText = toPlainText(
102
+ documentLevelArticle.content.find(
103
+ (block: Record<string, any>) => block._type === 'objectField'
104
+ ).objectAsField.content
105
+ ).trim();
106
+ expect(deserializedBlockText).toEqual(origBlockText);
107
+ });