Skip to content

Commit 2ff06d6

Browse files
authored
Merge pull request #219 from contentstack/fix/DX-3664-missing-attrs
feat: enhance default-node-options.ts
2 parents f311328 + d04aebb commit 2ff06d6

File tree

11 files changed

+839
-97
lines changed

11 files changed

+839
-97
lines changed

.talismanrc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ fileignoreconfig:
33
ignore_detectors:
44
- filecontent
55
- filename: package-lock.json
6-
checksum: 54777ceb615ca49bc21baf255b1ee9781da7e2868ff3d4292a6715bcbed33196
6+
checksum: 67614c9c8ad75adf4479b309dbea1d8baac81c28175b21f51fbb487840ca6bda
77
- filename: src/entry-editable.ts
88
checksum: 3ba7af9ed1c1adef2e2bd5610099716562bebb8ba750d4b41ddda99fc9eaf115
99
- filename: .husky/pre-commit
1010
checksum: 5baabd7d2c391648163f9371f0e5e9484f8fb90fa2284cfc378732ec3192c193
1111
- filename: src/endpoints.ts
1212
checksum: 721a1df93b02d04c1c19a76c171fe2748e4abb1fc3e43452e76fecfd8f384751
13+
- filename: src/options/default-node-options.ts
14+
checksum: d455330cc4f9306889fb299171364a37ad2c3bafe1fbd334033edc94f21694a6
1315
- filename: package.json
14-
checksum: 033eb21070795be5b426183f52d784347110fcb724bc9f8d63f94898ac5f0086
16+
checksum: 033eb21070795be5b426183f52d784347110fcb724bc9f8d63f94898ac5f0086

__test__/default-node-options.test.ts

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Node from '../src/nodes/node'
33
import NodeType from '../src/nodes/node-type'
44
import { Next, RenderMark, RenderNode } from '../src/options'
55
import { defaultNodeOption } from '../src/options/default-node-options'
6+
import { Attributes } from '../src/Models/metadata-model'
67

