mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-05-19 14:08:24 -04:00
test: fix impossible test scenarios
This commit is contained in:
@@ -12,6 +12,7 @@ import * as context from "~/server/core/request-context";
|
||||
import * as spawnModule from "~/server/utils/spawn";
|
||||
import { restic } from "~/server/utils/restic";
|
||||
import { NotFoundError, BadRequestError } from "http-errors-enhanced";
|
||||
import { scheduleQueries } from "../backups.queries";
|
||||
|
||||
const resticBackupMock = mock(() => Promise.resolve({ exitCode: 0, summary: generateBackupOutput(), error: "" }));
|
||||
const resticForgetMock = mock(() => Promise.resolve({ success: true, data: null }));
|
||||
@@ -55,12 +56,21 @@ describe("backup execution - validation failures", () => {
|
||||
|
||||
test("should fail backup when volume does not exist", async () => {
|
||||
// arrange
|
||||
const volume = await createTestVolume();
|
||||
const repository = await createTestRepository();
|
||||
const schedule = await createTestBackupSchedule({
|
||||
volumeId: 99999,
|
||||
volumeId: volume.id,
|
||||
repositoryId: repository.id,
|
||||
});
|
||||
|
||||
const hydratedSchedule = await scheduleQueries.findById(schedule.id, TEST_ORG_ID);
|
||||
expect(hydratedSchedule).toBeDefined();
|
||||
const scheduleWithoutVolume = {
|
||||
...hydratedSchedule!,
|
||||
volume: null,
|
||||
} as unknown as NonNullable<Awaited<ReturnType<typeof scheduleQueries.findById>>>;
|
||||
spyOn(scheduleQueries, "findById").mockResolvedValueOnce(scheduleWithoutVolume);
|
||||
|
||||
// act
|
||||
const result = await backupsExecutionService.validateBackupExecution(schedule.id);
|
||||
|
||||
@@ -76,11 +86,20 @@ describe("backup execution - validation failures", () => {
|
||||
test("should fail backup when repository does not exist", async () => {
|
||||
// arrange
|
||||
const volume = await createTestVolume();
|
||||
const repository = await createTestRepository();
|
||||
const schedule = await createTestBackupSchedule({
|
||||
volumeId: volume.id,
|
||||
repositoryId: "non-existent-repo",
|
||||
repositoryId: repository.id,
|
||||
});
|
||||
|
||||
const hydratedSchedule = await scheduleQueries.findById(schedule.id, TEST_ORG_ID);
|
||||
expect(hydratedSchedule).toBeDefined();
|
||||
const scheduleWithoutRepository = {
|
||||
...hydratedSchedule!,
|
||||
repository: null,
|
||||
} as unknown as NonNullable<Awaited<ReturnType<typeof scheduleQueries.findById>>>;
|
||||
spyOn(scheduleQueries, "findById").mockResolvedValueOnce(scheduleWithoutRepository);
|
||||
|
||||
// act
|
||||
const result = await backupsExecutionService.validateBackupExecution(schedule.id);
|
||||
|
||||
@@ -216,14 +235,13 @@ describe("retention policy - runForget", () => {
|
||||
test("should throw NotFoundError when repository does not exist", async () => {
|
||||
// arrange
|
||||
const schedule = await createTestBackupSchedule({
|
||||
repositoryId: "non-existent-repo",
|
||||
retentionPolicy: {
|
||||
keepHourly: 24,
|
||||
},
|
||||
});
|
||||
|
||||
// act & assert
|
||||
expect(backupsExecutionService.runForget(schedule.id)).rejects.toThrow("Repository not found");
|
||||
expect(backupsExecutionService.runForget(schedule.id, "non-existent-repo")).rejects.toThrow("Repository not found");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { scheduleQueries } from "../backups.queries";
|
||||
import { createTestBackupSchedule } from "~/test/helpers/backup";
|
||||
import { createTestVolume } from "~/test/helpers/volume";
|
||||
import { createTestRepository } from "~/test/helpers/repository";
|
||||
import { createTestOrganization } from "~/test/helpers/organization";
|
||||
import { TEST_ORG_ID } from "~/test/helpers/organization";
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
@@ -140,6 +141,7 @@ describe("scheduleQueries.findExecutable", () => {
|
||||
test("should not return schedules from other organizations", async () => {
|
||||
// arrange
|
||||
const otherOrgId = faker.string.uuid();
|
||||
await createTestOrganization({ id: otherOrgId });
|
||||
const schedule = await createTestBackupSchedule({
|
||||
volumeId: volume.id,
|
||||
repositoryId: repository.id,
|
||||
|
||||
@@ -236,7 +236,7 @@ describe("listSchedules", () => {
|
||||
});
|
||||
|
||||
describe("cleanupOrphanedSchedules", () => {
|
||||
test("should delete orphaned schedules and their mirror assignments", async () => {
|
||||
test("should return zero when cascades already removed orphaned schedules", async () => {
|
||||
const healthyVolume = await createTestVolume();
|
||||
const healthyRepository = await createTestRepository();
|
||||
const healthySchedule = await createTestBackupSchedule({
|
||||
@@ -262,7 +262,7 @@ describe("cleanupOrphanedSchedules", () => {
|
||||
|
||||
const cleanupResult = await backupsService.cleanupOrphanedSchedules();
|
||||
|
||||
expect(cleanupResult.deletedSchedules).toBeGreaterThanOrEqual(1);
|
||||
expect(cleanupResult.deletedSchedules).toBe(0);
|
||||
|
||||
const deletedSchedule = await db.query.backupSchedulesTable.findFirst({
|
||||
where: { id: orphanSchedule.id },
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import { db } from "~/server/db/db";
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { backupSchedulesTable, type BackupScheduleInsert } from "~/server/db/schema";
|
||||
import { ensureTestOrganization, TEST_ORG_ID } from "./organization";
|
||||
import { createTestOrganization, ensureTestOrganization, TEST_ORG_ID } from "./organization";
|
||||
import { createTestVolume } from "./volume";
|
||||
import { createTestRepository } from "./repository";
|
||||
|
||||
export const createTestBackupSchedule = async (overrides: Partial<BackupScheduleInsert> = {}) => {
|
||||
await ensureTestOrganization();
|
||||
const organizationId = overrides.organizationId ?? TEST_ORG_ID;
|
||||
|
||||
if (organizationId === TEST_ORG_ID) {
|
||||
await ensureTestOrganization();
|
||||
} else {
|
||||
await createTestOrganization({ id: organizationId });
|
||||
}
|
||||
|
||||
const volumeId = overrides.volumeId ?? (await createTestVolume({ organizationId })).id;
|
||||
const repositoryId = overrides.repositoryId ?? (await createTestRepository({ organizationId })).id;
|
||||
|
||||
const backup: BackupScheduleInsert = {
|
||||
name: faker.system.fileName(),
|
||||
cronExpression: "0 0 * * *",
|
||||
repositoryId: "repo_123",
|
||||
volumeId: 1,
|
||||
repositoryId,
|
||||
volumeId,
|
||||
shortId: faker.string.uuid(),
|
||||
organizationId: TEST_ORG_ID,
|
||||
organizationId,
|
||||
...overrides,
|
||||
};
|
||||
|
||||
|
||||
@@ -25,4 +25,5 @@ void mock.module("~/server/utils/crypto", () => ({
|
||||
beforeAll(async () => {
|
||||
const migrationsFolder = path.join(cwd(), "app", "drizzle");
|
||||
migrate(db, { migrationsFolder });
|
||||
db.run("PRAGMA foreign_keys = ON;");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user