formies/__tests__/unit/services/emailService.test.js
Mohamad.Elsena a3236ae9d5 Refactor environment configuration for PostgreSQL and enhance application structure
- Updated `.env` and `.env.test` files to include PostgreSQL connection settings and Redis configuration.
- Migrated database from SQLite to PostgreSQL, updating relevant queries and connection logic.
- Enhanced error handling and logging throughout the application.
- Added new test utilities for PostgreSQL integration and updated user model methods.
- Introduced new routes for user authentication and form management, ensuring compatibility with the new database structure.
- Created login and registration views in EJS for user interaction.
2025-05-28 16:16:33 +02:00

134 lines
4.7 KiB
JavaScript

// __tests__/unit/services/emailService.test.js
const emailServiceModule = require("../../../src/services/emailService"); // Adjust path
const { Resend } = require("resend");
const logger = require("../../../config/logger"); // Adjust path
jest.mock("resend"); // Mock the Resend constructor and its methods
jest.mock("../../../config/logger"); // Mock logger to spy on it
describe("Email Service (Resend)", () => {
const mockSend = jest.fn();
const originalResendApiKey = process.env.RESEND_API_KEY;
const originalEmailFrom = process.env.EMAIL_FROM_ADDRESS;
beforeEach(() => {
mockSend.mockClear();
Resend.mockClear();
Resend.mockImplementation(() => ({
emails: { send: mockSend },
}));
// Ensure env vars are set for these tests
process.env.RESEND_API_KEY = "test-resend-api-key";
process.env.EMAIL_FROM_ADDRESS = "sender@example.com";
});
afterAll(() => {
process.env.RESEND_API_KEY = originalResendApiKey;
process.env.EMAIL_FROM_ADDRESS = originalEmailFrom;
});
describe("sendSubmissionNotification", () => {
const form = {
name: "Test Form",
email_notifications_enabled: true,
notification_email_address: "custom@example.com",
};
const submissionData = { name: "John Doe", message: "Hello" };
const userOwnerEmail = "owner@example.com";
it("should send email if notifications enabled and custom address provided", async () => {
mockSend.mockResolvedValue({ data: { id: "email_id_123" }, error: null });
await emailServiceModule.sendSubmissionNotification(
form,
submissionData,
userOwnerEmail
);
expect(Resend).toHaveBeenCalledWith("test-resend-api-key");
expect(mockSend).toHaveBeenCalledWith({
from: "sender@example.com",
to: "custom@example.com",
subject: "New Submission for Form: Test Form",
html: expect.stringContaining("<strong>Test Form</strong>"),
});
expect(logger.info).toHaveBeenCalledWith(
expect.stringContaining("Submission email sent successfully")
);
});
it("should use owner email if custom address not provided", async () => {
const formNoCustomEmail = { ...form, notification_email_address: null };
mockSend.mockResolvedValue({ data: { id: "email_id_123" }, error: null });
await emailServiceModule.sendSubmissionNotification(
formNoCustomEmail,
submissionData,
userOwnerEmail
);
expect(mockSend).toHaveBeenCalledWith(
expect.objectContaining({
to: "owner@example.com",
})
);
});
it("should not send email if notifications are disabled", async () => {
const disabledForm = { ...form, email_notifications_enabled: false };
await emailServiceModule.sendSubmissionNotification(
disabledForm,
submissionData,
userOwnerEmail
);
expect(mockSend).not.toHaveBeenCalled();
expect(logger.info).toHaveBeenCalledWith(
expect.stringContaining("Email notifications are disabled")
);
});
it("should log error if Resend fails", async () => {
const resendError = new Error("Resend API Error");
mockSend.mockResolvedValue({ data: null, error: resendError }); // Resend SDK might return error in object
// OR mockSend.mockRejectedValue(resendError); if it throws
await emailServiceModule.sendSubmissionNotification(
form,
submissionData,
userOwnerEmail
);
expect(logger.error).toHaveBeenCalledWith(
"Error sending submission email via Resend:",
resendError
);
});
it("should not send if RESEND_API_KEY is missing", async () => {
delete process.env.RESEND_API_KEY; // Temporarily remove
// Re-require or re-instantiate the service if it checks env vars at import time
// For this structure, the check is at the top of the file, so it might already be 'null'
// A better approach would be for the service to have an isConfigured() method.
// Forcing a re-import for the test is tricky without specific Jest features for module reloading.
// Let's assume the check inside sendSubmissionNotification handles the 'resend' object being null.
// To test this properly, we might need to re-import the module after changing env var
jest.resetModules(); // Clears module cache
process.env.RESEND_API_KEY = undefined;
const freshEmailService = require("../../../src/services/emailService");
await freshEmailService.sendSubmissionNotification(
form,
submissionData,
userOwnerEmail
);
expect(mockSend).not.toHaveBeenCalled();
expect(logger.warn).toHaveBeenCalledWith(
expect.stringContaining("Resend SDK not initialized")
);
process.env.RESEND_API_KEY = "test-resend-api-key"; // Restore
jest.resetModules(); // Clean up
});
});
// You would add similar tests for sendVerificationEmail, etc. from the old Nodemailer-based service
// if you intend to keep that functionality (currently it's commented out or separate)
});