@@ -88,4 +88,54 @@ describe('popover plugin basics', () => {
8888 pluginView . destroy ( ) ;
8989 expect ( tippyInstance . destroy ) . toHaveBeenCalled ( ) ;
9090 } ) ;
91+
92+ it ( 'hides tippy when coordsAtPos returns null' , ( ) => {
93+ const doc = schema . nodes . doc . create ( null , [ schema . nodes . paragraph . create ( null , schema . text ( 'Hello @' ) ) ] ) ;
94+ const state = EditorState . create ( { schema, doc, plugins : [ plugin ] } ) ;
95+ const view = { state, dom : document . createElement ( 'div' ) } ;
96+
97+ const pluginView = plugin . spec . view ( view ) ;
98+
99+ // Mock coordsAtPos to return null (presentation mode collapsed selection)
100+ editor . coordsAtPos = vi . fn ( ) . mockReturnValue ( null ) ;
101+
102+ // Build a new state where selection is at end (after @)
103+ const endPos = state . doc . content . size - 1 ;
104+ const tr = state . tr . setSelection ( state . selection . constructor . near ( state . doc . resolve ( endPos ) ) ) ;
105+ const newState = state . apply ( tr ) ;
106+
107+ pluginView . update ( { ...view , state : newState } , state ) ;
108+
109+ expect ( tippyInstance . hide ) . toHaveBeenCalled ( ) ;
110+ pluginView . destroy ( ) ;
111+ } ) ;
112+
113+ it ( 'uses insertMention as the prop name (not inserMention)' , ( ) => {
114+ const doc = schema . nodes . doc . create ( null , [ schema . nodes . paragraph . create ( null , schema . text ( 'Hello @' ) ) ] ) ;
115+ const state = EditorState . create ( { schema, doc, plugins : [ plugin ] } ) ;
116+ const view = { state, dom : document . createElement ( 'div' ) } ;
117+
118+ const pluginView = plugin . spec . view ( view ) ;
119+
120+ hoisted . createAppMock . mockClear ( ) ;
121+ hoisted . createAppMock . mockReturnValue ( { mount : vi . fn ( ) , unmount : vi . fn ( ) } ) ;
122+
123+ // Mock coordsAtPos to return valid coords so the popover renders
124+ editor . coordsAtPos = vi . fn ( ) . mockReturnValue ( { top : 100 , bottom : 120 , left : 50 , right : 50 } ) ;
125+
126+ const endPos = state . doc . content . size - 1 ;
127+ const tr = state . tr . setSelection ( state . selection . constructor . near ( state . doc . resolve ( endPos ) ) ) ;
128+ const newState = state . apply ( tr ) ;
129+
130+ pluginView . update ( { ...view , state : newState } , state ) ;
131+
132+ const calls = hoisted . createAppMock . mock . calls ;
133+ if ( calls . length > 0 ) {
134+ const [ , props ] = calls [ calls . length - 1 ] ;
135+ expect ( props ) . toHaveProperty ( 'insertMention' ) ;
136+ expect ( props ) . not . toHaveProperty ( 'inserMention' ) ;
137+ }
138+
139+ pluginView . destroy ( ) ;
140+ } ) ;
91141} ) ;
0 commit comments