extract flipping monitor status, flip status on delete
This commit is contained in:
1 parent
abf66eed95
commit
0470eab782
2 files changed
+70
-13
No files matched your search
@@ -55,6 +55,24 @@ export class MaintenanceWindowService implements IMaintenanceWindowService {
|
||||
return MaintenanceWindowService.SERVICE_NAME;
|
||||
}
|
||||
|
||||
private flipMonitorsLeavingMaintenance = async (monitorIds: string[], teamId: string, excludeWindowId: string, now: Date): Promise<void> => {
|
||||
if (monitorIds.length === 0) return;
|
||||
|
||||
const otherWindows = await this.maintenanceWindowsRepository.findByMonitorIds(monitorIds, teamId, excludeWindowId);
|
||||
const stillCovered = new Set<string>();
|
||||
for (const otherWindow of otherWindows) {
|
||||
if (!isWindowActive(otherWindow, now)) continue;
|
||||
for (const monitorId of otherWindow.monitorIds) {
|
||||
if (monitorIds.includes(monitorId)) stillCovered.add(monitorId);
|
||||
}
|
||||
}
|
||||
|
||||
const toInitializing = monitorIds.filter((monitorId) => !stillCovered.has(monitorId));
|
||||
if (toInitializing.length > 0) {
|
||||
await this.monitorsRepository.updateByIds(toInitializing, teamId, { status: "initializing" });
|
||||
}
|
||||
};
|
||||
|
||||
createMaintenanceWindow = async ({
|
||||
teamId,
|
||||
monitorIDs,
|
||||
@@ -134,7 +152,14 @@ export class MaintenanceWindowService implements IMaintenanceWindowService {
|
||||
};
|
||||
|
||||
deleteMaintenanceWindow = async ({ id, teamId }: { id: string; teamId: string }) => {
|
||||
return await this.maintenanceWindowsRepository.deleteById(id, teamId);
|
||||
const deleted = await this.maintenanceWindowsRepository.deleteById(id, teamId);
|
||||
|
||||
const now = new Date();
|
||||
if (isWindowActive(deleted, now)) {
|
||||
await this.flipMonitorsLeavingMaintenance(deleted.monitorIds, teamId, deleted.id, now);
|
||||
}
|
||||
|
||||
return deleted;
|
||||
};
|
||||
|
||||
editMaintenanceWindow = async ({
|
||||
@@ -180,18 +205,7 @@ export class MaintenanceWindowService implements IMaintenanceWindowService {
|
||||
}
|
||||
|
||||
if (leavingCandidates.length > 0) {
|
||||
const otherWindows = await this.maintenanceWindowsRepository.findByMonitorIds(leavingCandidates, teamId, existing.id);
|
||||
const stillCovered = new Set<string>();
|
||||
for (const otherWindow of otherWindows) {
|
||||
if (!isWindowActive(otherWindow, now)) continue;
|
||||
for (const monitorId of otherWindow.monitorIds) {
|
||||
if (leavingCandidates.includes(monitorId)) stillCovered.add(monitorId);
|
||||
}
|
||||
}
|
||||
const toInitializing = leavingCandidates.filter((monitorId) => !stillCovered.has(monitorId));
|
||||
if (toInitializing.length > 0) {
|
||||
await this.monitorsRepository.updateByIds(toInitializing, teamId, { status: "initializing" });
|
||||
}
|
||||
await this.flipMonitorsLeavingMaintenance(leavingCandidates, teamId, existing.id, now);
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
@@ -233,6 +233,49 @@ describe("MaintenanceWindowService", () => {
|
||||
expect(result).toBe(deleted);
|
||||
expect(maintenanceWindowsRepository.deleteById).toHaveBeenCalledWith("mw-1", "team-1");
|
||||
});
|
||||
|
||||
it("does not touch monitor status when deleting an inactive window", async () => {
|
||||
// default fixture has past dates → inactive
|
||||
const { service, monitorsRepository, maintenanceWindowsRepository } = createService();
|
||||
|
||||
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
|
||||
|
||||
expect(monitorsRepository.updateByIds).not.toHaveBeenCalled();
|
||||
expect(maintenanceWindowsRepository.findByMonitorIds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("flips covered monitors to initializing when deleting an active window", async () => {
|
||||
const maintenanceWindowsRepository = createMaintenanceWindowsRepo();
|
||||
(maintenanceWindowsRepository.deleteById as jest.Mock).mockResolvedValue(makeActiveWindow({ monitorIds: ["mon-1", "mon-2"] }));
|
||||
const { service, monitorsRepository } = createService({ maintenanceWindowsRepository });
|
||||
|
||||
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
|
||||
|
||||
expect(monitorsRepository.updateByIds).toHaveBeenCalledTimes(1);
|
||||
expect(monitorsRepository.updateByIds).toHaveBeenCalledWith(["mon-1", "mon-2"], "team-1", { status: "initializing" });
|
||||
});
|
||||
|
||||
it("excludes the deleted window from the overlap check", async () => {
|
||||
const maintenanceWindowsRepository = createMaintenanceWindowsRepo();
|
||||
(maintenanceWindowsRepository.deleteById as jest.Mock).mockResolvedValue(makeActiveWindow({ monitorIds: ["mon-1"] }));
|
||||
const { service } = createService({ maintenanceWindowsRepository });
|
||||
|
||||
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
|
||||
|
||||
expect(maintenanceWindowsRepository.findByMonitorIds).toHaveBeenCalledWith(["mon-1"], "team-1", "mw-1");
|
||||
});
|
||||
|
||||
it("does not flip a monitor still covered by another active window", async () => {
|
||||
const maintenanceWindowsRepository = createMaintenanceWindowsRepo();
|
||||
(maintenanceWindowsRepository.deleteById as jest.Mock).mockResolvedValue(makeActiveWindow({ monitorIds: ["mon-1", "mon-2"] }));
|
||||
(maintenanceWindowsRepository.findByMonitorIds as jest.Mock).mockResolvedValue([makeActiveWindow({ id: "mw-2", monitorIds: ["mon-2"] })]);
|
||||
const { service, monitorsRepository } = createService({ maintenanceWindowsRepository });
|
||||
|
||||
await service.deleteMaintenanceWindow({ id: "mw-1", teamId: "team-1" });
|
||||
|
||||
expect(monitorsRepository.updateByIds).toHaveBeenCalledTimes(1);
|
||||
expect(monitorsRepository.updateByIds).toHaveBeenCalledWith(["mon-1"], "team-1", { status: "initializing" });
|
||||
});
|
||||
});
|
||||
|
||||
// ── editMaintenanceWindow ────────────────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user