Skip to content

Commit 8c91e48

Browse files
Fixing tests
1 parent a22c1a0 commit 8c91e48

File tree

4 files changed

+99
-52
lines changed

4 files changed

+99
-52
lines changed

.genkit/traces_idx/genkit.metadata

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"1.21.0"}

dev.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
});
2727

2828
converse.initialize({
29-
i18n: 'af',
29+
i18n: 'fr',
3030
theme: 'nordic',
3131
dark_theme: 'dracula',
3232
auto_away: 300,
@@ -37,7 +37,7 @@
3737
notify_all_room_messages: ['[email protected]'],
3838
fetch_url_headers: true,
3939
whitelisted_plugins: ['converse-debug'],
40-
bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
40+
bosh_service_url: 'http://localhost:5280/http-bind', // Please use this connection manager only for testing purposes
4141
// view_mode: 'overlayed',
4242
show_controlbox_by_default: true,
4343
// websocket_url: 'wss://conversejs.org/xmpp-websocket',

src/plugins/chatview/tests/query-actions.js

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,23 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
1616
await mock.waitForRoster(_converse, 'current', 1);
1717

1818
// Save original globals to restore them later
19-
const originalLocationDescriptor = Object.getOwnPropertyDescriptor(window, 'location');
19+
const originalHash = window.location.hash;
2020
const originalReplaceState = window.history.replaceState;
2121

22-
// Mock window.location to simulate a protocol handler URI
23-
// This simulates: ?uri=xmpp:[email protected]
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-
});
33-
3422
// Spy on history.replaceState to verify URL cleanup
3523
const replaceStateSpy = jasmine.createSpy('replaceState');
3624
window.history.replaceState = replaceStateSpy;
3725

26+
// Simulate a protocol handler URI by setting the hash
27+
window.location.hash = '#converse/action?uri=xmpp%3Aromeo%40montague.lit';
28+
3829
try {
3930
// Call the function - this should parse URI and open chat
4031
await u.routeToQueryAction();
4132

4233
// Verify that the URL was cleaned up (protocol handler removes ?uri=...)
43-
expect(replaceStateSpy).toHaveBeenCalledWith(
44-
{},
45-
document.title,
46-
'http://localhost/'
47-
);
34+
const expected_url = `${window.location.origin}${window.location.pathname}`;
35+
expect(replaceStateSpy).toHaveBeenCalledWith({}, document.title, expected_url);
4836

4937
// Wait for and verify that a chatbox was created
5038
await u.waitUntil(() => _converse.chatboxes.get('[email protected]'));
@@ -53,11 +41,7 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
5341
expect(chatbox.get('jid')).toBe('[email protected]');
5442
} finally {
5543
// Restore original globals to avoid test pollution
56-
if (originalLocationDescriptor) {
57-
Object.defineProperty(window, 'location', originalLocationDescriptor);
58-
} else {
59-
delete window.location;
60-
}
44+
window.location.hash = originalHash;
6145
window.history.replaceState = originalReplaceState;
6246
}
6347
}));
@@ -66,36 +50,26 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
6650
* Test message sending functionality when action=message
6751
* This tests URI parsing, chat opening, and message sending
6852
*/
69-
it("sends a message when action=message with body",
53+
fit("sends a message when action=message with body",
7054
mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
7155

7256
const { api } = _converse;
7357
await mock.waitForRoster(_converse, 'current', 1);
7458

75-
const originalLocationDescriptor = Object.getOwnPropertyDescriptor(window, 'location');
59+
const originalHash = window.location.hash;
7660
const originalReplaceState = window.history.replaceState;
7761

78-
// Mock URI with message action: ?uri=xmpp:[email protected]?action=message&body=Hello
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-
});
88-
8962
window.history.replaceState = jasmine.createSpy('replaceState');
9063

