@@ -536,4 +536,108 @@ describe('comments-store', () => {
536536 expect ( ordered ) . toEqual ( [ 'c-1' , null , undefined ] ) ;
537537 } ) ;
538538 } ) ;
539+
540+ describe ( 'comment anchor helpers' , ( ) => {
541+ it ( 'returns comment position by id or comment object' , ( ) => {
542+ const comment = { commentId : 'c-1' , fileId : 'doc-1' } ;
543+ store . commentsList = [ comment ] ;
544+ store . editorCommentPositions = {
545+ 'c-1' : { start : 12 , end : 18 } ,
546+ } ;
547+
548+ expect ( store . getCommentPosition ( 'c-1' ) ) . toEqual ( { start : 12 , end : 18 } ) ;
549+ expect ( store . getCommentPosition ( comment ) ) . toEqual ( { start : 12 , end : 18 } ) ;
550+ } ) ;
551+
552+ it ( 'returns comment position using importedId fallback' , ( ) => {
553+ const comment = { importedId : 'imported-1' , fileId : 'doc-1' } ;
554+ store . commentsList = [ comment ] ;
555+ store . editorCommentPositions = {
556+ 'imported-1' : { start : 20 , end : 30 } ,
557+ } ;
558+
559+ expect ( store . getCommentPosition ( 'imported-1' ) ) . toEqual ( { start : 20 , end : 30 } ) ;
560+ expect ( store . getCommentPosition ( comment ) ) . toEqual ( { start : 20 , end : 30 } ) ;
561+ } ) ;
562+
563+ it ( 'returns anchored text when editor and positions are available' , ( ) => {
564+ const textBetween = vi . fn ( ( ) => 'Anchored text' ) ;
565+ const editorStub = { state : { doc : { textBetween } } } ;
566+ __mockSuperdoc . documents . value = [ { id : 'doc-1' , type : 'docx' , getEditor : ( ) => editorStub } ] ;
567+
568+ store . commentsList = [ { commentId : 'c-1' , fileId : 'doc-1' } ] ;
569+ store . editorCommentPositions = {
570+ 'c-1' : { start : 5 , end : 12 } ,
571+ } ;
572+
573+ expect ( store . getCommentAnchoredText ( 'c-1' ) ) . toBe ( 'Anchored text' ) ;
574+ expect ( textBetween ) . toHaveBeenCalledWith ( 5 , 12 , ' ' , ' ' ) ;
575+ } ) ;
576+
577+ it ( 'returns anchored text with custom separator option' , ( ) => {
578+ const textBetween = vi . fn ( ( ) => 'Line1\nLine2' ) ;
579+ const editorStub = { state : { doc : { textBetween } } } ;
580+ __mockSuperdoc . documents . value = [ { id : 'doc-1' , type : 'docx' , getEditor : ( ) => editorStub } ] ;
581+
582+ store . commentsList = [ { commentId : 'c-1' , fileId : 'doc-1' } ] ;
583+ store . editorCommentPositions = {
584+ 'c-1' : { start : 0 , end : 20 } ,
585+ } ;
586+
587+ expect ( store . getCommentAnchoredText ( 'c-1' , { separator : '\n' } ) ) . toBe ( 'Line1\nLine2' ) ;
588+ expect ( textBetween ) . toHaveBeenCalledWith ( 0 , 20 , '\n' , '\n' ) ;
589+ } ) ;
590+
591+ it ( 'returns anchored text without trimming when trim is false' , ( ) => {
592+ const textBetween = vi . fn ( ( ) => ' spaced text ' ) ;
593+ const editorStub = { state : { doc : { textBetween } } } ;
594+ __mockSuperdoc . documents . value = [ { id : 'doc-1' , type : 'docx' , getEditor : ( ) => editorStub } ] ;
595+
596+ store . commentsList = [ { commentId : 'c-1' , fileId : 'doc-1' } ] ;
597+ store . editorCommentPositions = {
598+ 'c-1' : { start : 0 , end : 15 } ,
599+ } ;
600+
601+ expect ( store . getCommentAnchoredText ( 'c-1' , { trim : false } ) ) . toBe ( ' spaced text ' ) ;
602+ expect ( store . getCommentAnchoredText ( 'c-1' ) ) . toBe ( 'spaced text' ) ;
603+ } ) ;
604+
605+ it ( 'returns null when position or editor is missing' , ( ) => {
606+ store . commentsList = [ { commentId : 'c-1' , fileId : 'doc-1' } ] ;
607+ store . editorCommentPositions = { } ;
608+
609+ expect ( store . getCommentAnchoredText ( 'c-1' ) ) . toBeNull ( ) ;
610+ expect ( store . getCommentAnchorData ( 'c-1' ) ) . toBeNull ( ) ;
611+ } ) ;
612+
613+ it ( 'returns anchor data with position and text when available' , ( ) => {
614+ const textBetween = vi . fn ( ( ) => 'Selected text' ) ;
615+ const editorStub = { state : { doc : { textBetween } } } ;
616+ __mockSuperdoc . documents . value = [ { id : 'doc-1' , type : 'docx' , getEditor : ( ) => editorStub } ] ;
617+
618+ store . commentsList = [ { commentId : 'c-1' , fileId : 'doc-1' } ] ;
619+ store . editorCommentPositions = {
620+ 'c-1' : { start : 10 , end : 25 } ,
621+ } ;
622+
623+ const result = store . getCommentAnchorData ( 'c-1' ) ;
624+ expect ( result ) . toEqual ( {
625+ position : { start : 10 , end : 25 } ,
626+ anchoredText : 'Selected text' ,
627+ } ) ;
628+ } ) ;
629+
630+ it ( 'handles empty anchored text' , ( ) => {
631+ const textBetween = vi . fn ( ( ) => '' ) ;
632+ const editorStub = { state : { doc : { textBetween } } } ;
633+ __mockSuperdoc . documents . value = [ { id : 'doc-1' , type : 'docx' , getEditor : ( ) => editorStub } ] ;
634+
635+ store . commentsList = [ { commentId : 'c-1' , fileId : 'doc-1' } ] ;
636+ store . editorCommentPositions = {
637+ 'c-1' : { start : 5 , end : 5 } ,
638+ } ;
639+
640+ expect ( store . getCommentAnchoredText ( 'c-1' ) ) . toBe ( '' ) ;
641+ } ) ;
642+ } ) ;
539643} ) ;
0 commit comments