test(backend): add unit tests for MDM health-check DB helpers
This commit is contained in:
parent
15b4441deb
commit
7bf26a3138
303
backend/tests/devices/mdm-health.test.ts
Normal file
303
backend/tests/devices/mdm-health.test.ts
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/**
|
||||||
|
* Unit tests for the MDM health-check DB helpers in server/db/mdm.ts.
|
||||||
|
*
|
||||||
|
* Coverage:
|
||||||
|
* - getLinkedUserDevices
|
||||||
|
* - getMdmEnrollmentStatusesByUdids
|
||||||
|
* - updateUserDeviceMdmHealth
|
||||||
|
*
|
||||||
|
* All DB calls are mocked via vi.mock("../../server/utils/prisma") and
|
||||||
|
* vi.mock("pg").
|
||||||
|
*/
|
||||||
|
import { describe, expect, it, vi, beforeEach } from "vitest";
|
||||||
|
import {
|
||||||
|
getLinkedUserDevices,
|
||||||
|
getMdmEnrollmentStatusesByUdids,
|
||||||
|
updateUserDeviceMdmHealth,
|
||||||
|
type MdmEnrollmentStatus,
|
||||||
|
} from "../../server/db/mdm";
|
||||||
|
|
||||||
|
// ─── Prisma mock ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const mockPrisma = {
|
||||||
|
userDevice: {
|
||||||
|
findMany: vi.fn(),
|
||||||
|
update: vi.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
vi.mock("../../server/utils/prisma", () => ({
|
||||||
|
usePrisma: () => mockPrisma,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// ─── pg / NanoMDM pool mock ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const { mockPool } = vi.hoisted(() => {
|
||||||
|
const mockPool = {
|
||||||
|
query: vi.fn(),
|
||||||
|
};
|
||||||
|
return { mockPool };
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("pg", () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: {
|
||||||
|
Pool: vi.fn(() => mockPool),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// ─── Runtime config override ─────────────────────────────────────────────────
|
||||||
|
// setup.ts stubs useRuntimeConfig, but it does not include mdmDatabaseUrl which
|
||||||
|
// useMdmPool() requires to build the NanoMDM pg.Pool.
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const useRuntimeConfig = (globalThis as Record<string, unknown>)
|
||||||
|
.useRuntimeConfig as ReturnType<typeof vi.fn>;
|
||||||
|
useRuntimeConfig.mockReturnValue({
|
||||||
|
public: { supabase: { url: "", key: "" } },
|
||||||
|
supabase: { url: "", key: "" },
|
||||||
|
mdmDatabaseUrl: "postgres://localhost:5432/nanomdm",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── getLinkedUserDevices ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe("getLinkedUserDevices", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns an empty array when no linked iOS devices exist", async () => {
|
||||||
|
mockPrisma.userDevice.findMany.mockResolvedValue([]);
|
||||||
|
|
||||||
|
const result = await getLinkedUserDevices();
|
||||||
|
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
expect(mockPrisma.userDevice.findMany).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockPrisma.userDevice.findMany).toHaveBeenCalledWith({
|
||||||
|
where: { platform: "ios", mdmId: { not: null } },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
userId: true,
|
||||||
|
deviceId: true,
|
||||||
|
platform: true,
|
||||||
|
mdmId: true,
|
||||||
|
mdmEnrolled: true,
|
||||||
|
mdmSupervised: true,
|
||||||
|
mdmLastSeenAt: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns only iOS devices with mdmId != null and passes the correct where clause", async () => {
|
||||||
|
const now = new Date("2026-06-18T00:00:00.000Z");
|
||||||
|
const devices = [
|
||||||
|
{
|
||||||
|
id: "user-device-1",
|
||||||
|
userId: "user-1",
|
||||||
|
deviceId: "capacitor-id-1",
|
||||||
|
platform: "ios",
|
||||||
|
mdmId: "udid-1",
|
||||||
|
mdmEnrolled: true,
|
||||||
|
mdmSupervised: true,
|
||||||
|
mdmLastSeenAt: now,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
mockPrisma.userDevice.findMany.mockResolvedValue(devices);
|
||||||
|
|
||||||
|
const result = await getLinkedUserDevices();
|
||||||
|
|
||||||
|
expect(result).toEqual(devices);
|
||||||
|
expect(mockPrisma.userDevice.findMany).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockPrisma.userDevice.findMany).toHaveBeenCalledWith({
|
||||||
|
where: { platform: "ios", mdmId: { not: null } },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
userId: true,
|
||||||
|
deviceId: true,
|
||||||
|
platform: true,
|
||||||
|
mdmId: true,
|
||||||
|
mdmEnrolled: true,
|
||||||
|
mdmSupervised: true,
|
||||||
|
mdmLastSeenAt: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns multiple linked iOS devices when present", async () => {
|
||||||
|
const t1 = new Date("2026-06-17T10:00:00.000Z");
|
||||||
|
const t2 = new Date("2026-06-17T11:00:00.000Z");
|
||||||
|
const devices = [
|
||||||
|
{
|
||||||
|
id: "user-device-1",
|
||||||
|
userId: "user-1",
|
||||||
|
deviceId: "capacitor-id-1",
|
||||||
|
platform: "ios",
|
||||||
|
mdmId: "udid-1",
|
||||||
|
mdmEnrolled: true,
|
||||||
|
mdmSupervised: true,
|
||||||
|
mdmLastSeenAt: t1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "user-device-2",
|
||||||
|
userId: "user-2",
|
||||||
|
deviceId: "capacitor-id-2",
|
||||||
|
platform: "ios",
|
||||||
|
mdmId: "udid-2",
|
||||||
|
mdmEnrolled: false,
|
||||||
|
mdmSupervised: false,
|
||||||
|
mdmLastSeenAt: t2,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
mockPrisma.userDevice.findMany.mockResolvedValue(devices);
|
||||||
|
|
||||||
|
const result = await getLinkedUserDevices();
|
||||||
|
|
||||||
|
expect(result).toEqual(devices);
|
||||||
|
expect(result).toHaveLength(2);
|
||||||
|
expect(mockPrisma.userDevice.findMany).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── getMdmEnrollmentStatusesByUdids ─────────────────────────────────────────
|
||||||
|
|
||||||
|
describe("getMdmEnrollmentStatusesByUdids", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns an empty map without querying the pool when given an empty array", async () => {
|
||||||
|
const result = await getMdmEnrollmentStatusesByUdids([]);
|
||||||
|
|
||||||
|
expect(result).toEqual(new Map());
|
||||||
|
expect(mockPool.query).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps NanoMDM rows to Map<string, MdmEnrollmentStatus> correctly", async () => {
|
||||||
|
const lastSeenAt = new Date("2026-06-17T12:34:56.000Z");
|
||||||
|
mockPool.query.mockResolvedValue({
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
udid: "udid-enrolled",
|
||||||
|
enrolled: true,
|
||||||
|
supervised: true,
|
||||||
|
last_seen_at: lastSeenAt,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
udid: "udid-not-enrolled",
|
||||||
|
enrolled: false,
|
||||||
|
supervised: false,
|
||||||
|
last_seen_at: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await getMdmEnrollmentStatusesByUdids([
|
||||||
|
"udid-enrolled",
|
||||||
|
"udid-not-enrolled",
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(result).toEqual(
|
||||||
|
new Map<string, MdmEnrollmentStatus>([
|
||||||
|
[
|
||||||
|
"udid-enrolled",
|
||||||
|
{ enrolled: true, supervised: true, lastSeenAt: lastSeenAt },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"udid-not-enrolled",
|
||||||
|
{ enrolled: false, supervised: false, lastSeenAt: null },
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
expect(mockPool.query).toHaveBeenCalledTimes(1);
|
||||||
|
const [actualQuery, actualParams] = mockPool.query.mock.calls[0];
|
||||||
|
expect(actualQuery).toContain(
|
||||||
|
"LEFT JOIN enrollments e ON e.device_id = d.id",
|
||||||
|
);
|
||||||
|
expect(actualQuery).toContain(
|
||||||
|
"COALESCE(e.enabled = TRUE, FALSE) AS enrolled",
|
||||||
|
);
|
||||||
|
expect(actualQuery).toContain("(d.unlock_token IS NOT NULL) AS supervised");
|
||||||
|
expect(actualQuery).toContain("WHERE d.id = ANY($1::text[])");
|
||||||
|
expect(actualParams).toEqual([["udid-enrolled", "udid-not-enrolled"]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("omits UDIDs that are missing from NanoMDM", async () => {
|
||||||
|
mockPool.query.mockResolvedValue({
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
udid: "udid-present",
|
||||||
|
enrolled: true,
|
||||||
|
supervised: true,
|
||||||
|
last_seen_at: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await getMdmEnrollmentStatusesByUdids([
|
||||||
|
"udid-present",
|
||||||
|
"udid-missing",
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(result).toEqual(
|
||||||
|
new Map<string, MdmEnrollmentStatus>([
|
||||||
|
[
|
||||||
|
"udid-present",
|
||||||
|
{ enrolled: true, supervised: true, lastSeenAt: null },
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
expect(result.has("udid-missing")).toBe(false);
|
||||||
|
expect(mockPool.query).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ─── updateUserDeviceMdmHealth ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
describe("updateUserDeviceMdmHealth", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls prisma.userDevice.update with the correct where and data", async () => {
|
||||||
|
mockPrisma.userDevice.update.mockResolvedValue({ id: "user-device-1" });
|
||||||
|
|
||||||
|
const status: MdmEnrollmentStatus = {
|
||||||
|
enrolled: true,
|
||||||
|
supervised: false,
|
||||||
|
lastSeenAt: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateUserDeviceMdmHealth("user-device-1", status);
|
||||||
|
|
||||||
|
expect(mockPrisma.userDevice.update).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockPrisma.userDevice.update).toHaveBeenCalledWith({
|
||||||
|
where: { id: "user-device-1" },
|
||||||
|
data: {
|
||||||
|
mdmEnrolled: true,
|
||||||
|
mdmSupervised: false,
|
||||||
|
mdmLastSeenAt: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("persists a truthy lastSeenAt and supervised flag", async () => {
|
||||||
|
mockPrisma.userDevice.update.mockResolvedValue({ id: "user-device-2" });
|
||||||
|
const lastSeenAt = new Date("2026-06-17T12:34:56.000Z");
|
||||||
|
|
||||||
|
await updateUserDeviceMdmHealth("user-device-2", {
|
||||||
|
enrolled: true,
|
||||||
|
supervised: true,
|
||||||
|
lastSeenAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockPrisma.userDevice.update).toHaveBeenCalledWith({
|
||||||
|
where: { id: "user-device-2" },
|
||||||
|
data: {
|
||||||
|
mdmEnrolled: true,
|
||||||
|
mdmSupervised: true,
|
||||||
|
mdmLastSeenAt: lastSeenAt,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user