UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

658 lines (657 loc) • 26.9 kB
import { flattenTopLevelFields } from './flattenTopLevelFields.js'; describe('flattenFields', ()=>{ const i18n = { t: (value)=>value, language: 'en', dateFNS: {}, dateFNSKey: 'en-US', fallbackLanguage: 'en', translations: {} }; const baseField = { type: 'text', name: 'title', label: 'Title' }; describe('basic flattening', ()=>{ it('should return flat list for top-level fields', ()=>{ const fields = [ baseField ]; const result = flattenTopLevelFields(fields); expect(result).toHaveLength(1); expect(result[0].name).toBe('title'); }); }); describe('group flattening', ()=>{ it('should flatten fields inside group with accessor and labelWithPrefix with moveSubFieldsToTop', ()=>{ const fields = [ { type: 'group', name: 'meta', label: 'Meta Info', fields: [ { type: 'text', name: 'slug', label: 'Slug' } ] } ]; const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true, i18n }); expect(result).toHaveLength(2); expect(result[1].name).toBe('slug'); expect(result[1].accessor).toBe('meta.slug'); expect(result[1].labelWithPrefix).toBe('Meta Info > Slug'); }); it('should NOT flatten fields inside group without moveSubFieldsToTop', ()=>{ const fields = [ { type: 'group', name: 'meta', label: 'Meta Info', fields: [ { type: 'text', name: 'slug', label: 'Slug' } ] } ]; const result = flattenTopLevelFields(fields); // Should return the group as a top-level item, not the inner field expect(result).toHaveLength(1); expect(result[0].name).toBe('meta'); expect('fields' in result[0]).toBe(true); expect('accessor' in result[0]).toBe(false); expect('labelWithPrefix' in result[0]).toBe(false); }); it('should correctly handle deeply nested group fields with and without moveSubFieldsToTop', ()=>{ const fields = [ { type: 'group', name: 'outer', label: 'Outer', fields: [ { type: 'group', name: 'inner', label: 'Inner', fields: [ { type: 'text', name: 'deep', label: 'Deep Field' } ] } ] } ]; const hoisted = flattenTopLevelFields(fields, { moveSubFieldsToTop: true, i18n }); expect(hoisted).toHaveLength(3); expect(hoisted[2].name).toBe('deep'); expect(hoisted[2].accessor).toBe('outer.inner.deep'); expect(hoisted[2].labelWithPrefix).toBe('Outer > Inner > Deep Field'); const nonHoisted = flattenTopLevelFields(fields); expect(nonHoisted).toHaveLength(1); expect(nonHoisted[0].name).toBe('outer'); expect('fields' in nonHoisted[0]).toBe(true); expect('accessor' in nonHoisted[0]).toBe(false); expect('labelWithPrefix' in nonHoisted[0]).toBe(false); }); it('should hoist fields from unnamed group if moveSubFieldsToTop is true', ()=>{ const fields = [ { type: 'group', label: 'Unnamed group', fields: [ { type: 'text', name: 'insideUnnamedGroup' } ] } ]; const withExtract = flattenTopLevelFields(fields, { moveSubFieldsToTop: true, i18n }); // Should include top level group and its nested field as a top-level field expect(withExtract).toHaveLength(2); expect(withExtract[1].type).toBe('text'); expect(withExtract[1].accessor).toBeUndefined(); expect(withExtract[1].labelWithPrefix).toBeUndefined(); const withoutExtract = flattenTopLevelFields(fields); // Should return the group as a top-level item, not the inner field expect(withoutExtract).toHaveLength(1); expect(withoutExtract[0].type).toBe('text'); expect(withoutExtract[0].accessor).toBeUndefined(); expect(withoutExtract[0].labelWithPrefix).toBeUndefined(); }); it('should hoist using deepest named group only if parents are unnamed', ()=>{ const fields = [ { type: 'group', label: 'Outer', fields: [ { type: 'group', label: 'Middle', fields: [ { type: 'group', name: 'namedGroup', label: 'Named Group', fields: [ { type: 'group', label: 'Inner', fields: [ { type: 'text', name: 'nestedField', label: 'Nested Field' } ] } ] } ] } ] } ]; const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true, i18n }); expect(hoistedResult).toHaveLength(5); expect(hoistedResult[4].name).toBe('nestedField'); expect(hoistedResult[4].accessor).toBe('namedGroup.nestedField'); expect(hoistedResult[4].labelWithPrefix).toBe('Named Group > Nested Field'); const nonHoistedResult = flattenTopLevelFields(fields); expect(nonHoistedResult).toHaveLength(1); expect(nonHoistedResult[0].type).toBe('group'); expect('fields' in nonHoistedResult[0]).toBe(true); expect('accessor' in nonHoistedResult[0]).toBe(false); expect('labelWithPrefix' in nonHoistedResult[0]).toBe(false); }); }); describe('array and block edge cases', ()=>{ it('should NOT flatten fields in arrays or blocks with moveSubFieldsToTop', ()=>{ const fields = [ { type: 'array', name: 'items', label: 'Items', fields: [ { type: 'text', name: 'label', label: 'Label' } ] }, { type: 'blocks', name: 'layout', blocks: [ { slug: 'block', fields: [ { type: 'text', name: 'content', label: 'Content' } ] } ] } ]; const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true }); expect(result).toHaveLength(2); expect(result[0].name).toBe('items'); expect(result[1].name).toBe('layout'); }); it('should NOT flatten fields in arrays or blocks without moveSubFieldsToTop', ()=>{ const fields = [ { type: 'array', name: 'things', label: 'Things', fields: [ { type: 'text', name: 'thingLabel', label: 'Thing Label' } ] }, { type: 'blocks', name: 'contentBlocks', blocks: [ { slug: 'content', fields: [ { type: 'text', name: 'body', label: 'Body' } ] } ] } ]; const result = flattenTopLevelFields(fields); expect(result).toHaveLength(2); expect(result[0].name).toBe('things'); expect(result[1].name).toBe('contentBlocks'); }); it('should not hoist group fields nested inside arrays', ()=>{ const fields = [ { type: 'array', name: 'arrayField', label: 'Array Field', fields: [ { type: 'group', name: 'groupInArray', label: 'Group In Array', fields: [ { type: 'text', name: 'nestedInArrayGroup', label: 'Nested In Array Group' } ] } ] } ]; const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true }); expect(result).toHaveLength(1); expect(result[0].name).toBe('arrayField'); }); it('should not hoist group fields nested inside blocks', ()=>{ const fields = [ { type: 'blocks', name: 'blockField', blocks: [ { slug: 'exampleBlock', fields: [ { type: 'group', name: 'groupInBlock', label: 'Group In Block', fields: [ { type: 'text', name: 'nestedInBlockGroup', label: 'Nested In Block Group' } ] } ] } ] } ]; const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true }); expect(result).toHaveLength(1); expect(result[0].name).toBe('blockField'); }); }); describe('row and collapsible behavior', ()=>{ it('should recursively flatten collapsible fields regardless of moveSubFieldsToTop', ()=>{ const fields = [ { type: 'collapsible', label: 'Collapsible', fields: [ { type: 'text', name: 'nickname', label: 'Nickname' } ] } ]; const defaultResult = flattenTopLevelFields(fields); const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true }); for (const result of [ defaultResult, hoistedResult ]){ expect(result).toHaveLength(1); expect(result[0].name).toBe('nickname'); expect('accessor' in result[0]).toBe(false); expect('labelWithPrefix' in result[0]).toBe(false); } }); it('should recursively flatten row fields regardless of moveSubFieldsToTop', ()=>{ const fields = [ { type: 'row', fields: [ { type: 'text', name: 'firstName', label: 'First Name' }, { type: 'text', name: 'lastName', label: 'Last Name' } ] } ]; const defaultResult = flattenTopLevelFields(fields); const hoistedResult = flattenTopLevelFields(fields, { moveSubFieldsToTop: true }); for (const result of [ defaultResult, hoistedResult ]){ expect(result).toHaveLength(2); expect(result[0].name).toBe('firstName'); expect(result[1].name).toBe('lastName'); expect('accessor' in result[0]).toBe(false); expect('labelWithPrefix' in result[0]).toBe(false); } }); it('should hoist named group fields inside rows', ()=>{ const fields = [ { type: 'row', fields: [ { type: 'group', name: 'groupInRow', label: 'Group In Row', fields: [ { type: 'text', name: 'nestedInRowGroup', label: 'Nested In Row Group' } ] } ] } ]; const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true, i18n }); expect(result).toHaveLength(2); expect(result[1].accessor).toBe('groupInRow.nestedInRowGroup'); expect(result[1].labelWithPrefix).toBe('Group In Row > Nested In Row Group'); }); it('should hoist named group fields inside collapsibles', ()=>{ const fields = [ { type: 'collapsible', label: 'Collapsible', fields: [ { type: 'group', name: 'groupInCollapsible', label: 'Group In Collapsible', fields: [ { type: 'text', name: 'nestedInCollapsibleGroup', label: 'Nested In Collapsible Group' } ] } ] } ]; const result = flattenTopLevelFields(fields, { moveSubFieldsToTop: true, i18n }); expect(result).toHaveLength(2); expect(result[1].accessor).toBe('groupInCollapsible.nestedInCollapsibleGroup'); expect(result[1].labelWithPrefix).toBe('Group In Collapsible > Nested In Collapsible Group'); }); }); describe('tab integration', ()=>{ const namedTabFields = [ { type: 'tabs', tabs: [ { label: 'Tab One', name: 'tabOne', fields: [ { type: 'array', name: 'array', fields: [ { type: 'text', name: 'text' } ] }, { type: 'row', fields: [ { name: 'arrayInRow', type: 'array', fields: [ { name: 'textInArrayInRow', type: 'text' } ] } ] }, { type: 'text', name: 'textInTab', label: 'Text In Tab' }, { type: 'group', name: 'groupInTab', label: 'Group In Tab', fields: [ { type: 'text', name: 'nestedTextInTabGroup', label: 'Nested Text In Tab Group' } ] } ] } ] } ]; const unnamedTabFields = [ { type: 'tabs', tabs: [ { label: 'Tab One', fields: [ { type: 'array', name: 'array', fields: [ { type: 'text', name: 'text' } ] }, { type: 'row', fields: [ { name: 'arrayInRow', type: 'array', fields: [ { name: 'textInArrayInRow', type: 'text' } ] } ] }, { type: 'text', name: 'textInTab', label: 'Text In Tab' } ] } ] } ]; it('should hoist named group fields inside unamed tabs when moveSubFieldsToTop is true', ()=>{ const unnamedTabWithNamedGroup = [ { type: 'tabs', tabs: [ { label: 'Tab One', fields: [ { type: 'group', name: 'groupInTab', label: 'Group In Tab', fields: [ { type: 'text', name: 'nestedInTabGroup', label: 'Nested In Tab Group' } ] } ] } ] } ]; const result = flattenTopLevelFields(unnamedTabWithNamedGroup, { moveSubFieldsToTop: true, i18n }); expect(result).toHaveLength(2); expect(result[1].accessor).toBe('groupInTab.nestedInTabGroup'); expect(result[1].labelWithPrefix).toBe('Group In Tab > Nested In Tab Group'); }); it('should hoist fields inside unnamed groups inside unnamed tabs when moveSubFieldsToTop is true', ()=>{ const unnamedTabWithUnnamedGroup = [ { type: 'tabs', tabs: [ { label: 'Tab One', fields: [ { type: 'group', label: 'Unnamed Group In Tab', fields: [ { type: 'text', name: 'nestedInUnnamedGroup', label: 'Nested In Unnamed Group' } ] } ] } ] } ]; const defaultResult = flattenTopLevelFields(unnamedTabWithUnnamedGroup); expect(defaultResult).toHaveLength(1); expect(defaultResult[0].type).toBe('text'); expect(defaultResult[0].label).toBe('Nested In Unnamed Group'); expect('accessor' in defaultResult[0]).toBe(false); expect('labelWithPrefix' in defaultResult[0]).toBe(false); const hoistedResult = flattenTopLevelFields(unnamedTabWithUnnamedGroup, { moveSubFieldsToTop: true, i18n }); expect(hoistedResult).toHaveLength(2); const hoistedField = hoistedResult[1]; expect(hoistedField.name).toBe('nestedInUnnamedGroup'); expect(hoistedField.accessor).toBeUndefined(); expect(hoistedField.labelWithPrefix).toBeUndefined(); }); it('should properly hoist fields inside named tabs when moveSubFieldsToTop is true', ()=>{ const result = flattenTopLevelFields(namedTabFields, { moveSubFieldsToTop: true, i18n }); expect(result).toHaveLength(5); expect(result[0].accessor).toBe('tabOne.array'); expect(result[0].labelWithPrefix).toBe('Tab One > array'); expect(result[1].accessor).toBe('tabOne.arrayInRow'); expect(result[1].labelWithPrefix).toBe('Tab One > arrayInRow'); expect(result[2].accessor).toBe('tabOne.textInTab'); expect(result[2].labelWithPrefix).toBe('Tab One > Text In Tab'); expect(result[4].accessor).toBe('tabOne.groupInTab.nestedTextInTabGroup'); expect(result[4].labelWithPrefix).toBe('Tab One > Group In Tab > Nested Text In Tab Group'); }); it('should NOT hoist fields inside named tabs when moveSubFieldsToTop is false', ()=>{ const result = flattenTopLevelFields(namedTabFields); // We expect one top-level field: the tabs container itself is *not* hoisted expect(result).toHaveLength(1); const tabField = result[0]; expect(tabField.type).toBe('tab'); // Confirm nested fields are NOT hoisted: no accessors or labelWithPrefix at the top level expect('accessor' in tabField).toBe(false); expect('labelWithPrefix' in tabField).toBe(false); }); it('should hoist fields inside unnamed tabs regardless of moveSubFieldsToTop', ()=>{ const resultDefault = flattenTopLevelFields(unnamedTabFields); const resultHoisted = flattenTopLevelFields(unnamedTabFields, { moveSubFieldsToTop: true, i18n }); expect(resultDefault).toHaveLength(3); expect(resultHoisted).toHaveLength(3); expect(resultDefault).toEqual(resultHoisted); for (const field of resultDefault){ expect(field.accessor).toBeUndefined(); expect(field.labelWithPrefix).toBeUndefined(); } }); }); }); //# sourceMappingURL=flattenTopLevelFields.spec.js.map