Files
margin-mail/src/providers.test.ts
T
pj eb59cb5f8d build the app, and ship it on Linux and Windows as well as macOS
The client itself: the sync engine and mirror, the Gmail and IMAP providers,
the screener, the three boxes and two piles, compose and send, the sanitiser
and tracker stripping, contacts, clips, backup, notifications and the guide.

The pipeline that ships it. Three runners now build in parallel and the
publish gate wants all four platform keys in latest.json before a release
leaves draft. Linux gets two more packages Tauri does not build: a flatpak
repackaged from the deb against GNOME 48, and a Nix package that relinks the
deb against nixpkgs so it runs as a native Wayland client rather than through
Xwayland. CI runs the Rust suite on all three desktops rather than on Linux
alone, and rebuilds the flatpak manifest on every push to main.

Two things that were only ever exercised on macOS and were wrong everywhere
else. The menu bar was built by adjusting the submenus macOS is given, so on
a platform whose default menu has no File or View the new File menu landed
after Edit, Check for Updates landed nowhere, and the three places and the
reading pane had no menu at all. The deb declared libwebkit2gtk-4.1-0 and
libgtk-3-0 twice, because tauri.conf.json named the dependencies Tauri
already emits.

The updater key exists now, so releases can sign their artifacts.
2026-09-06 12:15:30 +05:30

108 lines
4.0 KiB
TypeScript

// Where an address goes, decided twice: from the domain, and from the servers discovery found.
//
// These are the decisions with a right answer. A gmail.com address that ended up on a password
// panel would be a screen that fails on purpose, and a work domain hosted by Google that was not
// recognised would be the same failure one lookup later.
import { describe, expect, it } from "vitest";
import type { MailConfig } from "./ipc";
import { closedName, domainOf, passwordHint, providerName, routeFor, routeOf } from "./providers";
function found(imapHost: string, displayName: string | null = null): MailConfig {
const leg = (host: string) => ({
host,
port: 993,
security: "tls" as const,
auth: "password" as const,
username: "[email protected]",
});
return { imap: leg(imapHost), smtp: leg(imapHost), source: "ispdb", displayName };
}
describe("routeFor", () => {
it("sends Google's own domains to the browser without a lookup", () => {
expect(routeFor("[email protected]")).toBe("google");
expect(routeFor("[email protected]")).toBe("google");
});
it("recognises Microsoft's consumer domains under any country's ending", () => {
for (const address of [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
]) {
expect(routeFor(address), address).toBe("microsoft");
}
});
it("knows the providers that have no IMAP at all, by name", () => {
expect(routeFor("[email protected]")).toBe("closed");
expect(routeFor("[email protected]")).toBe("closed");
expect(closedName("[email protected]")).toBe("HEY");
expect(closedName("[email protected]")).toBe("Tuta");
});
it("looks everything else up, including domains that merely contain a provider's name", () => {
expect(routeFor("[email protected]")).toBe("lookup");
expect(routeFor("[email protected]")).toBe("lookup");
expect(routeFor("[email protected]")).toBe("lookup");
expect(routeFor("[email protected]")).toBe("lookup");
});
});
describe("routeOf", () => {
it("knows a custom domain by the servers it was found on", () => {
expect(routeOf(found("imap.gmail.com"))).toBe("google");
expect(routeOf(found("imap.googlemail.com"))).toBe("google");
expect(routeOf(found("outlook.office365.com"))).toBe("microsoft");
expect(routeOf(found("imap-mail.outlook.com"))).toBe("microsoft");
});
it("leaves everyone else on the password", () => {
expect(routeOf(found("imap.fastmail.com"))).toBe("password");
expect(routeOf(found("127.0.0.1"))).toBe("password");
expect(routeOf(found("mail.gmail.example"))).toBe("password");
});
});
describe("providerName", () => {
it("is what the provider calls itself, or the domain when it said nothing", () => {
expect(providerName(found("imap.fastmail.com", "Fastmail"), "[email protected]")).toBe(
"Fastmail",
);
expect(providerName(found("mail.northgate.example"), "[email protected]")).toBe(
"northgate.example",
);
expect(providerName(null, "nonsense")).toBe("this address");
});
});
describe("passwordHint", () => {
it("names the kind of password a provider wants before it is typed", () => {
expect(passwordHint(found("imap.fastmail.com"))).toContain("app password");
expect(passwordHint(found("imap.mail.me.com"))).toContain("app-specific password");
expect(passwordHint(found("imap.mail.yahoo.com"))).toContain("Yahoo");
expect(passwordHint(found("imap.aol.com"))).toContain("AOL");
});
it("says a loopback is a bridge with a password of its own", () => {
expect(passwordHint(found("127.0.0.1"))).toContain("Bridge shows under Mailbox details");
});
it("has nothing to add for a server it knows nothing about", () => {
expect(passwordHint(found("mail.northgate.example"))).toBeNull();
expect(passwordHint(null)).toBeNull();
});
});
describe("domainOf", () => {
it("is the lowercased half after the last @", () => {
expect(domainOf("[email protected] ")).toBe("example.com");
expect(domainOf("nonsense")).toBe("");
});
});