Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import debug from "@xmpp/debug";
const xmpp = client({
service: "ws://localhost:5280/xmpp-websocket",
domain: "localhost",
lang: "en",
resource: "example",
username: "username",
password: "password",
Expand Down Expand Up @@ -100,6 +101,7 @@ See [jid package](/packages/jid)
- `ws://hostname:port/path` plain WebSocket
- `wss://hostname:port/path` secure WebSocket
- `domain` `<string>` Optional domain of the service, if omitted will use the hostname from `service`. Useful when the service domain is different than the service hostname.
- `lang` `<string>` Optional language tag for the stream, sets the `xml:lang` attribute on the stream per [RFC 6120 Section 4.7.4](https://xmpp.org/rfcs/rfc6120.html#streams-attr-xmllang). Useful for servers that use this attribute to determine the language for error messages.
- `resource` `<string`> Optional resource for [resource binding](/packages/resource-binding)
- `username` `<string>` Optional username for [sasl](/packages/sasl)
- `password` `<string>` Optional password for [sasl](/packages/sasl)
Expand Down
74 changes: 74 additions & 0 deletions packages/connection/test/open.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { EventEmitter } from "@xmpp/events";
import { mockSocket } from "@xmpp/test";

import Connection from "../index.js";

class MockParser extends EventEmitter {}

test("open() sets xml:lang attribute when lang option is provided", async () => {
const conn = new Connection({ domain: "example.com", lang: "en" });
conn.Parser = MockParser;
conn.socket = mockSocket();

// Emit 'open' event after a small delay to let open() set up
setTimeout(() => conn.emit("open"), 10);

await conn.open({ domain: "example.com", lang: "en" });

expect(conn.root.attrs["xml:lang"]).toBe("en");
expect(conn.root.attrs.to).toBe("example.com");
});

test("open() omits xml:lang attribute when lang option is undefined", async () => {
const conn = new Connection({ domain: "example.com" });
conn.Parser = MockParser;
conn.socket = mockSocket();

setTimeout(() => conn.emit("open"), 10);

await conn.open({ domain: "example.com", lang: undefined });

// The xml:lang attribute should be undefined (will be omitted in XML output)
expect(conn.root.attrs["xml:lang"]).toBe(undefined);
expect(conn.root.attrs.to).toBe("example.com");
});

test("start() passes lang option to open()", async () => {
const conn = new Connection({
service: "xmpp://localhost:5222",
domain: "example.com",
lang: "fr",
});
conn.Parser = MockParser;

// Mock connect to succeed immediately
conn.connect = async () => {
conn.socket = mockSocket();
conn._status("connect");
};

// Emit events after start() sets up listeners
setTimeout(() => {
conn.emit("open");
conn.emit("online");
}, 10);

await conn.start();

expect(conn.root.attrs["xml:lang"]).toBe("fr");
});

test("restart() passes lang option to open()", async () => {
const conn = new Connection({
domain: "example.com",
lang: "de",
});
conn.Parser = MockParser;
conn.socket = mockSocket();

setTimeout(() => conn.emit("open"), 10);

await conn.restart();

expect(conn.root.attrs["xml:lang"]).toBe("de");
});
Loading