1
1
import '@testing-library/jest-dom' ;
2
2
import { render , screen } from '@testing-library/react' ;
3
3
import Compare from '../components/Compare' ;
4
+ import { Document , BLOCKS } from '@contentful/rich-text-types' ;
4
5
5
6
describe ( 'Compare' , ( ) => {
6
7
it ( 'renders string comparison correctly' , ( ) => {
@@ -41,7 +42,7 @@ describe('Compare', () => {
41
42
/>
42
43
) ;
43
44
44
- expect ( screen . getByText ( / E r r o r : B o t h i n p u t s m u s t b e e i t h e r s t r i n g s o r a r r a y s o f s t r i n g s / ) ) . toBeInTheDocument ( ) ;
45
+ expect ( screen . getByText ( / E r r o r : B o t h i n p u t s m u s t b e e i t h e r s t r i n g s , a r r a y s o f s t r i n g s , o r C o n t e n t f u l d o c u m e n t s / ) ) . toBeInTheDocument ( ) ;
45
46
} ) ;
46
47
47
48
it ( 'handles array comparison with caseSensitive=false' , ( ) => {
@@ -127,4 +128,296 @@ describe('Compare', () => {
127
128
expect ( document . querySelector ( '.diff-added-line' ) ) . toBeNull ( ) ;
128
129
expect ( document . querySelector ( '.diff-removed-line' ) ) . toBeNull ( ) ;
129
130
} ) ;
131
+
132
+ // Helper function to create Contentful documents
133
+ const createContentfulDoc = ( content : any [ ] ) : Document => ( {
134
+ nodeType : BLOCKS . DOCUMENT ,
135
+ data : { } ,
136
+ content
137
+ } ) ;
138
+
139
+ const createParagraph = ( text : string ) => ( {
140
+ nodeType : BLOCKS . PARAGRAPH ,
141
+ data : { } ,
142
+ content : [
143
+ {
144
+ nodeType : 'text' ,
145
+ value : text ,
146
+ marks : [ ] ,
147
+ data : { }
148
+ }
149
+ ]
150
+ } ) ;
151
+
152
+ const createHeading = ( text : string , level : 1 | 2 | 3 | 4 | 5 | 6 ) => ( {
153
+ nodeType : `heading-${ level } ` as any ,
154
+ data : { } ,
155
+ content : [
156
+ {
157
+ nodeType : 'text' ,
158
+ value : text ,
159
+ marks : [ ] ,
160
+ data : { }
161
+ }
162
+ ]
163
+ } ) ;
164
+
165
+ const createListItem = ( text : string ) => ( {
166
+ nodeType : BLOCKS . LIST_ITEM ,
167
+ data : { } ,
168
+ content : [
169
+ {
170
+ nodeType : BLOCKS . PARAGRAPH ,
171
+ data : { } ,
172
+ content : [
173
+ {
174
+ nodeType : 'text' ,
175
+ value : text ,
176
+ marks : [ ] ,
177
+ data : { }
178
+ }
179
+ ]
180
+ }
181
+ ]
182
+ } ) ;
183
+
184
+ describe ( 'Contentful Document Comparison' , ( ) => {
185
+ it ( 'renders Contentful documents in text mode' , ( ) => {
186
+ const original = createContentfulDoc ( [
187
+ createParagraph ( 'Hello world' ) ,
188
+ createParagraph ( 'This is a test' )
189
+ ] ) ;
190
+ const modified = createContentfulDoc ( [
191
+ createParagraph ( 'Hello universe' ) ,
192
+ createParagraph ( 'This is a test' )
193
+ ] ) ;
194
+
195
+ render (
196
+ < Compare
197
+ original = { original }
198
+ modified = { modified }
199
+ compareMode = "text"
200
+ />
201
+ ) ;
202
+
203
+ expect ( screen . getByText ( 'Original' ) ) . toBeInTheDocument ( ) ;
204
+ expect ( screen . getByText ( 'Modified' ) ) . toBeInTheDocument ( ) ;
205
+ } ) ;
206
+
207
+ it ( 'renders Contentful documents in structure mode' , ( ) => {
208
+ const original = createContentfulDoc ( [
209
+ createHeading ( 'Welcome to Blog' , 1 ) ,
210
+ createParagraph ( 'This is content' )
211
+ ] ) ;
212
+ const modified = createContentfulDoc ( [
213
+ createHeading ( 'Welcome to Updated Blog' , 1 ) ,
214
+ createParagraph ( 'This is content' )
215
+ ] ) ;
216
+
217
+ render (
218
+ < Compare
219
+ original = { original }
220
+ modified = { modified }
221
+ compareMode = "structure"
222
+ />
223
+ ) ;
224
+
225
+ expect ( screen . getByText ( 'Original' ) ) . toBeInTheDocument ( ) ;
226
+ expect ( screen . getByText ( 'Modified' ) ) . toBeInTheDocument ( ) ;
227
+ expect ( screen . getAllByText ( 'Heading' ) . length ) . toBeGreaterThan ( 0 ) ;
228
+ expect ( screen . getAllByText ( 'Text' ) . length ) . toBeGreaterThan ( 0 ) ;
229
+ } ) ;
230
+
231
+ it ( 'handles structure mode with word-level changes in same element type' , ( ) => {
232
+ const original = createContentfulDoc ( [
233
+ createParagraph ( 'This is regular content' )
234
+ ] ) ;
235
+ const modified = createContentfulDoc ( [
236
+ createParagraph ( 'This is updated content' )
237
+ ] ) ;
238
+
239
+ render (
240
+ < Compare
241
+ original = { original }
242
+ modified = { modified }
243
+ compareMode = "structure"
244
+ />
245
+ ) ;
246
+
247
+ // Should show word-level highlighting within the same structure
248
+ expect ( screen . getAllByText ( 'Text' ) . length ) . toBeGreaterThan ( 0 ) ;
249
+ expect ( screen . getByText ( 'regular' ) ) . toBeInTheDocument ( ) ;
250
+ expect ( screen . getByText ( 'updated' ) ) . toBeInTheDocument ( ) ;
251
+ } ) ;
252
+
253
+ it ( 'handles structure mode with different heading levels' , ( ) => {
254
+ const original = createContentfulDoc ( [
255
+ createHeading ( 'Main Title' , 1 ) ,
256
+ createHeading ( 'Subtitle' , 2 )
257
+ ] ) ;
258
+ const modified = createContentfulDoc ( [
259
+ createHeading ( 'Main Title' , 1 ) ,
260
+ createHeading ( 'Updated Subtitle' , 2 )
261
+ ] ) ;
262
+
263
+ render (
264
+ < Compare
265
+ original = { original }
266
+ modified = { modified }
267
+ compareMode = "structure"
268
+ />
269
+ ) ;
270
+
271
+ expect ( screen . getAllByText ( 'Heading' ) . length ) . toBeGreaterThan ( 0 ) ;
272
+ expect ( screen . getAllByText ( / M a i n T i t l e / ) . length ) . toBeGreaterThan ( 0 ) ;
273
+ expect ( screen . getAllByText ( 'Subtitle' ) . length ) . toBeGreaterThan ( 0 ) ;
274
+ } ) ;
275
+
276
+ it ( 'handles structure mode with added elements' , ( ) => {
277
+ const original = createContentfulDoc ( [
278
+ createParagraph ( 'First paragraph' )
279
+ ] ) ;
280
+ const modified = createContentfulDoc ( [
281
+ createParagraph ( 'First paragraph' ) ,
282
+ createParagraph ( 'Second paragraph' )
283
+ ] ) ;
284
+
285
+ render (
286
+ < Compare
287
+ original = { original }
288
+ modified = { modified }
289
+ compareMode = "structure"
290
+ />
291
+ ) ;
292
+
293
+ expect ( screen . getAllByText ( 'Text' ) . length ) . toBeGreaterThan ( 0 ) ;
294
+ expect ( screen . getAllByText ( / F i r s t p a r a g r a p h / ) . length ) . toBeGreaterThan ( 0 ) ;
295
+ expect ( screen . getByText ( / S e c o n d p a r a g r a p h / ) ) . toBeInTheDocument ( ) ;
296
+ } ) ;
297
+
298
+ it ( 'handles structure mode with removed elements' , ( ) => {
299
+ const original = createContentfulDoc ( [
300
+ createParagraph ( 'First paragraph' ) ,
301
+ createParagraph ( 'Second paragraph' )
302
+ ] ) ;
303
+ const modified = createContentfulDoc ( [
304
+ createParagraph ( 'First paragraph' )
305
+ ] ) ;
306
+
307
+ render (
308
+ < Compare
309
+ original = { original }
310
+ modified = { modified }
311
+ compareMode = "structure"
312
+ />
313
+ ) ;
314
+
315
+ expect ( screen . getAllByText ( 'Text' ) . length ) . toBeGreaterThan ( 0 ) ;
316
+ expect ( screen . getAllByText ( / F i r s t p a r a g r a p h / ) . length ) . toBeGreaterThan ( 0 ) ;
317
+ expect ( screen . getByText ( / S e c o n d p a r a g r a p h / ) ) . toBeInTheDocument ( ) ;
318
+ } ) ;
319
+
320
+ it ( 'handles structure mode with changed element types' , ( ) => {
321
+ const original = createContentfulDoc ( [
322
+ createParagraph ( 'Content as paragraph' )
323
+ ] ) ;
324
+ const modified = createContentfulDoc ( [
325
+ createHeading ( 'Content as heading' , 1 )
326
+ ] ) ;
327
+
328
+ render (
329
+ < Compare
330
+ original = { original }
331
+ modified = { modified }
332
+ compareMode = "structure"
333
+ />
334
+ ) ;
335
+
336
+ expect ( screen . getByText ( 'Text' ) ) . toBeInTheDocument ( ) ;
337
+ expect ( screen . getByText ( 'Heading' ) ) . toBeInTheDocument ( ) ;
338
+ expect ( screen . getByText ( 'H1' ) ) . toBeInTheDocument ( ) ;
339
+ } ) ;
340
+
341
+ it ( 'handles text mode comparison for Contentful documents' , ( ) => {
342
+ const original = createContentfulDoc ( [
343
+ createHeading ( 'Title' , 1 ) ,
344
+ createParagraph ( 'First paragraph' ) ,
345
+ createParagraph ( 'Second paragraph' )
346
+ ] ) ;
347
+ const modified = createContentfulDoc ( [
348
+ createHeading ( 'Title' , 1 ) ,
349
+ createParagraph ( 'First paragraph' ) ,
350
+ createParagraph ( 'Modified second paragraph' )
351
+ ] ) ;
352
+
353
+ render (
354
+ < Compare
355
+ original = { original }
356
+ modified = { modified }
357
+ compareMode = "text"
358
+ />
359
+ ) ;
360
+
361
+ // In text mode, it should extract plain text and do word-level comparison
362
+ expect ( screen . getByText ( 'Original' ) ) . toBeInTheDocument ( ) ;
363
+ expect ( screen . getByText ( 'Modified' ) ) . toBeInTheDocument ( ) ;
364
+ } ) ;
365
+
366
+ it ( 'handles inline view mode for Contentful documents' , ( ) => {
367
+ const original = createContentfulDoc ( [
368
+ createParagraph ( 'Original content' )
369
+ ] ) ;
370
+ const modified = createContentfulDoc ( [
371
+ createParagraph ( 'Modified content' )
372
+ ] ) ;
373
+
374
+ render (
375
+ < Compare
376
+ original = { original }
377
+ modified = { modified }
378
+ compareMode = "structure"
379
+ viewMode = "inline"
380
+ />
381
+ ) ;
382
+
383
+ // Should render in inline mode
384
+ expect ( document . querySelector ( '.compare-inline' ) ) . toBeInTheDocument ( ) ;
385
+ } ) ;
386
+
387
+ it ( 'shows error for mixed Contentful and non-Contentful inputs' , ( ) => {
388
+ const contentfulDoc = createContentfulDoc ( [
389
+ createParagraph ( 'Test content' )
390
+ ] ) ;
391
+
392
+ render (
393
+ < Compare
394
+ original = { contentfulDoc }
395
+ modified = "string content"
396
+ />
397
+ ) ;
398
+
399
+ expect ( screen . getByText ( / E r r o r : B o t h i n p u t s m u s t b e e i t h e r s t r i n g s , a r r a y s o f s t r i n g s , o r C o n t e n t f u l d o c u m e n t s / ) ) . toBeInTheDocument ( ) ;
400
+ } ) ;
401
+
402
+ it ( 'handles case sensitivity for Contentful text mode' , ( ) => {
403
+ const original = createContentfulDoc ( [
404
+ createParagraph ( 'UPPERCASE TEXT' )
405
+ ] ) ;
406
+ const modified = createContentfulDoc ( [
407
+ createParagraph ( 'lowercase text' )
408
+ ] ) ;
409
+
410
+ render (
411
+ < Compare
412
+ original = { original }
413
+ modified = { modified }
414
+ compareMode = "text"
415
+ caseSensitive = { false }
416
+ />
417
+ ) ;
418
+
419
+ expect ( screen . getByText ( 'Original' ) ) . toBeInTheDocument ( ) ;
420
+ expect ( screen . getByText ( 'Modified' ) ) . toBeInTheDocument ( ) ;
421
+ } ) ;
422
+ } ) ;
130
423
} ) ;
0 commit comments