78
const text = 'text'
89
const next : Next = () => text
@@ -233,4 +234,337 @@ describe('Default node render options', () => {
233234
expect(renderString).toEqual('<sup>text</sup>')
234235
done()
235236
})
237+
})
238+
239+
describe('Default node render options - Missing attrs cases', () => {
240+
// Create nodes with undefined attrs using type assertion
241+
const nodeWithoutAttrs = {
242+
type: NodeType.PARAGRAPH,
243+
children: []
244+
} as unknown as Node
245+
246+
const nodeWithUndefinedAttrs = {
247+
type: NodeType.PARAGRAPH,
248+
attrs: undefined as unknown as Attributes,
249+
children: []
250+
} as Node
251+
252+
it('Should handle paragraph without attrs', done => {
253+
const renderString = (defaultNodeOption[NodeType.PARAGRAPH] as RenderNode)(nodeWithoutAttrs, next)
254+
expect(renderString).toEqual('<p>text</p>')
255+
done()
256+
})
257+
258+
it('Should handle paragraph with undefined attrs', done => {
259+
const renderString = (defaultNodeOption[NodeType.PARAGRAPH] as RenderNode)(nodeWithUndefinedAttrs, next)
260+
expect(renderString).toEqual('<p>text</p>')
261+
done()
262+
})
263+
264+
it('Should handle link without attrs', done => {
265+
const linkNodeNoAttrs = {
266+
type: NodeType.LINK,
267+
children: []
268+
} as unknown as Node
269+
const renderString = (defaultNodeOption[NodeType.LINK] as RenderNode)(linkNodeNoAttrs, next)
270+
expect(renderString).toEqual('<a>text</a>')
271+
done()
272+
})
273+
274+
it('Should handle link without href or url', done => {
275+
const linkNodePartialAttrs = {
276+
type: NodeType.LINK,
277+
attrs: { style: 'color: red;' },
278+
children: []
279+
} as Node
280+
const renderString = (defaultNodeOption[NodeType.LINK] as RenderNode)(linkNodePartialAttrs, next)
281+
expect(renderString).toEqual('<a style="color: red;">text</a>')
282+
done()
283+
})
284+
285+
it('Should handle image without attrs', done => {
286+
const imgNodeNoAttrs = {
287+
type: NodeType.IMAGE,
288+
children: []
289+
} as unknown as Node
290+
const renderString = (defaultNodeOption[NodeType.IMAGE] as RenderNode)(imgNodeNoAttrs, next)
291+
expect(renderString).toEqual('<img />text')
292+
done()
293+
})
294+
295+
it('Should handle image without src or url', done => {
296+
const imgNodePartialAttrs = {
297+
type: NodeType.IMAGE,
298+
attrs: { id: 'img-id' },
299+
children: []
300+
} as Node
301+
const renderString = (defaultNodeOption[NodeType.IMAGE] as RenderNode)(imgNodePartialAttrs, next)
302+
expect(renderString).toEqual('<img id="img-id" />text')
303+
done()
304+
})
305+
306+
it('Should handle embed without attrs', done => {
307+
const embedNodeNoAttrs = {
308+
type: NodeType.EMBED,
309+
children: []
310+
} as unknown as Node
311+
const renderString = (defaultNodeOption[NodeType.EMBED] as RenderNode)(embedNodeNoAttrs, next)
312+
expect(renderString).toEqual('<iframe>text</iframe>')
313+
done()
314+
})
315+
316+
it('Should handle headings without attrs', done => {
317+
const headingNodeNoAttrs = {
318+
type: NodeType.HEADING_1,
319+
children: []
320+
} as unknown as Node
321+
const renderString = (defaultNodeOption[NodeType.HEADING_1] as RenderNode)(headingNodeNoAttrs, next)
322+
expect(renderString).toEqual('<h1>text</h1>')
323+
done()
324+
})
325+
326+
it('Should handle headings with partial attrs', done => {
327+
const headingNodePartialAttrs = {
328+
type: NodeType.HEADING_2,
329+
attrs: { style: 'font-weight: bold;' },
330+
children: []
331+
} as Node
332+
const renderString = (defaultNodeOption[NodeType.HEADING_2] as RenderNode)(headingNodePartialAttrs, next)
333+
expect(renderString).toEqual('<h2 style="font-weight: bold;">text</h2>')
334+
done()
335+
})
336+
337+
it('Should handle lists without attrs', done => {
338+
const listNodeNoAttrs = {
339+
type: NodeType.ORDER_LIST,
340+
children: []
341+
} as unknown as Node
342+
const renderString = (defaultNodeOption[NodeType.ORDER_LIST] as RenderNode)(listNodeNoAttrs, next)
343+
expect(renderString).toEqual('<ol>text</ol>')
344+
done()
345+
})
346+
347+
it('Should handle table without attrs', done => {
348+
const tableNodeNoAttrs = {
349+
type: NodeType.TABLE,
350+
children: []
351+
} as unknown as Node
352+
const renderString = (defaultNodeOption[NodeType.TABLE] as RenderNode)(tableNodeNoAttrs, next)
353+
expect(renderString).toEqual('<table>text</table>')
354+
done()
355+
})
356+
357+
it('Should handle table without colWidths', done => {
358+
const tableNodeNoColWidths = {
359+
type: NodeType.TABLE,
360+
attrs: { style: 'border: 1px solid;' },
361+
children: []
362+
} as Node
363+
const renderString = (defaultNodeOption[NodeType.TABLE] as RenderNode)(tableNodeNoColWidths, next)
364+
expect(renderString).toEqual('<table style="border: 1px solid;">text</table>')
365+
done()
366+
})
367+
368+
it('Should handle table head without attrs', done => {
369+
const tableHeadNoAttrs = {
370+
type: NodeType.TABLE_HEAD,
371+
children: []
372+
} as unknown as Node
373+
const renderString = (defaultNodeOption[NodeType.TABLE_HEAD] as RenderNode)(tableHeadNoAttrs, next)
374+
expect(renderString).toEqual('<th>text</th>')
375+
done()
376+
})
377+
378+
it('Should handle table head without rowSpan or colSpan', done => {
379+
const tableHeadPartialAttrs = {
380+
type: NodeType.TABLE_HEAD,
381+
attrs: { style: 'background: gray;' },
382+
children: []
383+
} as Node
384+
const renderString = (defaultNodeOption[NodeType.TABLE_HEAD] as RenderNode)(tableHeadPartialAttrs, next)
385+
expect(renderString).toEqual('<th style="background: gray;">text</th>')
386+
done()
387+
})
388+
389+
it('Should handle table data without attrs', done => {
390+
const tableDataNoAttrs = {
391+
type: NodeType.TABLE_DATA,
392+
children: []
393+
} as unknown as Node
394+
const renderString = (defaultNodeOption[NodeType.TABLE_DATA] as RenderNode)(tableDataNoAttrs, next)
395+
expect(renderString).toEqual('<td>text</td>')
396+
done()
397+
})
398+
399+
it('Should handle table data with void attribute', done => {
400+
const tableDataVoidNoAttrs = {
401+
type: NodeType.TABLE_DATA,
402+
attrs: { void: true },
403+
children: []
404+
} as Node
405+
const renderString = (defaultNodeOption[NodeType.TABLE_DATA] as RenderNode)(tableDataVoidNoAttrs, next)
406+
expect(renderString).toEqual('')
407+
done()
408+
})
409+
410+
it('Should handle blockquote without attrs', done => {
411+
const blockquoteNoAttrs = {
412+
type: NodeType.BLOCK_QUOTE,
413+
children: []
414+
} as unknown as Node
415+
const renderString = (defaultNodeOption[NodeType.BLOCK_QUOTE] as RenderNode)(blockquoteNoAttrs, next)
416+
expect(renderString).toEqual('<blockquote>text</blockquote>')
417+
done()
418+
})
419+
420+
it('Should handle code without attrs', done => {
421+
const codeNoAttrs = {
422+
type: NodeType.CODE,
423+
children: []
424+
} as unknown as Node
425+
const renderString = (defaultNodeOption[NodeType.CODE] as RenderNode)(codeNoAttrs, next)
426+
expect(renderString).toEqual('<code>text</code>')
427+
done()
428+
})
429+
430+
it('Should handle reference without attrs', done => {
431+
const referenceNoAttrs = {
432+
type: NodeType.REFERENCE,
433+
children: []
434+
} as unknown as Node
435+
const renderString = (defaultNodeOption.reference as RenderNode)(referenceNoAttrs, next)
436+
expect(renderString).toEqual('')
437+
done()
438+
})
439+
440+
it('Should handle reference with type but no display-type', done => {
441+
const referencePartialAttrs = {
442+
type: NodeType.REFERENCE,
443+
attrs: { type: 'entry' },
444+
children: []
445+
} as Node
446+
const renderString = (defaultNodeOption.reference as RenderNode)(referencePartialAttrs, next)
447+
expect(renderString).toEqual('')
448+
done()
449+
})
450+
451+
it('Should handle reference with entry type and link display-type but missing href', done => {
452+
const referenceLinkNoHref = {
453+
type: NodeType.REFERENCE,
454+
attrs: { type: 'entry', 'display-type': 'link' },
455+
children: []
456+
} as Node
457+
const renderString = (defaultNodeOption.reference as RenderNode)(referenceLinkNoHref, next)
458+
expect(renderString).toEqual('<a>text</a>')
459+
done()
460+
})
461+
462+
it('Should handle reference with asset type and link display-type but missing href', done => {
463+
const referenceAssetLinkNoHref = {
464+
type: NodeType.REFERENCE,
465+
attrs: { type: 'asset', 'display-type': 'link' },
466+
children: []
467+
} as Node
468+
const renderString = (defaultNodeOption.reference as RenderNode)(referenceAssetLinkNoHref, next)
469+
expect(renderString).toEqual('<a type="asset" content-type-uid="sys_assets" sys-style-type="download">text</a>')
470+
done()
471+
})
472+
473+
it('Should handle reference with asset type but missing asset-link', done => {
474+
const referenceAssetNoLink = {
475+
type: NodeType.REFERENCE,
476+
attrs: { type: 'asset' },
477+
children: []
478+
} as Node
479+
const renderString = (defaultNodeOption.reference as RenderNode)(referenceAssetNoLink, next)
480+
expect(renderString).toEqual('<figure><img /></figure>')
481+
done()
482+
})
483+
484+
it('Should handle reference with asset type but partial attributes', done => {
485+
const referenceAssetPartial = {
486+
type: NodeType.REFERENCE,
487+
attrs: {
488+
type: 'asset',
489+
'asset-link': 'https://example.com/image.jpg',
490+
style: 'border: 1px;'
491+
},
492+
children: []
493+
} as Node
494+
const renderString = (defaultNodeOption.reference as RenderNode)(referenceAssetPartial, next)
495+
expect(renderString).toContain('<figure')
496+
expect(renderString).toContain('style="border: 1px;"')
497+
expect(renderString).toContain('src=')
498+
done()
499+
})
500+
501+
it('Should handle link with target attribute', done => {
502+
const linkWithTarget = {
503+
type: NodeType.LINK,
504+
attrs: { href: 'https://example.com', target: '_blank' },
505+
children: []
506+
} as Node
507+
const renderString = (defaultNodeOption[NodeType.LINK] as RenderNode)(linkWithTarget, next)
508+
expect(renderString).toEqual('<a href="https://example.com" target="_blank">text</a>')
509+
done()
510+
})
511+
512+
it('Should handle link without target attribute', done => {
513+
const linkWithoutTarget = {
514+
type: NodeType.LINK,
515+
attrs: { href: 'https://example.com' },
516+
children: []
517+
} as Node
518+
const renderString = (defaultNodeOption[NodeType.LINK] as RenderNode)(linkWithoutTarget, next)
519+
expect(renderString).toEqual('<a href="https://example.com">text</a>')
520+
done()
521+
})
522+
523+
it('Should handle elements with only class-name attribute', done => {
524+
const nodeWithClass = {
525+
type: NodeType.PARAGRAPH,
526+
attrs: { 'class-name': 'custom-class' },
527+
children: []
528+
} as Node
529+
const renderString = (defaultNodeOption[NodeType.PARAGRAPH] as RenderNode)(nodeWithClass, next)
530+
expect(renderString).toEqual('<p class="custom-class">text</p>')
531+
done()
532+
})
533+
534+
it('Should handle elements with only id attribute', done => {
535+
const nodeWithId = {
536+
type: NodeType.PARAGRAPH,
537+
attrs: { id: 'custom-id' },
538+
children: []
539+
} as Node
540+
const renderString = (defaultNodeOption[NodeType.PARAGRAPH] as RenderNode)(nodeWithId, next)
541+
expect(renderString).toEqual('<p id="custom-id">text</p>')
542+
done()
543+
})
544+
545+
it('Should handle elements with only style attribute', done => {
546+
const nodeWithStyle = {
547+
type: NodeType.PARAGRAPH,
548+
attrs: { style: 'color: blue;' },
549+
children: []
550+
} as Node
551+
const renderString = (defaultNodeOption[NodeType.PARAGRAPH] as RenderNode)(nodeWithStyle, next)
552+
expect(renderString).toEqual('<p style="color: blue;">text</p>')
553+
done()
554+
})
555+
556+
it('Should handle all common attributes together', done => {
557+
const nodeWithAllAttrs = {
558+
type: NodeType.PARAGRAPH,
559+
attrs: {
560+
style: 'color: blue;',
561+
'class-name': 'custom-class',
562+
id: 'custom-id'
563+
},
564+
children: []
565+
} as Node
566+
const renderString = (defaultNodeOption[NodeType.PARAGRAPH] as RenderNode)(nodeWithAllAttrs, next)
567+
expect(renderString).toEqual('<p style="color: blue;" class="custom-class" id="custom-id">text</p>')
568+
done()
569+
})
236570
})

0 commit comments

Comments
 (0)