mirror of
https://github.com/hanzoai/calendar.git
synced 2026-09-24 22:42:24 +00:00
* --init * -- * replace old structure with new DI * fix type * -- * moving stuff around * moving stuff around again * minor clean up * -- * resolve conflict * clea up * old schema clean up * further clean up * removing unwanted merged responsibilities * -- * improve DI and SOLID * some type fixes * --1 * clean up --cont * fix DI in facade for test * more fix * fix * checking * o.o * fix import * fix failing test --2 * fix failing test --3 * fix failing test --4 * normalization use * introduce facade container injection * uniform async telemetry spans * further improvements * replace prismock with repo mocks * ensure we don't pass prisma outside of repo * fix import * remove try catch from repo calls * async await fixes * using deps pattern * more clean up and fixes * more clean up * address feedback --1 * separation of concern * clean up * test clean up * feedback --2 * remove extra fetch * remove await * migrate _post test from prismock * fix type * -- * fix tokens path * rename AuditRepo * test --1 * update _post to integration test * fix test * fix test * test fix maybe? * -- * feedback * feedback * fixes * more feedback * NIT * use sentry and logger imports as planned * assertion in test * add missing test case * add tests for controllers and services * NITs * fix domain normalisation
328 lines
9.8 KiB
TypeScript
328 lines
9.8 KiB
TypeScript
import { describe, test, expect, vi, beforeEach } from "vitest";
|
|
|
|
import { WatchlistType, WatchlistAction, WatchlistSource } from "@calcom/prisma/enums";
|
|
|
|
import type { SpanFn } from "../lib/telemetry";
|
|
import { listAllSystemEntriesController } from "./list-all-system-entries.controller";
|
|
|
|
// Mock the DI container
|
|
vi.mock("@calcom/features/di/watchlist/containers/watchlist", () => ({
|
|
getWatchlistFeature: vi.fn(),
|
|
}));
|
|
|
|
const mockWatchlistService = {
|
|
listAllSystemEntries: vi.fn(),
|
|
};
|
|
|
|
const mockWatchlistFeature: Partial<
|
|
ReturnType<typeof import("../lib/facade/WatchlistFeature").createWatchlistFeature>
|
|
> = {
|
|
watchlist: mockWatchlistService as never,
|
|
};
|
|
|
|
describe("listAllSystemEntriesController", () => {
|
|
beforeEach(async () => {
|
|
vi.clearAllMocks();
|
|
const { getWatchlistFeature } = await import("@calcom/features/di/watchlist/containers/watchlist");
|
|
vi.mocked(getWatchlistFeature).mockResolvedValue(
|
|
mockWatchlistFeature as ReturnType<typeof getWatchlistFeature>
|
|
);
|
|
});
|
|
|
|
describe("Basic functionality", () => {
|
|
test("should return all system entries (global + org)", async () => {
|
|
const mockEntries = [
|
|
{
|
|
id: "1",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: WatchlistType.DOMAIN,
|
|
value: "@competitor.com",
|
|
description: "Competitor domain",
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: false,
|
|
organizationId: 123,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
];
|
|
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue(mockEntries);
|
|
|
|
const result = await listAllSystemEntriesController({});
|
|
|
|
expect(result).toEqual(mockEntries);
|
|
expect(result).toHaveLength(2);
|
|
expect(mockWatchlistService.listAllSystemEntries).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
test("should return empty array when no entries exist", async () => {
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue([]);
|
|
|
|
const result = await listAllSystemEntriesController({});
|
|
|
|
expect(result).toEqual([]);
|
|
expect(mockWatchlistService.listAllSystemEntries).toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("Entry types", () => {
|
|
test("should return entries of all types (EMAIL, DOMAIN, USERNAME)", async () => {
|
|
const mockEntries = [
|
|
{
|
|
id: "1",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: WatchlistType.DOMAIN,
|
|
value: "@domain.com",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: WatchlistType.USERNAME,
|
|
value: "spammer123",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
];
|
|
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue(mockEntries);
|
|
|
|
const result = await listAllSystemEntriesController({});
|
|
|
|
expect(result).toHaveLength(3);
|
|
expect(result.map((e) => e.type)).toEqual([
|
|
WatchlistType.EMAIL,
|
|
WatchlistType.DOMAIN,
|
|
WatchlistType.USERNAME,
|
|
]);
|
|
});
|
|
|
|
test("should return entries with different actions (BLOCK, REPORT, ALERT)", async () => {
|
|
const mockEntries = [
|
|
{
|
|
id: "1",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.REPORT,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.ALERT,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
];
|
|
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue(mockEntries);
|
|
|
|
const result = await listAllSystemEntriesController({});
|
|
|
|
expect(result.map((e) => e.action)).toEqual([
|
|
WatchlistAction.BLOCK,
|
|
WatchlistAction.REPORT,
|
|
WatchlistAction.ALERT,
|
|
]);
|
|
});
|
|
|
|
test("should return entries with different sources (MANUAL, FREE_DOMAIN_POLICY)", async () => {
|
|
const mockEntries = [
|
|
{
|
|
id: "1",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: WatchlistType.DOMAIN,
|
|
value: "@gmail.com",
|
|
description: null,
|
|
action: WatchlistAction.REPORT,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.FREE_DOMAIN_POLICY,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
];
|
|
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue(mockEntries);
|
|
|
|
const result = await listAllSystemEntriesController({});
|
|
|
|
expect(result.map((e) => e.source)).toEqual([
|
|
WatchlistSource.MANUAL,
|
|
WatchlistSource.FREE_DOMAIN_POLICY,
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("Multiple organizations", () => {
|
|
test("should return entries from multiple organizations", async () => {
|
|
const mockEntries = [
|
|
{
|
|
id: "1",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: false,
|
|
organizationId: 100,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "2",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: false,
|
|
organizationId: 200,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
{
|
|
id: "3",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: false,
|
|
organizationId: 300,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
];
|
|
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue(mockEntries);
|
|
|
|
const result = await listAllSystemEntriesController({});
|
|
|
|
expect(result).toHaveLength(3);
|
|
const orgIds = result.map((e) => e.organizationId);
|
|
expect(orgIds).toEqual([100, 200, 300]);
|
|
expect(new Set(orgIds).size).toBe(3); // All different orgs
|
|
});
|
|
});
|
|
|
|
describe("Telemetry (span)", () => {
|
|
test("should call span when provided", async () => {
|
|
const mockEntries = [
|
|
{
|
|
id: "1",
|
|
type: WatchlistType.EMAIL,
|
|
value: "[email protected]",
|
|
description: null,
|
|
action: WatchlistAction.BLOCK,
|
|
isGlobal: true,
|
|
organizationId: null,
|
|
source: WatchlistSource.MANUAL,
|
|
lastUpdatedAt: new Date(),
|
|
},
|
|
];
|
|
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue(mockEntries);
|
|
|
|
const mockSpan: SpanFn = vi.fn((options, callback) => {
|
|
return Promise.resolve(callback());
|
|
});
|
|
|
|
const result = await listAllSystemEntriesController({
|
|
span: mockSpan,
|
|
});
|
|
|
|
expect(result).toEqual(mockEntries);
|
|
expect(mockSpan).toHaveBeenCalledWith(
|
|
{ name: "listAllSystemEntries Controller" },
|
|
expect.any(Function)
|
|
);
|
|
});
|
|
|
|
test("should not call span when not provided", async () => {
|
|
mockWatchlistService.listAllSystemEntries.mockResolvedValue([]);
|
|
|
|
const result = await listAllSystemEntriesController({
|
|
// No span provided
|
|
});
|
|
|
|
expect(result).toEqual([]);
|
|
// No span to verify - just ensure it doesn't crash
|
|
});
|
|
});
|
|
|
|
describe("Error handling", () => {
|
|
test("should propagate errors from service", async () => {
|
|
const error = new Error("Service error");
|
|
mockWatchlistService.listAllSystemEntries.mockRejectedValue(error);
|
|
|
|
await expect(listAllSystemEntriesController({})).rejects.toThrow("Service error");
|
|
});
|
|
|
|
test("should propagate errors from service when span is provided", async () => {
|
|
const error = new Error("Service error");
|
|
mockWatchlistService.listAllSystemEntries.mockRejectedValue(error);
|
|
|
|
const mockSpan: SpanFn = vi.fn((options, callback) => {
|
|
return Promise.resolve(callback());
|
|
});
|
|
|
|
await expect(listAllSystemEntriesController({ span: mockSpan })).rejects.toThrow("Service error");
|
|
expect(mockSpan).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|