2025-11-05 17:04:23 -03:00

151 lines
3.8 KiB
JavaScript

import { promise } from "@xmpp/events";
import { xml } from "@xmpp/xml";
import debug from "@xmpp/debug";
import JID from "@xmpp/jid";
import clone from "ltx/lib/clone.js";
import mockSocket from "./mockSocket.js";
import client from "./client.js";
export default function context(entity = client()) {
debug(entity);
entity.socket = mockSocket();
entity.jid = new JID("foo@bar/test");
const ctx = {
entity,
sanitize(s) {
const stanza = clone(s);
const { id } = stanza.attrs;
delete stanza.attrs.id;
delete stanza.attrs.xmlns;
return { stanza, id };
},
catch() {
return promise(entity, "send").then((s) => this.sanitize(s));
},
catchOutgoing(match = () => true) {
return new Promise((resolve) => {
function onSend(stanza) {
if (match(stanza)) {
entity.removeListener("send", onSend);
resolve(stanza);
}
}
entity.on("send", onSend);
});
},
catchOutgoingIq(match = () => true) {
return this.catchOutgoing((stanza) => stanza.is("iq") && match(stanza));
},
async catchOutgoingGet(match = () => true) {
const stanza = await this.catchOutgoingIq(
(stanza) => stanza.attrs.type === "get" && match(stanza),
);
const [child] = stanza.children;
if (child) {
child.parent = null;
}
return child;
},
async catchOutgoingSet(match = () => true) {
const stanza = await this.catchOutgoingIq(
(stanza) => stanza.attrs.type === "set" && match(stanza),
);
const [child] = stanza.children;
if (child) {
child.parent = null;
}
return child;
},
scheduleIncomingResult(child) {
return promise(entity, "send").then((stanza) => {
const { id } = stanza.attrs;
return this.fakeIncomingResult(child, id);
});
},
scheduleIncomingError(child) {
return promise(entity, "send").then((stanza) => {
const { id } = stanza.attrs;
return this.fakeIncomingError(child, id);
});
},
fakeIncomingGet(child, attrs = {}) {
attrs.type = "get";
return this.fakeIncomingIq(xml("iq", attrs, child)).then((stanza) => {
const [child] = stanza.children;
if (child) {
child.parent = null;
}
return child;
});
},
fakeIncomingSet(child, attrs = {}) {
attrs.type = "set";
return this.fakeIncomingIq(xml("iq", attrs, child)).then((stanza) => {
const [child] = stanza.children;
if (child) {
child.parent = null;
}
return child;
});
},
fakeIncomingResult(child, id) {
return this.fakeIncomingIq(xml("iq", { type: "result", id }, child)).then(
(stanza) => {
const [child] = stanza.children;
if (child) {
child.parent = null;
}
return child;
},
);
},
fakeIncomingError(child, id) {
return this.fakeIncomingIq(xml("iq", { type: "error", id }, child)).then(
(stanza) => {
const [child] = stanza.children;
if (child) {
child.parent = null;
}
return child;
},
);
},
fakeIncomingIq(el) {
const stanza = clone(el);
if (stanza.is("iq") && !stanza.attrs.id) {
stanza.attrs.id = "fake";
}
return this.fakeIncoming(stanza);
},
async fakeIncoming(el) {
const p = promise(entity, "send");
const stanza = clone(el);
delete stanza.attrs.xmlns;
await Promise.resolve();
this.mockInput(el);
await p;
return this.sanitize(el).stanza;
},
fakeOutgoing(el) {
entity.emit("send", el);
},
mockInput(el) {
entity.emit("input", el.toString());
entity._onElement(el);
},
};
return ctx;
}