import { describe, expect, it, vi } from "vitest"; import { createEmailImportAccountController, createImapFlowOptions, type EmailImportConfig, isEmailImportServiceRunning, startConfiguredEmailImportService, stopEmailImportService, validateEmailImportConfiguration, } from "./emailImportService"; const baseConfig: EmailImportConfig = { userId: 2, emailAddress: "compta@example.org", password: "secret", host: "outlook.office365.com", port: 993, }; describe("createImapFlowOptions", () => { it("transmet le jeton brut à ImapFlow pour une authentification OAuth2", () => { const options = createImapFlowOptions( { ...baseConfig, authMode: "oauth2" }, "access-token-value", ); expect(options.secure).toBe(true); expect(options.auth).toEqual({ user: "compta@example.org", accessToken: "access-token-value", }); expect(options.auth).not.toHaveProperty("pass"); expect(options.tls?.rejectUnauthorized).toBe(true); expect(options.disableAutoIdle).toBe(true); }); it("conserve le mot de passe uniquement pour le mode basique", () => { const options = createImapFlowOptions({ ...baseConfig, authMode: "basic" }); expect(options.auth).toEqual({ user: "compta@example.org", pass: "secret", }); expect(options.auth).not.toHaveProperty("accessToken"); }); }); describe("validateEmailImportConfiguration", () => { it("accepte une boîte OAuth2 configurée même lorsque la planification automatique est désactivée", () => { const error = validateEmailImportConfiguration({ emailImportEnabled: 0, emailImportAddress: "compta@example.org", emailImportPassword: null, emailImportHost: "outlook.office365.com", emailImportPort: 993, emailImportSinceDate: null, emailImportAuthMode: "oauth2", azureTenantId: "tenant", azureClientId: "client", azureClientSecret: "secret", }); expect(error).toBeNull(); }); it("refuse une boîte dont la configuration IMAP est incomplète", () => { const error = validateEmailImportConfiguration({ emailImportEnabled: 0, emailImportAddress: "compta@example.org", emailImportPassword: null, emailImportHost: null, emailImportPort: 993, emailImportSinceDate: null, emailImportAuthMode: "oauth2", azureTenantId: "tenant", azureClientId: "client", azureClientSecret: "secret", }); expect(error).toBe("Configuration IMAP incomplète"); }); }); describe("startConfiguredEmailImportService", () => { it("ne crée aucune planification si le test IMAP préalable échoue", async () => { const userId = 901; stopEmailImportService(userId); const result = await startConfiguredEmailImportService( { ...baseConfig, userId, authMode: "basic" }, 5, async () => ({ success: false, message: "Authentification IMAP refusée.", }), ); expect(result).toEqual({ success: false, message: "Authentification IMAP refusée.", }); expect(isEmailImportServiceRunning(userId)).toBe(false); }); it("démarre après un test IMAP concluant et exécute le contrôle initial", async () => { const userId = 902; const runEmailCheck = vi.fn(async () => undefined); try { const result = await startConfiguredEmailImportService( { ...baseConfig, userId, authMode: "basic" }, 5, async () => ({ success: true, message: "Connexion IMAP réussie." }), runEmailCheck, ); expect(result).toEqual({ success: true, message: "Service de réception e-mail démarré", }); expect(isEmailImportServiceRunning(userId)).toBe(true); expect(runEmailCheck).toHaveBeenCalledWith(expect.objectContaining({ userId })); } finally { stopEmailImportService(userId); } }); }); describe("createEmailImportAccountController", () => { it("cible exclusivement le compte sélectionné par un administrateur", async () => { const start = vi.fn(async () => ({ success: true, message: "Service de réception e-mail démarré" })); const stop = vi.fn(); const isRunning = vi.fn(() => true); const controller = createEmailImportAccountController({ start, stop, isRunning }); await expect(controller.startAccount(42)).resolves.toEqual({ success: true, message: "Service de réception e-mail démarré", }); expect(start).toHaveBeenCalledWith(42); expect(controller.stopAccount(42)).toEqual({ success: true, message: "Service de réception e-mail arrêté", }); expect(stop).toHaveBeenCalledWith(42); expect(controller.accountStatus(42)).toEqual({ isRunning: true }); expect(isRunning).toHaveBeenCalledWith(42); }); });