155 lines
5.4 KiB
TypeScript
155 lines
5.4 KiB
TypeScript
function assert(condition: unknown, message = "assertion failed"): void {
|
|
if (!condition) throw new Error(message);
|
|
}
|
|
|
|
function assertEqual<T>(actual: T, expected: T, message = "values should be equal"): void {
|
|
if (actual !== expected) throw new Error(`${message}: expected ${String(expected)}, got ${String(actual)}`);
|
|
}
|
|
|
|
function assertDeepEqual(actual: unknown, expected: unknown, message = "values should be deeply equal"): void {
|
|
const actualJson = JSON.stringify(actual);
|
|
const expectedJson = JSON.stringify(expected);
|
|
if (actualJson !== expectedJson) throw new Error(`${message}: expected ${expectedJson}, got ${actualJson}`);
|
|
}
|
|
|
|
import {
|
|
mailProfileChildDescriptors,
|
|
mailProfileEditTargetInitialSection,
|
|
mailProfileEditTargetPanelMode,
|
|
mailProfileEditTargetShowsProfileFields,
|
|
mailProfileEditTargetShowsSettingsPanel,
|
|
mailProfileEditTargetVisibleSections,
|
|
mailProfileCreateStageCanContinue,
|
|
mailProfileCreateStagePanel,
|
|
mailProfileCreateStages,
|
|
mailProfileCreateCredentialsPayload,
|
|
mailProfileTargetedUpdatePayload
|
|
} from "../src/features/mail/mailProfileEditorModel";
|
|
|
|
const smtpOnlyChildren = mailProfileChildDescriptors({ id: "profile-1", imap: null });
|
|
assertDeepEqual(
|
|
smtpOnlyChildren.map((child) => `${child.kind}:${child.protocol}`),
|
|
["server:smtp", "credential:smtp", "server:imap"],
|
|
"SMTP-only profiles expose SMTP server/credentials and an addable IMAP server"
|
|
);
|
|
assert(!smtpOnlyChildren.some((child) => child.kind === "credential" && child.protocol === "imap"), "IMAP credentials are hidden until an IMAP server exists");
|
|
|
|
const fullChildren = mailProfileChildDescriptors({ id: "profile-1", imap: { host: "imap.example.org" } });
|
|
assertDeepEqual(
|
|
fullChildren.map((child) => `${child.kind}:${child.protocol}`),
|
|
["server:smtp", "credential:smtp", "server:imap", "credential:imap"],
|
|
"profiles with IMAP expose focused rows for both transports and credentials"
|
|
);
|
|
|
|
assertEqual(mailProfileEditTargetInitialSection({ kind: "server", protocol: "imap" }), "imap");
|
|
assertEqual(mailProfileEditTargetPanelMode({ kind: "server", protocol: "smtp" }), "server");
|
|
assertEqual(mailProfileEditTargetPanelMode({ kind: "credentials", protocol: "imap" }), "credentials");
|
|
assertEqual(mailProfileEditTargetPanelMode({ kind: "profile" }), null);
|
|
assertDeepEqual(mailProfileEditTargetVisibleSections({ kind: "create" }), ["smtp", "imap"]);
|
|
assertDeepEqual(mailProfileEditTargetVisibleSections({ kind: "credentials", protocol: "imap" }), ["imap"]);
|
|
assertEqual(mailProfileEditTargetShowsProfileFields({ kind: "profile" }), true);
|
|
assertEqual(mailProfileEditTargetShowsProfileFields({ kind: "server", protocol: "smtp" }), false);
|
|
assertEqual(mailProfileEditTargetShowsSettingsPanel({ kind: "profile" }), false);
|
|
assertEqual(mailProfileEditTargetShowsSettingsPanel({ kind: "create" }), true);
|
|
assertDeepEqual(
|
|
mailProfileCreateStages,
|
|
[
|
|
"profile",
|
|
"smtp_server",
|
|
"smtp_credentials",
|
|
"imap_server",
|
|
"imap_credentials"
|
|
],
|
|
"profile creation keeps server and credential stages explicit"
|
|
);
|
|
assertDeepEqual(
|
|
mailProfileCreateStagePanel("smtp_credentials"),
|
|
{
|
|
showProfileFields: false,
|
|
showSettingsPanel: true,
|
|
initialSection: "smtp",
|
|
visibleSections: ["smtp"],
|
|
panelMode: "credentials"
|
|
}
|
|
);
|
|
assertDeepEqual(
|
|
mailProfileCreateStagePanel("imap_server"),
|
|
{
|
|
showProfileFields: false,
|
|
showSettingsPanel: true,
|
|
initialSection: "imap",
|
|
visibleSections: ["imap"],
|
|
panelMode: "server"
|
|
}
|
|
);
|
|
assertEqual(
|
|
mailProfileCreateStageCanContinue("profile", {
|
|
name: "",
|
|
smtpHost: "",
|
|
imapHost: "",
|
|
imapUsername: "",
|
|
imapPassword: ""
|
|
}),
|
|
false
|
|
);
|
|
assertEqual(
|
|
mailProfileCreateStageCanContinue("smtp_server", {
|
|
name: "Profile",
|
|
smtpHost: "smtp.example.org",
|
|
imapHost: "",
|
|
imapUsername: "",
|
|
imapPassword: ""
|
|
}),
|
|
true
|
|
);
|
|
assertEqual(
|
|
mailProfileCreateStageCanContinue("imap_credentials", {
|
|
name: "Profile",
|
|
smtpHost: "smtp.example.org",
|
|
imapHost: "",
|
|
imapUsername: "imap-user",
|
|
imapPassword: ""
|
|
}),
|
|
false,
|
|
"IMAP credentials cannot be submitted without an IMAP server"
|
|
);
|
|
|
|
const updateParts = {
|
|
profile: { name: "Renamed" },
|
|
smtp: { host: "smtp.example.org" },
|
|
imap: { host: "imap.example.org" },
|
|
credentials: {
|
|
smtp: { username: "smtp-user", password: "smtp-secret" },
|
|
imap: { username: "imap-user", password: "imap-secret" }
|
|
},
|
|
clearImap: false
|
|
};
|
|
assertDeepEqual(
|
|
mailProfileTargetedUpdatePayload({ kind: "profile" }, updateParts),
|
|
{ name: "Renamed" },
|
|
"profile edits do not replay transport or credential fields"
|
|
);
|
|
assertDeepEqual(
|
|
mailProfileTargetedUpdatePayload({ kind: "server", protocol: "smtp" }, updateParts),
|
|
{ smtp: { host: "smtp.example.org" } },
|
|
"server edits do not replay credential fields"
|
|
);
|
|
assertDeepEqual(
|
|
mailProfileTargetedUpdatePayload({ kind: "credentials", protocol: "imap" }, updateParts),
|
|
{ credentials: { imap: { username: "imap-user", password: "imap-secret" } } },
|
|
"credential edits send only the selected protocol"
|
|
);
|
|
assertEqual(
|
|
mailProfileCreateCredentialsPayload({ username: null }, { password: "" }),
|
|
undefined,
|
|
"credential-free creates omit the credential object"
|
|
);
|
|
assertDeepEqual(
|
|
mailProfileCreateCredentialsPayload(
|
|
{ username: "smtp-user", password: null },
|
|
{ username: null, password: "imap-secret" }
|
|
),
|
|
{ smtp: { username: "smtp-user" }, imap: { password: "imap-secret" } },
|
|
"create payloads retain only explicitly populated credential fields"
|
|
);
|