91-
try {
92-
const { routeToQueryAction } = await import('../utils.js');
64+
// Mock URI with message action
65+
window.location.hash = '#converse/action?uri=xmpp%3Aromeo%40montague.lit%3Faction%3Dmessage%26body%3DHello';
9366

67+
try {
9468
// Spy on the connection send method to verify XMPP stanza sending
9569
spyOn(api.connection.get(), 'send');
9670

9771
// Execute the function
98-
await routeToQueryAction();
72+
await u.routeToQueryAction();
9973

10074
// Verify chat was opened
10175
await u.waitUntil(() => _converse.chatboxes.get('[email protected]'));
@@ -108,11 +82,85 @@ describe("XMPP URI Query Actions (XEP-0147)", function () {
10882
expect(message.get('message')).toBe('Hello');
10983
expect(message.get('type')).toBe('chat');
11084
} finally {
111-
if (originalLocationDescriptor) {
112-
Object.defineProperty(window, 'location', originalLocationDescriptor);
113-
} else {
114-
delete window.location;
115-
}
85+
window.location.hash = originalHash;
86+
window.history.replaceState = originalReplaceState;
87+
}
88+
}));
89+
90+
/**
91+
* Test roster add functionality when action=add-roster
92+
* This tests URI parsing and adding a contact to the roster
93+
*/
94+
fit("adds a contact to roster when action=add-roster",
95+
mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
96+
97+
const { api } = _converse;
98+
await mock.waitForRoster(_converse, 'current', 1);
99+
100+
const originalHash = window.location.hash;
101+
const originalReplaceState = window.history.replaceState;
102+
103+
window.history.replaceState = jasmine.createSpy('replaceState');
104+
105+
// Mock URI with add-roster action: ?uri=xmpp:[email protected]?action=add-roster&name=Juliet&group=Friends
106+
window.location.hash = '#converse/action?uri=xmpp%3Ajuliet%40capulet.lit%3Faction%3Dadd-roster%26name%3DJuliet%26group%3DFriends';
107+
108+
try {
109+
// Spy on the contacts.add API method - return a resolved promise to avoid network calls
110+
spyOn(api.contacts, 'add').and.returnValue(Promise.resolve());
111+
112+
// Execute the function
113+
await u.routeToQueryAction();
114+
115+
// Verify that contacts.add was called with correct parameters
116+
expect(api.contacts.add).toHaveBeenCalledWith(
117+
{
118+
119+
name: 'Juliet',
120+
groups: ['Friends']
121+
},
122+
true, // persist on server
123+
true, // subscribe to presence
124+
'' // no custom message
125+
);
126+
} finally {
127+
window.location.hash = originalHash;
128+
window.history.replaceState = originalReplaceState;
129+
}
130+
}));
131+
132+
/**
133+
* Test handling of invalid JIDs
134+
* This ensures the function gracefully handles malformed JIDs
135+
*/
136+
fit("handles invalid JID gracefully",
137+
mock.initConverse(['chatBoxesFetched'], {}, async function (_converse) {
138+
139+
const { api } = _converse;
140+
await mock.waitForRoster(_converse, 'current', 1);
141+
142+
const originalHash = window.location.hash;
143+
const originalReplaceState = window.history.replaceState;
144+
145+
window.history.replaceState = jasmine.createSpy('replaceState');
146+
147+
// Mock URI with invalid JID (missing domain)
148+
window.location.hash = '#converse/action?uri=xmpp%3Ainvalid-jid';
149+
150+
try {
151+
// Spy on api.chats.open to ensure it's NOT called for invalid JID
152+
spyOn(api.chats, 'open');
153+
154+
// Execute the function
155+
await u.routeToQueryAction();
156+
157+
// Verify that no chat was opened for the invalid JID
158+
expect(api.chats.open).not.toHaveBeenCalled();
159+
160+
// Verify no chatbox was created
161+
expect(_converse.chatboxes.get('invalid-jid')).toBeUndefined();
162+
} finally {
163+
window.location.hash = originalHash;
116164
window.history.replaceState = originalReplaceState;
117165
}
118166
}));

src/plugins/chatview/utils.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,24 @@ export async function routeToQueryAction(event) {
9090
const uri = extractXMPPURI(event);
9191
if (!uri) return;
9292

93-
const { jid, queryParams } = parseXMPPURI(uri);
93+
const { jid, query_params } = parseXMPPURI(uri);
9494
if (!u.isValidJID(jid)) {
9595
return log.warn(`routeToQueryAction: Invalid JID: "${jid}"`);
9696
}
9797

98-
const action = queryParams?.get('action');
98+
const action = query_params?.get('action');
9999
if (!action) {
100100
log.debug(`routeToQueryAction: No action specified, opening chat for "${jid}"`);
101101
return api.chats.open(jid);
102102
}
103103

104104
switch (action) {
105105
case 'message':
106-
await handleMessageAction(jid, queryParams);
106+
await handleMessageAction(jid, query_params);
107107
break;
108108

109109
case 'add-roster':
110-
await handleRosterAction(jid, queryParams);
110+
await handleRosterAction(jid, query_params);
111111
break;
112112

113113
default:
@@ -168,8 +168,6 @@ async function handleMessageAction(jid, params) {
168168
* Handles the `action=add-roster` case.
169169
*/
170170
async function handleRosterAction(jid, params) {
171-
await api.waitUntil('rosterContactsFetched');
172-
173171
const name = params.get('name') || jid.split('@')[0];
174172
const group = params.get('group');
175173
const groups = group ? [group] : [];

0 commit comments

Comments
 (0)