homeio
PublicForked from doctor-io/homeio
custom-apps-delete.test.ts
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("server-only", () => ({}));
const findInstalledStackByAppIdMock = vi.fn();
const dbExecuteMock = vi.fn();
const returningMock = vi.fn();
vi.mock("@/lib/server/modules/apps/stacks-repository", () => ({
findInstalledStackByAppId: (...args: unknown[]) => findInstalledStackByAppIdMock(...args),
}));
vi.mock("@/lib/server/db/drizzle", () => ({
db: {
execute: (...args: unknown[]) => dbExecuteMock(...args),
delete: () => ({ where: () => ({ returning: () => returningMock() }) }),
},
}));
import { deleteCustomStoreTemplate } from "@/lib/server/modules/store/custom-apps";
describe("deleteCustomStoreTemplate", () => {
beforeEach(() => {
findInstalledStackByAppIdMock.mockReset();
returningMock.mockReset();
dbExecuteMock.mockReset();
dbExecuteMock.mockResolvedValue({ rows: [{ table_exists: "custom_store_apps" }] });
});
it("refuses to remove the definition of an installed app", async () => {
// The definition is what redeploys and updates read from, so dropping it
// under a running stack would strand it.
findInstalledStackByAppIdMock.mockResolvedValue({ appId: "plex", status: "installed" });
await expect(deleteCustomStoreTemplate("plex")).rejects.toThrow(
/Uninstall this app before removing/i,
);
expect(returningMock).not.toHaveBeenCalled();
});
it("removes a leftover definition that was never installed", async () => {
findInstalledStackByAppIdMock.mockResolvedValue(null);
returningMock.mockResolvedValue([
{
appId: "custom-leftover",
name: "Leftover",
iconUrl: null,
webUiUrl: null,
sourceType: "docker-compose",
sourceText: "services: {}",
composeContent: "services:\n app:\n image: nginx:alpine\n",
repositoryUrl: null,
createdAt: new Date(),
updatedAt: new Date(),
},
]);
const removed = await deleteCustomStoreTemplate("custom-leftover");
expect(removed.isCustom).toBe(true);
});
it("reports a missing definition rather than succeeding quietly", async () => {
findInstalledStackByAppIdMock.mockResolvedValue(null);
returningMock.mockResolvedValue([]);
await expect(deleteCustomStoreTemplate("nope")).rejects.toThrow(/not found/i);
});
});