@@ -8,37 +8,36 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
88 * Test the core functionality: opening a chat when no action is specified
99 * This tests the basic URI parsing and chat opening behavior
1010 */
11- it ( "opens a chat when URI has no action parameter" ,
11+ fit ( "opens a chat when URI has no action parameter" ,
1212 mock . initConverse ( [ 'chatBoxesFetched' ] , { } , async function ( _converse ) {
1313
1414 const { api } = _converse ;
1515 // Wait for roster to be initialized so we can open chats
1616 await mock . waitForRoster ( _converse , 'current' , 1 ) ;
1717
1818 // Save original globals to restore them later
19- const originalLocation = window . location ;
19+ const originalLocationDescriptor = Object . getOwnPropertyDescriptor ( window , ' location' ) ;
2020 const originalReplaceState = window . history . replaceState ;
2121
2222 // Mock window.location to simulate a protocol handler URI
2323 // This simulates: ?uri=xmpp:[email protected] 24- delete window . location ;
25- window . location = {
26- search :
'?uri=xmpp%3Aromeo%40montague.lit' , // URL-encoded: xmpp:[email protected] 27- hash : '' ,
28- origin : 'http://localhost' ,
29- pathname : '/' ,
30- } ;
24+ Object . defineProperty ( window , "location" , {
25+ value : {
26+ search :
'?uri=xmpp%3Aromeo%40montague.lit' , // URL-encoded: xmpp:[email protected] 27+ hash : '' ,
28+ origin : 'http://localhost' ,
29+ pathname : '/' ,
30+ } ,
31+ configurable : true ,
32+ } ) ;
3133
3234 // Spy on history.replaceState to verify URL cleanup
3335 const replaceStateSpy = jasmine . createSpy ( 'replaceState' ) ;
3436 window . history . replaceState = replaceStateSpy ;
3537
3638 try {
37- // Import the function to test
38- const { routeToQueryAction } = await import ( '../utils.js' ) ;
39-
4039 // Call the function - this should parse URI and open chat
41- await routeToQueryAction ( ) ;
40+ await u . routeToQueryAction ( ) ;
4241
4342 // Verify that the URL was cleaned up (protocol handler removes ?uri=...)
4443 expect ( replaceStateSpy ) . toHaveBeenCalledWith (
@@ -54,7 +53,11 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
5453 expect ( chatbox . get ( 'jid' ) ) . toBe ( '[email protected] ' ) ; 5554 } finally {
5655 // Restore original globals to avoid test pollution
57- window . location = originalLocation ;
56+ if ( originalLocationDescriptor ) {
57+ Object . defineProperty ( window , 'location' , originalLocationDescriptor ) ;
58+ } else {
59+ delete window . location ;
60+ }
5861 window . history . replaceState = originalReplaceState ;
5962 }
6063 } ) ) ;
@@ -69,17 +72,19 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
6972 const { api } = _converse ;
7073 await mock . waitForRoster ( _converse , 'current' , 1 ) ;
7174
72- const originalLocation = window . location ;
75+ const originalLocationDescriptor = Object . getOwnPropertyDescriptor ( window , ' location' ) ;
7376 const originalReplaceState = window . history . replaceState ;
7477
7578 // Mock URI with message action: ?uri=xmpp:[email protected] ?action=message&body=Hello 76- delete window . location ;
77- window . location = {
78- search : '?uri=xmpp%3Aromeo%40montague.lit%3Faction%3Dmessage%26body%3DHello' ,
79- hash : '' ,
80- origin : 'http://localhost' ,
81- pathname : '/' ,
82- } ;
79+ Object . defineProperty ( window , "location" , {
80+ value : {
81+ search : '?uri=xmpp%3Aromeo%40montague.lit%3Faction%3Dmessage%26body%3DHello' ,
82+ hash : '' ,
83+ origin : 'http://localhost' ,
84+ pathname : '/' ,
85+ } ,
86+ configurable : true ,
87+ } ) ;
8388
8489 window . history . replaceState = jasmine . createSpy ( 'replaceState' ) ;
8590
@@ -103,103 +108,11 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
103108 expect ( message . get ( 'message' ) ) . toBe ( 'Hello' ) ;
104109 expect ( message . get ( 'type' ) ) . toBe ( 'chat' ) ;
105110 } finally {
106- window . location = originalLocation ;
107- window . history . replaceState = originalReplaceState ;
108- }
109- } ) ) ;
110-
111- /**
112- * Test error handling for invalid JIDs
113- * This ensures the function doesn't crash and handles invalid input gracefully
114- */
115- it ( "handles invalid JID gracefully" ,
116- mock . initConverse ( [ 'chatBoxesFetched' ] , { } , async function ( _converse ) {
117-
118- const originalLocation = window . location ;
119- const originalReplaceState = window . history . replaceState ;
120-
121- // Mock URI with invalid JID format
122- delete window . location ;
123- window . location = {
124- search : '?uri=xmpp%3Ainvalid-jid' ,
125- hash : '' ,
126- origin : 'http://localhost' ,
127- pathname : '/' ,
128- } ;
129-
130- window . history . replaceState = jasmine . createSpy ( 'replaceState' ) ;
131-
132- try {
133- const { routeToQueryAction } = await import ( '../utils.js' ) ;
134-
135- // Record initial chatbox count
136- const initialCount = _converse . chatboxes . length ;
137-
138- // Function should not throw an error, just log warning and return
139- await routeToQueryAction ( ) ;
140-
141- // Verify no new chatbox was created for invalid JID
142- expect ( _converse . chatboxes . length ) . toBe ( initialCount ) ;
143-
144- // URL should still be cleaned up even for invalid JIDs
145- expect ( window . history . replaceState ) . toHaveBeenCalled ( ) ;
146- } finally {
147- window . location = originalLocation ;
148- window . history . replaceState = originalReplaceState ;
149- }
150- } ) ) ;
151-
152- /**
153- * Test roster contact addition (action=add-roster)
154- * This tests the contact management functionality
155- */
156- it ( "adds contact to roster when action=add-roster" ,
157- mock . initConverse ( [ 'chatBoxesFetched' ] , { } , async function ( _converse ) {
158-
159- const { api } = _converse ;
160- await mock . waitForRoster ( _converse , 'current' , 1 ) ;
161- await mock . waitUntilDiscoConfirmed ( _converse , _converse . bare_jid , [ ] , [ ] ) ;
162-
163- const originalLocation = window . location ;
164- const originalReplaceState = window . history . replaceState ;
165-
166- // Mock URI with roster action: ?uri=xmpp:[email protected] ?action=add-roster&name=John&group=Friends 167- delete window . location ;
168- window . location = {
169- search : '?uri=xmpp%3Anewcontact%40montague.lit%3Faction%3Dadd-roster%26name%3DJohn%26group%3DFriends' ,
170- hash : '' ,
171- origin : 'http://localhost' ,
172- pathname : '/' ,
173- } ;
174-
175- window . history . replaceState = jasmine . createSpy ( 'replaceState' ) ;
176-
177- try {
178- const { routeToQueryAction } = await import ( '../utils.js' ) ;
179-
180- // Spy on connection send to verify roster IQ stanza
181- spyOn ( api . connection . get ( ) , 'send' ) ;
182-
183- await routeToQueryAction ( ) ;
184-
185- // Wait for roster IQ to be sent
186- await u . waitUntil ( ( ) => api . connection . get ( ) . send . calls . count ( ) > 0 ) ;
187-
188- // Verify the roster addition IQ was sent
189- const sent_stanzas = api . connection . get ( ) . send . calls . all ( ) . map ( call => call . args [ 0 ] ) ;
190- const roster_iq = sent_stanzas . find ( s =>
191- s . querySelector &&
192- s . querySelector ( 'iq[type="set"] query[xmlns="jabber:iq:roster"]' )
193- ) ;
194- expect ( roster_iq ) . toBeDefined ( ) ;
195-
196- // Verify roster item details
197- const item = roster_iq . querySelector ( 'item' ) ;
198- expect ( item . getAttribute ( 'jid' ) ) . toBe ( '[email protected] ' ) ; 199- expect ( item . getAttribute ( 'name' ) ) . toBe ( 'John' ) ;
200- expect ( item . querySelector ( 'group' ) . textContent ) . toBe ( 'Friends' ) ;
201- } finally {
202- window . location = originalLocation ;
111+ if ( originalLocationDescriptor ) {
112+ Object . defineProperty ( window , 'location' , originalLocationDescriptor ) ;
113+ } else {
114+ delete window . location ;
115+ }
203116 window . history . replaceState = originalReplaceState ;
204117 }
205118 } ) ) ;
0 commit comments