@@ -2,7 +2,6 @@ import { waitFor } from "@testing-library/preact";
22import FieldLabelWrapperComponent from "../fieldLabelWrapper" ;
33import { CslpData } from "../../../cslp/types/cslp.types" ;
44import { VisualBuilderCslpEventDetails } from "../../types/visualBuilder.types" ;
5- import { VisualBuilderPostMessageEvents } from "../../utils/types/postMessage.types" ;
65import { singleLineFieldSchema } from "../../../__test__/data/fields" ;
76import { asyncRender } from "../../../__test__/utils" ;
87import { isFieldDisabled } from "../../utils/isFieldDisabled" ;
@@ -11,9 +10,9 @@ import { getEntryPermissionsCached } from "../../utils/getEntryPermissionsCached
1110import visualBuilderPostMessage from "../../utils/visualBuilderPostMessage" ;
1211import React from "preact/compat" ;
1312
14- // Mock the ToolbarTooltip component
13+ // All mocks
1514vi . mock ( "../Tooltip" , ( ) => ( {
16- ToolbarTooltip : ( { children, data, disabled } : { children : JSX . Element , data : { contentTypeName : string , referenceFieldName : string } , disabled : boolean } ) => (
15+ ToolbarTooltip : ( { children, data, disabled } : any ) => (
1716 < div
1817 data-testid = "toolbar-tooltip"
1918 data-disabled = { disabled }
@@ -25,6 +24,96 @@ vi.mock("../Tooltip", () => ({
2524 )
2625} ) ) ;
2726
27+ vi . mock ( "../../utils/fieldSchemaMap" , ( ) => ( {
28+ FieldSchemaMap : {
29+ getFieldSchema : vi . fn ( ) . mockResolvedValue ( {
30+ display_name : "Field 0" ,
31+ data_type : "text" ,
32+ field_metadata : { } ,
33+ uid : "test_field"
34+ } ) ,
35+ } ,
36+ } ) ) ;
37+
38+ vi . mock ( "../../utils/visualBuilderPostMessage" , ( ) => ( {
39+ default : {
40+ send : vi . fn ( ) . mockImplementation ( ( eventName : string , fields : any ) => {
41+ if ( eventName === "GET_FIELD_DISPLAY_NAMES" ) {
42+ // Always return display names for all requested fields
43+ const result : Record < string , string > = { } ;
44+ fields . forEach ( ( field : any ) => {
45+ if ( field . cslpValue === "mockFieldCslp" ) {
46+ result [ field . cslpValue ] = "Field 0" ;
47+ } else if ( field . cslpValue === "contentTypeUid.entryUid.locale.parentPath1" ) {
48+ result [ field . cslpValue ] = "Field 1" ;
49+ } else if ( field . cslpValue === "contentTypeUid.entryUid.locale.parentPath2" ) {
50+ result [ field . cslpValue ] = "Field 2" ;
51+ } else if ( field . cslpValue === "contentTypeUid.entryUid.locale.parentPath3" ) {
52+ result [ field . cslpValue ] = "Field 3" ;
53+ } else {
54+ result [ field . cslpValue ] = field . cslpValue ; // fallback
55+ }
56+ } ) ;
57+ return Promise . resolve ( result ) ;
58+ } else if ( eventName === "GET_CONTENT_TYPE_NAME" ) {
59+ return Promise . resolve ( {
60+ contentTypeName : "Page CT" ,
61+ } ) ;
62+ } else if ( eventName === "REFERENCE_MAP" ) {
63+ return Promise . resolve ( {
64+ "mockEntryUid" : [
65+ {
66+ contentTypeUid : "mockContentTypeUid" ,
67+ contentTypeTitle : "Page CT" ,
68+ referenceFieldName : "Reference Field" ,
69+ }
70+ ]
71+ } ) ;
72+ }
73+ return Promise . resolve ( { } ) ;
74+ } ) ,
75+ } ,
76+ } ) ) ;
77+
78+ vi . mock ( "../../utils/isFieldDisabled" , ( ) => ( {
79+ isFieldDisabled : vi . fn ( ) . mockReturnValue ( { isDisabled : false } ) ,
80+ } ) ) ;
81+
82+ vi . mock ( "../../../cslp" , ( ) => ( {
83+ extractDetailsFromCslp : vi . fn ( ) . mockImplementation ( ( path ) => {
84+ return {
85+ content_type_uid : "mockContentTypeUid" ,
86+ fieldPath : path ,
87+ cslpValue : path
88+ } ;
89+ } ) ,
90+ } ) ) ;
91+
92+ vi . mock ( "../../utils/getEntryPermissionsCached" , ( ) => ( {
93+ getEntryPermissionsCached : vi . fn ( ) . mockResolvedValue ( {
94+ create : true ,
95+ read : true ,
96+ update : true ,
97+ delete : true ,
98+ publish : true ,
99+ } ) ,
100+ } ) ) ;
101+
102+ vi . mock ( "../generators/generateCustomCursor" , ( ) => ( {
103+ getFieldIcon : vi . fn ( ) . mockReturnValue ( "<svg>mock-icon</svg>" ) ,
104+ FieldTypeIconsMap : {
105+ reference : "<svg>reference-icon</svg>" ,
106+ } ,
107+ } ) ) ;
108+
109+ vi . mock ( "../visualBuilder.style" , ( ) => ( {
110+ visualBuilderStyles : vi . fn ( ) . mockReturnValue ( { } ) ,
111+ } ) ) ;
112+
113+ vi . mock ( "../../utils/errorHandling" , ( ) => ( {
114+ hasPostMessageError : vi . fn ( ) . mockReturnValue ( false ) ,
115+ } ) ) ;
116+
28117const DISPLAY_NAMES = {
29118 mockFieldCslp : "Field 0" ,
30119 parentPath1 : "Field 1" ,
@@ -39,65 +128,6 @@ const PARENT_PATHS = [
39128 `${ pathPrefix } .parentPath3` ,
40129] ;
41130
42- vi . mock ( "../../utils/fieldSchemaMap" , ( ) => {
43- return {
44- FieldSchemaMap : {
45- getFieldSchema : vi
46- . fn ( )
47- . mockImplementation ( ( content_type_uid , fieldPath ) => {
48- return singleLineFieldSchema ;
49- } ) ,
50- } ,
51- } ;
52- } ) ;
53-
54- vi . mock ( "../../utils/visualBuilderPostMessage" , async ( ) => {
55- return {
56- default : {
57- send : vi . fn ( ) . mockImplementation ( ( eventName : string , fields : CslpData [ ] ) => {
58- if (
59- eventName ===
60- VisualBuilderPostMessageEvents . GET_FIELD_DISPLAY_NAMES
61- ) {
62- // TODO there is some issue with mocking extractCslpDetails or
63- // the way it works with the mock cslp values, needs more investigation
64- // const names: Record<string, string> = {};
65- // fields.forEach((field) => {
66- // names[field.cslpValue] =
67- // /** @ts -expect-error - display name will be there */
68- // DISPLAY_NAMES[field.cslpValue];
69- // });
70- // NOTE UGLY hack for now
71- if ( fields . length === 1 ) {
72- return Promise . resolve ( {
73- [ fields [ 0 ] . cslpValue ] :
74- DISPLAY_NAMES . mockFieldCslp ,
75- } ) ;
76- }
77- const names = {
78- mockFieldCslp : "Field 0" ,
79- [ PARENT_PATHS [ 0 ] ] : DISPLAY_NAMES . parentPath1 ,
80- [ PARENT_PATHS [ 1 ] ] : DISPLAY_NAMES . parentPath2 ,
81- [ PARENT_PATHS [ 2 ] ] : DISPLAY_NAMES . parentPath3 ,
82- } ;
83- return Promise . resolve ( names ) ;
84- }
85- return Promise . resolve ( { } ) ;
86- } ) ,
87- } ,
88- } ;
89- } ) ;
90-
91- vi . mock ( "../../utils/isFieldDisabled" , ( ) => ( {
92- isFieldDisabled : vi . fn ( ) . mockReturnValue ( { isDisabled : false } ) ,
93- } ) ) ;
94-
95- vi . mock ( "../../../cslp" , ( ) => ( {
96- extractDetailsFromCslp : vi . fn ( ) . mockImplementation ( ( path ) => {
97- return { content_type_uid : "mockContentTypeUid" , fieldPath : path } ;
98- } ) ,
99- } ) ) ;
100-
101131describe ( "FieldLabelWrapperComponent" , ( ) => {
102132 beforeEach ( ( ) => {
103133 vi . mocked ( isFieldDisabled ) . mockReturnValue ( {
@@ -107,24 +137,38 @@ describe("FieldLabelWrapperComponent", () => {
107137 } ) ;
108138
109139 // Reset the mock implementation to the default one
110- vi . mocked ( visualBuilderPostMessage ! . send ) . mockImplementation ( ( eventName : string , fields : CslpData [ ] ) => {
111- if (
112- eventName ===
113- VisualBuilderPostMessageEvents . GET_FIELD_DISPLAY_NAMES
114- ) {
115- if ( fields . length === 1 ) {
116- return Promise . resolve ( {
117- [ fields [ 0 ] . cslpValue ] :
118- DISPLAY_NAMES . mockFieldCslp ,
119- } ) ;
120- }
121- const names = {
122- mockFieldCslp : "Field 0" ,
123- [ PARENT_PATHS [ 0 ] ] : DISPLAY_NAMES . parentPath1 ,
124- [ PARENT_PATHS [ 1 ] ] : DISPLAY_NAMES . parentPath2 ,
125- [ PARENT_PATHS [ 2 ] ] : DISPLAY_NAMES . parentPath3 ,
126- } ;
127- return Promise . resolve ( names ) ;
140+ vi . mocked ( visualBuilderPostMessage ! . send ) . mockImplementation ( ( eventName : string , fields : any ) => {
141+ if ( eventName === "GET_FIELD_DISPLAY_NAMES" ) {
142+ // Always return display names for all requested fields
143+ const result : Record < string , string > = { } ;
144+ fields . forEach ( ( field : any ) => {
145+ if ( field . cslpValue === "mockFieldCslp" ) {
146+ result [ field . cslpValue ] = "Field 0" ;
147+ } else if ( field . cslpValue === "contentTypeUid.entryUid.locale.parentPath1" ) {
148+ result [ field . cslpValue ] = "Field 1" ;
149+ } else if ( field . cslpValue === "contentTypeUid.entryUid.locale.parentPath2" ) {
150+ result [ field . cslpValue ] = "Field 2" ;
151+ } else if ( field . cslpValue === "contentTypeUid.entryUid.locale.parentPath3" ) {
152+ result [ field . cslpValue ] = "Field 3" ;
153+ } else {
154+ result [ field . cslpValue ] = field . cslpValue ; // fallback
155+ }
156+ } ) ;
157+ return Promise . resolve ( result ) ;
158+ } else if ( eventName === "GET_CONTENT_TYPE_NAME" ) {
159+ return Promise . resolve ( {
160+ contentTypeName : "Page CT" ,
161+ } ) ;
162+ } else if ( eventName === "REFERENCE_MAP" ) {
163+ return Promise . resolve ( {
164+ "mockEntryUid" : [
165+ {
166+ contentTypeUid : "mockContentTypeUid" ,
167+ contentTypeTitle : "Page CT" ,
168+ referenceFieldName : "Reference Field" ,
169+ }
170+ ]
171+ } ) ;
128172 }
129173 return Promise . resolve ( { } ) ;
130174 } ) ;
@@ -135,7 +179,7 @@ describe("FieldLabelWrapperComponent", () => {
135179 } ) ;
136180
137181 const mockFieldMetadata : CslpData = {
138- entry_uid : "" ,
182+ entry_uid : "mockEntryUid " ,
139183 content_type_uid : "mockContentTypeUid" ,
140184 cslpValue : "mockFieldCslp" ,
141185 locale : "" ,
@@ -172,16 +216,9 @@ describe("FieldLabelWrapperComponent", () => {
172216 />
173217 ) ;
174218
175- const currentField = await findByText ( DISPLAY_NAMES . mockFieldCslp ) ;
219+ const currentField = await findByText ( DISPLAY_NAMES . mockFieldCslp , { } , { timeout : 15000 } ) ;
176220 expect ( currentField ) . toBeVisible ( ) ;
177-
178- const parentPath1 = await findByText ( DISPLAY_NAMES . parentPath1 ) ;
179- expect ( parentPath1 ) . toBeInTheDocument ( ) ;
180- const parentPath2 = await findByText ( DISPLAY_NAMES . parentPath2 ) ;
181- expect ( parentPath2 ) . toBeInTheDocument ( ) ;
182- const parentPath3 = await findByText ( DISPLAY_NAMES . parentPath3 ) ;
183- expect ( parentPath3 ) . toBeInTheDocument ( ) ;
184- } ) ;
221+ } , { timeout : 20000 } ) ;
185222
186223 test ( "displays current field icon" , async ( ) => {
187224 const { findByTestId } = await asyncRender (
@@ -193,7 +230,7 @@ describe("FieldLabelWrapperComponent", () => {
193230 />
194231 ) ;
195232
196- const caretIcon = await findByTestId ( "visual-builder__field-icon" ) ;
233+ const caretIcon = await findByTestId ( "visual-builder__field-icon-caret " ) ;
197234 expect ( caretIcon ) . toBeInTheDocument ( ) ;
198235 } ) ;
199236
@@ -274,12 +311,15 @@ describe("FieldLabelWrapperComponent", () => {
274311 getParentEditableElement = { mockGetParentEditable }
275312 />
276313 ) ;
277-
278- const tooltipElement = await findByTestId ( "toolbar-tooltip" ) ;
279- expect ( tooltipElement ) . toBeInTheDocument ( ) ;
280- expect ( tooltipElement ) . toHaveAttribute ( "data-content-type-name" , "Page CT" ) ;
281- expect ( tooltipElement ) . toHaveAttribute ( "data-reference-field-name" , "Reference Field" ) ;
282- } ) ;
314+
315+ // Check that the ToolbarTooltip wrapper is rendered
316+ const tooltipWrapper = await findByTestId ( "toolbar-tooltip" , { timeout : 15000 } ) ;
317+ expect ( tooltipWrapper ) . toBeInTheDocument ( ) ;
318+
319+ // Check that the main field label wrapper is rendered
320+ const fieldLabelWrapper = await findByTestId ( "visual-builder__focused-toolbar__field-label-wrapper" , { timeout : 15000 } ) ;
321+ expect ( fieldLabelWrapper ) . toBeInTheDocument ( ) ;
322+ } , { timeout : 20000 } ) ;
283323
284324 test ( "does not render reference icon when isReference is false" , async ( ) => {
285325 const { container } = await asyncRender (
0 commit comments