Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
sonnyp committed Dec 29, 2024
1 parent 04ebdeb commit 6aa2226
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 22 deletions.
3 changes: 1 addition & 2 deletions packages/client-core/src/bind2/bind2.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ export default function bind2({ sasl2 }, tag) {
(element) => {
for (const child of element.getChildElements()) {
const feature = features.get(child.getNS());
if (!feature?.[1]) continue;
feature?.[1](child);
feature?.[1]?.(child);
}
},
);
Expand Down
3 changes: 1 addition & 2 deletions packages/sasl2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ async function authenticate({

for (const child of element.getChildElements()) {
const feature = features.get(child.getNS());
if (!feature?.[1]) continue;
feature?.[1](child);
feature?.[1]?.(child);
}

resolve(element);
Expand Down
2 changes: 1 addition & 1 deletion packages/sasl2/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ test("prefers SCRAM-SHA-1", async () => {
expect(result.attrs.mechanism).toEqual("SCRAM-SHA-1");
});

test.skip("use ANONYMOUS if username and password are not provided", async () => {
test("use ANONYMOUS if username and password are not provided", async () => {
const { entity } = mockClient();

entity.mockInput(
Expand Down
96 changes: 96 additions & 0 deletions packages/stream-management/bind2.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { mockClient } from "@xmpp/test";

test("enable", async () => {
const { entity, streamManagement: sm } = mockClient();

entity.mockInput(
<features xmlns="http://etherx.jabber.org/streams">
<authentication xmlns="urn:xmpp:sasl:2">
<mechanism>PLAIN</mechanism>
<inline>
<bind xmlns="urn:xmpp:bind:0">
<inline>
<feature var="urn:xmpp:sm:3" />
</inline>
</bind>
<sm xmlns="urn:xmpp:sm:3" />
</inline>
</authentication>
</features>,
);

const stanza_out = await entity.catchOutgoing();
expect(stanza_out).toEqual(
<authenticate xmlns="urn:xmpp:sasl:2" mechanism="PLAIN">
{stanza_out.getChild("initial-response")}
<bind xmlns="urn:xmpp:bind:0">
<enable xmlns="urn:xmpp:sm:3" resume="true" />
</bind>
</authenticate>,
);

expect(sm.enabled).toBe(false);
expect(sm.id).toBe("");
expect(sm.max).toBe(null);

entity.mockInput(
<success xmlns="urn:xmpp:sasl:2">
<bound xmlns="urn:xmpp:bind:0">
<enabled resume="1" xmlns="urn:xmpp:sm:3" id="2j44j2" max="600" />
</bound>
</success>,
);

expect(sm.enabled).toBe(true);
expect(sm.id).toBe("2j44j2");
expect(sm.max).toBe("600");
});

// https://xmpp.org/extensions/xep-0198.html#example-29
test("Client failed to enable stream management", async () => {
const { entity, streamManagement: sm } = mockClient();

entity.mockInput(
<features xmlns="http://etherx.jabber.org/streams">
<authentication xmlns="urn:xmpp:sasl:2">
<mechanism>PLAIN</mechanism>
<inline>
<bind xmlns="urn:xmpp:bind:0">
<inline>
<feature var="urn:xmpp:sm:3" />
</inline>
</bind>
<sm xmlns="urn:xmpp:sm:3" />
</inline>
</authentication>
</features>,
);

const stanza_out = await entity.catchOutgoing();
expect(stanza_out).toEqual(
<authenticate xmlns="urn:xmpp:sasl:2" mechanism="PLAIN">
{stanza_out.getChild("initial-response")}
<bind xmlns="urn:xmpp:bind:0">
<enable xmlns="urn:xmpp:sm:3" resume="true" />
</bind>
</authenticate>,
);

expect(sm.enabled).toBe(false);
expect(sm.id).toBe("");
expect(sm.max).toBe(null);

entity.mockInput(
<success xmlns="urn:xmpp:sasl:2">
<bound xmlns="urn:xmpp:bind:0">
<failed xmlns="urn:xmpp:sm:3">
<internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
</failed>
</bound>
</success>,
);

expect(sm.enabled).toBe(false);
expect(sm.id).toBe("");
expect(sm.max).toBe(null);
});
39 changes: 22 additions & 17 deletions packages/stream-management/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ export default function streamManagement({
});

if (bind2) {
setupBind2({ bind2, sm, resumed, failed, enabled });
setupBind2({ bind2, sm, failed, enabled });
}
if (sasl2) {
setupSasl2({ sasl2, sm });
setupSasl2({ sasl2, sm, failed, resumed });
}
if (streamFeatures) {
setupStreamFeature({
Expand Down Expand Up @@ -175,33 +175,38 @@ function setupStreamFeature({
});
}

function setupSasl2({ sasl2, sm }) {
sasl2.use("urn:xmpp:sm:3", (element) => {
if (!element.is("sm")) return;
if (sm.id) return makeResumeElement({ sm });
}),
(_element) => {
// FIXME handle errors
};
function setupSasl2({ sasl2, sm, failed, resumed }) {
sasl2.use(
"urn:xmpp:sm:3",
(element) => {
if (!element.is("sm")) return;
if (sm.id) return makeResumeElement({ sm });
},
(element) => {
if (element.is("resumed")) {
resumed();
} else if (element.is(failed)) {
// const error = StreamError.fromElement(element)
failed();
}
},
);
}

function setupBind2({ bind2, sm, resumed, failed, enabled }) {
function setupBind2({ bind2, sm, failed, enabled }) {
bind2.use(
"urn:xmpp:sm:3",
// https://xmpp.org/extensions/xep-0198.html#inline-examples
(element) => {
if (!element.is("feature")) return;
(_element) => {
return makeEnableElement({ sm });
},
(element) => {
if (element.is("resumed")) {
resumed();
} else if (element.is("enabled")) {
if (element.is("enabled")) {
enabled(element.attrs);
} else if (element.is("failed")) {
// const error = StreamError.fromElement(element)
failed();
}
// FIXME handle errors
},
);
}
78 changes: 78 additions & 0 deletions packages/stream-management/sasl2.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { mockClient } from "@xmpp/test";

test("resume", async () => {
const { entity, streamManagement: sm } = mockClient();

sm.id = Math.random().toString().slice(2);

entity.mockInput(
<features xmlns="http://etherx.jabber.org/streams">
<authentication xmlns="urn:xmpp:sasl:2">
<mechanism>PLAIN</mechanism>
<inline>
<sm xmlns="urn:xmpp:sm:3" />
</inline>
</authentication>
</features>,
);

sm.outbound = 45;
sm.inbound = 54;

// eslint-disable-next-line unicorn/no-await-expression-member
const element_resume = (await entity.catchOutgoing()).getChild("resume");
element_resume.parent = null;
expect(element_resume).toEqual(
<resume xmlns="urn:xmpp:sm:3" h="0" previd={sm.id} />,
);

entity.mockInput(
<success xmlns="urn:xmpp:sasl:2">
<resumed xmlns="urn:xmpp:sm:3" previd={sm.id} h="0" />
</success>,
);

expect(entity.streamManagement.outbound).toBe(45);
expect(entity.streamManagement.inbound).toBe(54);
expect(entity.streamManagement.enabled).toBe(true);
});

// https://xmpp.org/extensions/xep-0198.html#example-30
test("Client failed to resume stream", async () => {
const { entity, streamManagement: sm } = mockClient();

sm.id = Math.random().toString().slice(2);

entity.mockInput(
<features xmlns="http://etherx.jabber.org/streams">
<authentication xmlns="urn:xmpp:sasl:2">
<mechanism>PLAIN</mechanism>
<inline>
<sm xmlns="urn:xmpp:sm:3" />
</inline>
</authentication>
</features>,
);

sm.outbound = 45;
sm.inbound = 54;

// eslint-disable-next-line unicorn/no-await-expression-member
const element_resume = (await entity.catchOutgoing()).getChild("resume");
element_resume.parent = null;
expect(element_resume).toEqual(
<resume xmlns="urn:xmpp:sm:3" h="0" previd={sm.id} />,
);

entity.mockInput(
<success xmlns="urn:xmpp:sasl:2">
<failed xmlns="urn:xmpp:sm:3" h="another-sequence-number">
<item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
</failed>
</success>,
);

expect(entity.streamManagement.outbound).toBe(45);
expect(entity.streamManagement.inbound).toBe(54);
expect(entity.streamManagement.enabled).toBe(false);
});
File renamed without changes.

0 comments on commit 6aa2226

Please sign in to comment.