| import { describe, expect, it } from "vitest"; |
| import { |
| isAllowedBlueBubblesSender, |
| looksLikeBlueBubblesTargetId, |
| normalizeBlueBubblesMessagingTarget, |
| parseBlueBubblesTarget, |
| parseBlueBubblesAllowTarget, |
| } from "./targets.js"; |
|
|
| describe("normalizeBlueBubblesMessagingTarget", () => { |
| it("normalizes chat_guid targets", () => { |
| expect(normalizeBlueBubblesMessagingTarget("chat_guid:ABC-123")).toBe("chat_guid:ABC-123"); |
| }); |
|
|
| it("normalizes group numeric targets to chat_id", () => { |
| expect(normalizeBlueBubblesMessagingTarget("group:123")).toBe("chat_id:123"); |
| }); |
|
|
| it("strips provider prefix and normalizes handles", () => { |
| expect(normalizeBlueBubblesMessagingTarget("bluebubbles:imessage:User@Example.com")).toBe( |
| "imessage:user@example.com", |
| ); |
| }); |
|
|
| it("extracts handle from DM chat_guid for cross-context matching", () => { |
| |
| expect(normalizeBlueBubblesMessagingTarget("chat_guid:iMessage;-;+19257864429")).toBe( |
| "+19257864429", |
| ); |
| expect(normalizeBlueBubblesMessagingTarget("chat_guid:SMS;-;+15551234567")).toBe( |
| "+15551234567", |
| ); |
| |
| expect(normalizeBlueBubblesMessagingTarget("chat_guid:iMessage;-;user@example.com")).toBe( |
| "user@example.com", |
| ); |
| }); |
|
|
| it("preserves group chat_guid format", () => { |
| |
| expect(normalizeBlueBubblesMessagingTarget("chat_guid:iMessage;+;chat123456789")).toBe( |
| "chat_guid:iMessage;+;chat123456789", |
| ); |
| }); |
|
|
| it("normalizes raw chat_guid values", () => { |
| expect(normalizeBlueBubblesMessagingTarget("iMessage;+;chat660250192681427962")).toBe( |
| "chat_guid:iMessage;+;chat660250192681427962", |
| ); |
| expect(normalizeBlueBubblesMessagingTarget("iMessage;-;+19257864429")).toBe("+19257864429"); |
| }); |
|
|
| it("normalizes chat<digits> pattern to chat_identifier format", () => { |
| expect(normalizeBlueBubblesMessagingTarget("chat660250192681427962")).toBe( |
| "chat_identifier:chat660250192681427962", |
| ); |
| expect(normalizeBlueBubblesMessagingTarget("chat123")).toBe("chat_identifier:chat123"); |
| expect(normalizeBlueBubblesMessagingTarget("Chat456789")).toBe("chat_identifier:Chat456789"); |
| }); |
|
|
| it("normalizes UUID/hex chat identifiers", () => { |
| expect(normalizeBlueBubblesMessagingTarget("8b9c1a10536d4d86a336ea03ab7151cc")).toBe( |
| "chat_identifier:8b9c1a10536d4d86a336ea03ab7151cc", |
| ); |
| expect(normalizeBlueBubblesMessagingTarget("1C2D3E4F-1234-5678-9ABC-DEF012345678")).toBe( |
| "chat_identifier:1C2D3E4F-1234-5678-9ABC-DEF012345678", |
| ); |
| }); |
| }); |
|
|
| describe("looksLikeBlueBubblesTargetId", () => { |
| it("accepts chat targets", () => { |
| expect(looksLikeBlueBubblesTargetId("chat_guid:ABC-123")).toBe(true); |
| }); |
|
|
| it("accepts email handles", () => { |
| expect(looksLikeBlueBubblesTargetId("user@example.com")).toBe(true); |
| }); |
|
|
| it("accepts phone numbers with punctuation", () => { |
| expect(looksLikeBlueBubblesTargetId("+1 (555) 123-4567")).toBe(true); |
| }); |
|
|
| it("accepts raw chat_guid values", () => { |
| expect(looksLikeBlueBubblesTargetId("iMessage;+;chat660250192681427962")).toBe(true); |
| }); |
|
|
| it("accepts chat<digits> pattern as chat_id", () => { |
| expect(looksLikeBlueBubblesTargetId("chat660250192681427962")).toBe(true); |
| expect(looksLikeBlueBubblesTargetId("chat123")).toBe(true); |
| expect(looksLikeBlueBubblesTargetId("Chat456789")).toBe(true); |
| }); |
|
|
| it("accepts UUID/hex chat identifiers", () => { |
| expect(looksLikeBlueBubblesTargetId("8b9c1a10536d4d86a336ea03ab7151cc")).toBe(true); |
| expect(looksLikeBlueBubblesTargetId("1C2D3E4F-1234-5678-9ABC-DEF012345678")).toBe(true); |
| }); |
|
|
| it("rejects display names", () => { |
| expect(looksLikeBlueBubblesTargetId("Jane Doe")).toBe(false); |
| }); |
| }); |
|
|
| describe("parseBlueBubblesTarget", () => { |
| it("parses chat<digits> pattern as chat_identifier", () => { |
| expect(parseBlueBubblesTarget("chat660250192681427962")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "chat660250192681427962", |
| }); |
| expect(parseBlueBubblesTarget("chat123")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "chat123", |
| }); |
| expect(parseBlueBubblesTarget("Chat456789")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "Chat456789", |
| }); |
| }); |
|
|
| it("parses UUID/hex chat identifiers as chat_identifier", () => { |
| expect(parseBlueBubblesTarget("8b9c1a10536d4d86a336ea03ab7151cc")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "8b9c1a10536d4d86a336ea03ab7151cc", |
| }); |
| expect(parseBlueBubblesTarget("1C2D3E4F-1234-5678-9ABC-DEF012345678")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "1C2D3E4F-1234-5678-9ABC-DEF012345678", |
| }); |
| }); |
|
|
| it("parses explicit chat_id: prefix", () => { |
| expect(parseBlueBubblesTarget("chat_id:123")).toEqual({ kind: "chat_id", chatId: 123 }); |
| }); |
|
|
| it("parses phone numbers as handles", () => { |
| expect(parseBlueBubblesTarget("+19257864429")).toEqual({ |
| kind: "handle", |
| to: "+19257864429", |
| service: "auto", |
| }); |
| }); |
|
|
| it("parses raw chat_guid format", () => { |
| expect(parseBlueBubblesTarget("iMessage;+;chat660250192681427962")).toEqual({ |
| kind: "chat_guid", |
| chatGuid: "iMessage;+;chat660250192681427962", |
| }); |
| }); |
| }); |
|
|
| describe("parseBlueBubblesAllowTarget", () => { |
| it("parses chat<digits> pattern as chat_identifier", () => { |
| expect(parseBlueBubblesAllowTarget("chat660250192681427962")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "chat660250192681427962", |
| }); |
| expect(parseBlueBubblesAllowTarget("chat123")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "chat123", |
| }); |
| }); |
|
|
| it("parses UUID/hex chat identifiers as chat_identifier", () => { |
| expect(parseBlueBubblesAllowTarget("8b9c1a10536d4d86a336ea03ab7151cc")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "8b9c1a10536d4d86a336ea03ab7151cc", |
| }); |
| expect(parseBlueBubblesAllowTarget("1C2D3E4F-1234-5678-9ABC-DEF012345678")).toEqual({ |
| kind: "chat_identifier", |
| chatIdentifier: "1C2D3E4F-1234-5678-9ABC-DEF012345678", |
| }); |
| }); |
|
|
| it("parses explicit chat_id: prefix", () => { |
| expect(parseBlueBubblesAllowTarget("chat_id:456")).toEqual({ kind: "chat_id", chatId: 456 }); |
| }); |
|
|
| it("parses phone numbers as handles", () => { |
| expect(parseBlueBubblesAllowTarget("+19257864429")).toEqual({ |
| kind: "handle", |
| handle: "+19257864429", |
| }); |
| }); |
| }); |
|
|
| describe("isAllowedBlueBubblesSender", () => { |
| it("denies when allowFrom is empty", () => { |
| const allowed = isAllowedBlueBubblesSender({ |
| allowFrom: [], |
| sender: "+15551234567", |
| }); |
| expect(allowed).toBe(false); |
| }); |
|
|
| it("allows wildcard entries", () => { |
| const allowed = isAllowedBlueBubblesSender({ |
| allowFrom: ["*"], |
| sender: "+15551234567", |
| }); |
| expect(allowed).toBe(true); |
| }); |
| }); |
|
|