setting sservices tests
This commit is contained in:
1 parent
4b1e8fb002
commit
9222d0b62d
1 file changed
+150
@@ -0,0 +1,150 @@
|
||||
import SettingsService from "@/services/system/SettingsService.js";
|
||||
import ApiError from "@/utils/ApiError.js";
|
||||
|
||||
// Mock models and mongoose db
|
||||
jest.mock("@/db/models/index.js", () => ({
|
||||
SystemSettings: {
|
||||
findById: jest.fn(),
|
||||
create: jest.fn(),
|
||||
findOneAndUpdate: jest.fn(),
|
||||
},
|
||||
}));
|
||||
import { SystemSettings } from "@/db/models/index.js";
|
||||
|
||||
jest.mock("mongoose", () => ({
|
||||
connection: { db: null },
|
||||
}));
|
||||
import mongoose from "mongoose";
|
||||
|
||||
// Mock EmailService used via setEmailService
|
||||
class MockEmailService {
|
||||
rebuildTransport = jest.fn();
|
||||
}
|
||||
|
||||
describe("SettingsService", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("get", () => {
|
||||
it("creates default settings when missing and returns settings", async () => {
|
||||
const select = (v) => ({ select: jest.fn().mockResolvedValue(v) });
|
||||
SystemSettings.findById
|
||||
.mockReturnValueOnce(select(null)) // initial check
|
||||
.mockReturnValueOnce(select({ _id: "global", systemEmailHost: "" })); // after create
|
||||
SystemSettings.create.mockResolvedValue({ _id: "global" });
|
||||
|
||||
const svc = new SettingsService();
|
||||
const res = await svc.get();
|
||||
expect(SystemSettings.create).toHaveBeenCalledWith({ _id: "global" });
|
||||
expect(res).toEqual({ _id: "global", systemEmailHost: "" });
|
||||
});
|
||||
|
||||
it("throws when settings cannot be loaded after create", async () => {
|
||||
const select = (v) => ({ select: jest.fn().mockResolvedValue(v) });
|
||||
SystemSettings.findById
|
||||
.mockReturnValueOnce(select(null))
|
||||
.mockReturnValueOnce(select(null));
|
||||
SystemSettings.create.mockResolvedValue({ _id: "global" });
|
||||
|
||||
const svc = new SettingsService();
|
||||
await expect(svc.get()).rejects.toMatchObject({
|
||||
message: "Unable to load system settings",
|
||||
status: 500,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("updateEmailSettings", () => {
|
||||
it("sets provided fields, unsets others, rebuilds transport and returns settings", async () => {
|
||||
const incoming = {
|
||||
systemEmailHost: "smtp.example.com",
|
||||
systemEmailPort: 587,
|
||||
systemEmailSecure: false,
|
||||
};
|
||||
const updated = { _id: "global", ...incoming };
|
||||
SystemSettings.findOneAndUpdate.mockResolvedValue(updated);
|
||||
|
||||
const svc = new SettingsService();
|
||||
const email = new MockEmailService();
|
||||
svc.setEmailService(email);
|
||||
const res = await svc.updateEmailSettings(incoming);
|
||||
|
||||
expect(SystemSettings.findOneAndUpdate).toHaveBeenCalledWith(
|
||||
{ _id: "global" },
|
||||
expect.objectContaining({ $set: expect.any(Object), $unset: expect.any(Object) }),
|
||||
expect.objectContaining({ new: true, upsert: true, setDefaultsOnInsert: true })
|
||||
);
|
||||
expect(email.rebuildTransport).toHaveBeenCalledWith(updated);
|
||||
expect(res).toBe(updated);
|
||||
});
|
||||
|
||||
it("throws when update returns no settings", async () => {
|
||||
SystemSettings.findOneAndUpdate.mockResolvedValue(null);
|
||||
const svc = new SettingsService();
|
||||
const email = new MockEmailService();
|
||||
svc.setEmailService(email);
|
||||
await expect(svc.updateEmailSettings({})).rejects.toMatchObject({
|
||||
message: "Unable to update system settings",
|
||||
status: 500,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("updateRetentionPolicy", () => {
|
||||
it("updates TTL via db.command and verifies expireAfterSeconds", async () => {
|
||||
SystemSettings.findOneAndUpdate.mockResolvedValue({ _id: "global" });
|
||||
const mockDb = {
|
||||
command: jest
|
||||
.fn()
|
||||
// collMod
|
||||
.mockResolvedValueOnce({ ok: 1 })
|
||||
// listCollections
|
||||
.mockResolvedValueOnce({ cursor: { firstBatch: [{ options: { expireAfterSeconds: 86400 } }] }, ok: 1 }),
|
||||
};
|
||||
mongoose.connection.db = mockDb;
|
||||
|
||||
const svc = new SettingsService();
|
||||
const result = await svc.updateRetentionPolicy(1); // 1 day
|
||||
expect(mockDb.command).toHaveBeenCalledWith({ collMod: "checks", expireAfterSeconds: 86400 });
|
||||
expect(result).toBe(1);
|
||||
});
|
||||
|
||||
it("throws when db not initialized", async () => {
|
||||
SystemSettings.findOneAndUpdate.mockResolvedValue({ _id: "global" });
|
||||
mongoose.connection.db = null;
|
||||
const svc = new SettingsService();
|
||||
await expect(svc.updateRetentionPolicy(1)).rejects.toMatchObject({
|
||||
message: "Database not initialized",
|
||||
status: 500,
|
||||
});
|
||||
});
|
||||
|
||||
it("throws when collMod fails", async () => {
|
||||
SystemSettings.findOneAndUpdate.mockResolvedValue({ _id: "global" });
|
||||
const mockDb = { command: jest.fn().mockResolvedValueOnce({ ok: 0 }) };
|
||||
mongoose.connection.db = mockDb;
|
||||
const svc = new SettingsService();
|
||||
await expect(svc.updateRetentionPolicy(1)).rejects.toMatchObject({
|
||||
message: "Failed to apply TTL to checks collection",
|
||||
status: 500,
|
||||
});
|
||||
});
|
||||
|
||||
it("throws when TTL verification fails", async () => {
|
||||
SystemSettings.findOneAndUpdate.mockResolvedValue({ _id: "global" });
|
||||
const mockDb = {
|
||||
command: jest
|
||||
.fn()
|
||||
.mockResolvedValueOnce({ ok: 1 })
|
||||
.mockResolvedValueOnce({ cursor: { firstBatch: [{ options: { expireAfterSeconds: 30 } }] }, ok: 1 }),
|
||||
};
|
||||
mongoose.connection.db = mockDb;
|
||||
const svc = new SettingsService();
|
||||
await expect(svc.updateRetentionPolicy(1)).rejects.toMatchObject({
|
||||
message: "TTL verification failed: expireAfterSeconds not applied",
|
||||
status: 500,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user