test: share bluebubbles attachment fixtures

This commit is contained in:
Peter Steinberger 2026-03-13 21:23:29 +00:00
parent 89e0e80db3
commit eca22c0cc7
1 changed files with 24 additions and 36 deletions

View File

@ -82,6 +82,15 @@ describe("downloadBlueBubblesAttachment", () => {
).rejects.toThrow("too large");
}
function mockSuccessfulAttachmentDownload(buffer = new Uint8Array([1])) {
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers(),
arrayBuffer: () => Promise.resolve(buffer.buffer),
});
return buffer;
}
it("throws when guid is missing", async () => {
const attachment: BlueBubblesAttachment = {};
await expect(
@ -159,12 +168,7 @@ describe("downloadBlueBubblesAttachment", () => {
});
it("encodes guid in URL", async () => {
const mockBuffer = new Uint8Array([1]);
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers(),
arrayBuffer: () => Promise.resolve(mockBuffer.buffer),
});
mockSuccessfulAttachmentDownload();
const attachment: BlueBubblesAttachment = { guid: "att/with/special chars" };
await downloadBlueBubblesAttachment(attachment, {
@ -244,12 +248,7 @@ describe("downloadBlueBubblesAttachment", () => {
});
it("resolves credentials from config when opts not provided", async () => {
const mockBuffer = new Uint8Array([1]);
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers(),
arrayBuffer: () => Promise.resolve(mockBuffer.buffer),
});
mockSuccessfulAttachmentDownload();
const attachment: BlueBubblesAttachment = { guid: "att-config" };
const result = await downloadBlueBubblesAttachment(attachment, {
@ -270,12 +269,7 @@ describe("downloadBlueBubblesAttachment", () => {
});
it("passes ssrfPolicy with allowPrivateNetwork when config enables it", async () => {
const mockBuffer = new Uint8Array([1]);
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers(),
arrayBuffer: () => Promise.resolve(mockBuffer.buffer),
});
mockSuccessfulAttachmentDownload();
const attachment: BlueBubblesAttachment = { guid: "att-ssrf" };
await downloadBlueBubblesAttachment(attachment, {
@ -295,12 +289,7 @@ describe("downloadBlueBubblesAttachment", () => {
});
it("auto-allowlists serverUrl hostname when allowPrivateNetwork is not set", async () => {
const mockBuffer = new Uint8Array([1]);
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers(),
arrayBuffer: () => Promise.resolve(mockBuffer.buffer),
});
mockSuccessfulAttachmentDownload();
const attachment: BlueBubblesAttachment = { guid: "att-no-ssrf" };
await downloadBlueBubblesAttachment(attachment, {
@ -313,12 +302,7 @@ describe("downloadBlueBubblesAttachment", () => {
});
it("auto-allowlists private IP serverUrl hostname when allowPrivateNetwork is not set", async () => {
const mockBuffer = new Uint8Array([1]);
mockFetch.mockResolvedValueOnce({
ok: true,
headers: new Headers(),
arrayBuffer: () => Promise.resolve(mockBuffer.buffer),
});
mockSuccessfulAttachmentDownload();
const attachment: BlueBubblesAttachment = { guid: "att-private-ip" };
await downloadBlueBubblesAttachment(attachment, {
@ -352,6 +336,14 @@ describe("sendBlueBubblesAttachment", () => {
return Buffer.from(body).toString("utf8");
}
function expectVoiceAttachmentBody() {
const body = mockFetch.mock.calls[0][1]?.body as Uint8Array;
const bodyText = decodeBody(body);
expect(bodyText).toContain('name="isAudioMessage"');
expect(bodyText).toContain("true");
return bodyText;
}
it("marks voice memos when asVoice is true and mp3 is provided", async () => {
mockFetch.mockResolvedValueOnce({
ok: true,
@ -367,10 +359,7 @@ describe("sendBlueBubblesAttachment", () => {
opts: { serverUrl: "http://localhost:1234", password: "test" },
});
const body = mockFetch.mock.calls[0][1]?.body as Uint8Array;
const bodyText = decodeBody(body);
expect(bodyText).toContain('name="isAudioMessage"');
expect(bodyText).toContain("true");
const bodyText = expectVoiceAttachmentBody();
expect(bodyText).toContain('filename="voice.mp3"');
});
@ -389,8 +378,7 @@ describe("sendBlueBubblesAttachment", () => {
opts: { serverUrl: "http://localhost:1234", password: "test" },
});
const body = mockFetch.mock.calls[0][1]?.body as Uint8Array;
const bodyText = decodeBody(body);
const bodyText = expectVoiceAttachmentBody();
expect(bodyText).toContain('filename="voice.mp3"');
expect(bodyText).toContain('name="voice.mp3"');
});