1- import $ from "jquery" ;
2- import type { ComponentChildren } from "preact" ;
31import { render } from "preact" ;
42import { act } from "preact/test-utils" ;
53import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
64
7- const {
8- triliumEventHandlers,
9- latestModalPropsRef,
10- latestNoteAutocompletePropsRef,
11- addLinkSpy,
12- logErrorSpy,
13- showRecentNotesSpy,
14- setTextSpy
15- } = vi . hoisted ( ( ) => ( {
16- triliumEventHandlers : new Map < string , ( payload : any ) => void > ( ) ,
17- latestModalPropsRef : { current : null as any } ,
18- latestNoteAutocompletePropsRef : { current : null as any } ,
19- addLinkSpy : vi . fn ( ( ) => Promise . resolve ( ) ) ,
20- logErrorSpy : vi . fn ( ) ,
21- showRecentNotesSpy : vi . fn ( ) ,
22- setTextSpy : vi . fn ( )
23- } ) ) ;
24-
25- vi . mock ( "../../services/i18n" , ( ) => ( {
26- t : ( key : string ) => key
27- } ) ) ;
28-
29- vi . mock ( "../../services/tree" , ( ) => ( {
30- default : {
31- getNoteIdFromUrl : ( notePath : string ) => notePath . split ( "/" ) . at ( - 1 ) ,
32- getNoteTitle : vi . fn ( async ( ) => "Target note" )
33- }
34- } ) ) ;
35-
36- vi . mock ( "../../services/ws" , ( ) => ( {
37- logError : logErrorSpy
38- } ) ) ;
39-
40- vi . mock ( "../../services/note_autocomplete" , ( ) => ( {
41- __esModule : true ,
42- default : {
43- showRecentNotes : showRecentNotesSpy ,
44- setText : setTextSpy
45- }
46- } ) ) ;
47-
48- vi . mock ( "../react/react_utils" , ( ) => ( {
49- refToJQuerySelector : ( ref : { current : HTMLInputElement | null } ) => ref . current ? $ ( ref . current ) : $ ( )
50- } ) ) ;
51-
52- vi . mock ( "../react/hooks" , ( ) => ( {
53- useTriliumEvent : ( name : string , handler : ( payload : any ) => void ) => {
54- triliumEventHandlers . set ( name , handler ) ;
55- }
56- } ) ) ;
57-
58- vi . mock ( "../react/Modal" , ( ) => ( {
59- default : ( props : any ) => {
60- latestModalPropsRef . current = props ;
61-
62- if ( ! props . show ) {
63- return null ;
64- }
65-
66- return (
67- < form onSubmit = { ( e ) => {
68- e . preventDefault ( ) ;
69- props . onSubmit ?.( ) ;
70- } } >
71- { props . children }
72- { props . footer }
73- </ form >
74- ) ;
75- }
76- } ) ) ;
77-
78- vi . mock ( "../react/FormGroup" , ( ) => ( {
79- default : ( { children } : { children : ComponentChildren } ) => < div > { children } </ div >
80- } ) ) ;
81-
82- vi . mock ( "../react/Button" , ( ) => ( {
83- default : ( { text } : { text : string } ) => < button type = "submit" > { text } </ button >
84- } ) ) ;
85-
86- vi . mock ( "../react/FormRadioGroup" , ( ) => ( {
87- default : ( ) => null
88- } ) ) ;
89-
90- vi . mock ( "../react/NoteAutocomplete" , ( ) => ( {
91- default : ( props : any ) => {
92- latestNoteAutocompletePropsRef . current = props ;
93- return < input ref = { props . inputRef } /> ;
94- }
95- } ) ) ;
96-
97- import AddLinkDialog from "./add_link" ;
5+ import { type AddLinkDialogTestState , createAddLinkDialogTestState , setupAddLinkDialogMocks } from "./add_link.spec_utils" ;
986
997describe ( "AddLinkDialog" , ( ) => {
1008 let container : HTMLDivElement ;
9+ let AddLinkDialog : ( props : object ) => JSX . Element ;
10+ let state : AddLinkDialogTestState ;
10111
102- beforeEach ( ( ) => {
12+ beforeEach ( async ( ) => {
13+ vi . resetModules ( ) ;
14+ state = createAddLinkDialogTestState ( ) ;
10315 vi . clearAllMocks ( ) ;
104- latestModalPropsRef . current = null ;
105- latestNoteAutocompletePropsRef . current = null ;
106- triliumEventHandlers . clear ( ) ;
16+ setupAddLinkDialogMocks ( state ) ;
17+
18+ ( { default : AddLinkDialog } = await import ( "./add_link" ) ) ;
19+
10720 container = document . createElement ( "div" ) ;
10821 document . body . appendChild ( container ) ;
10922 } ) ;
@@ -120,41 +33,37 @@ describe("AddLinkDialog", () => {
12033 render ( < AddLinkDialog /> , container ) ;
12134 } ) ;
12235
123- const showDialog = triliumEventHandlers . get ( "showAddLinkDialog" ) ;
124- expect ( showDialog ) . toBeTypeOf ( "function" ) ;
36+ const showDialog = state . triliumEventHandlers . get ( "showAddLinkDialog" ) ;
37+ if ( ! showDialog ) {
38+ throw new Error ( "showAddLinkDialog handler was not registered" ) ;
39+ }
12540
12641 await act ( async ( ) => {
127- showDialog ?. ( {
42+ showDialog ( {
12843 text : "" ,
12944 hasSelection : false ,
130- addLink : addLinkSpy
45+ addLink : state . addLinkSpy
13146 } ) ;
13247 } ) ;
13348
134- const suggestion = {
135- notePath : "root/target-note" ,
136- noteTitle : "Target note"
137- } ;
138-
13949 act ( ( ) => {
140- latestNoteAutocompletePropsRef . current . onKeyDownCapture ( {
50+ state . latestNoteAutocompletePropsRef . current . onKeyDownCapture ( {
14151 key : "Enter" ,
14252 ctrlKey : false ,
14353 metaKey : false ,
14454 shiftKey : false ,
14555 altKey : false ,
14656 isComposing : false
14757 } ) ;
148- latestNoteAutocompletePropsRef . current . onChange ( suggestion ) ;
58+ state . latestNoteAutocompletePropsRef . current . onChange ( {
59+ notePath : "root/target-note"
60+ } ) ;
14961 } ) ;
15062
151- expect ( latestModalPropsRef . current . show ) . toBe ( false ) ;
152- expect ( logErrorSpy ) . not . toHaveBeenCalled ( ) ;
153-
15463 await act ( async ( ) => {
155- latestModalPropsRef . current . onHidden ( ) ;
64+ state . latestModalPropsRef . current . onHidden ( ) ;
15665 } ) ;
15766
158- expect ( addLinkSpy ) . toHaveBeenCalledWith ( "root/target-note" , null ) ;
67+ expect ( state . addLinkSpy ) . toHaveBeenCalledWith ( "root/target-note" , null ) ;
15968 } ) ;
16069} ) ;
0 commit comments