Files
calendar/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.test.ts
T
c478f73327 feat: orgs trigger alert when loading a calendar and no availability is (#14796)
* Install upstash redis again - base of noficationSender

* Setup email handler etc and use tasker

* Remove logs

* Sending emails and correct format and spacing in emails

* Update email styles

* Update email styles

* add switch to enable feature

* fix: reset tasker types - will fix in new PR

* WIP: test suite

* WIP: test suite

* Add redis service and add WIP mock test

* Add tests for redis service and fix lpush

* More working tests

* More working tests

* fix: type error + typo

* update export to match i18n next mock

* (debug) push for debug

* Fix: fixed hosting in mocks

* Add common.json i18n

* add better test descriptions

* reset mocks after each test to allow concurancy

* Remove redundant RedisService.test.ts

* Rename and remove redundant isAdmin check

* Rename to .d.ts

* Add key versioning to constructRedisKey

* Update packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.ts

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Update packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.ts

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Add try/catch

* fix breaking when option === undefined

* Add missing await to Promise.all

* Rename data stored in redis to save space

* Include thrown error in logs

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2024-05-03 13:48:04 +00:00

121 lines
3.5 KiB
TypeScript

import i18nMock from "../../../../../../tests/libs/__mocks__/libServerI18n";
import prismaMock from "../../../../../../tests/libs/__mocks__/prismaMock";
import { vi, describe, it, beforeAll, afterAll, expect, beforeEach, afterEach } from "vitest";
import dayjs from "@calcom/dayjs";
import * as CalcomEmails from "@calcom/emails";
import { RedisService } from "@calcom/features/redis/RedisService";
import { handleNotificationWhenNoSlots } from "./handleNotificationWhenNoSlots";
vi.mock("@calcom/features/redis/RedisService", () => {
const mockedRedis = vi.fn();
mockedRedis.prototype.lrange = vi.fn();
mockedRedis.prototype.lpush = vi.fn();
mockedRedis.prototype.expire = vi.fn();
return {
RedisService: mockedRedis,
};
});
vi.mock("@calcom/features/flags/server/utils", () => {
// Mock kill switch to be false
return {
getFeatureFlag: vi.fn().mockResolvedValue(false),
};
});
vi.spyOn(CalcomEmails, "sendOrganizationAdminNoSlotsNotification");
describe("(Orgs) Send admin notifications when a user has no availability", () => {
beforeAll(() => {
// Setup env vars
vi.stubEnv("UPSTASH_REDIS_REST_TOKEN", "mocked_token");
vi.stubEnv("UPSTASH_REDIS_REST_URL", "mocked_url");
});
beforeEach(() => {
// Setup mocks
prismaMock.membership.findMany.mockResolvedValue([
{
user: {
email: "test@test.com",
locale: "en",
},
},
]);
// @ts-expect-error FIXME - also type error in bookingScenario
i18nMock.getTranslation.mockImplementation(() => {
return new Promise((resolve) => {
const identityFn = (key: string) => key;
resolve(identityFn);
});
});
});
afterEach(() => {
vi.resetAllMocks();
});
afterAll(() => {
vi.unstubAllEnvs();
});
it("Should send a notification after 2 times if the org has them enabled", async () => {
const redisService = new RedisService();
const mocked = vi.mocked(redisService);
prismaMock.team.findFirst.mockResolvedValue({
organizationSettings: {
adminGetsNoSlotsNotification: true,
},
});
// Define event and organization details
const eventDetails = {
username: "user1",
eventSlug: "event1",
startTime: dayjs(), // Mocking Dayjs format function
};
const orgDetails = {
currentOrgDomain: "org1",
isValidOrgDomain: true,
};
// Call the function
await handleNotificationWhenNoSlots({ eventDetails, orgDetails });
expect(CalcomEmails.sendOrganizationAdminNoSlotsNotification).not.toHaveBeenCalled();
// Mock length to be one then recall to trigger email
mocked.lrange.mockResolvedValueOnce([""]);
await handleNotificationWhenNoSlots({ eventDetails, orgDetails });
expect(CalcomEmails.sendOrganizationAdminNoSlotsNotification).toHaveBeenCalled();
});
it("Should not send a notification if the org has them disabled", async () => {
prismaMock.team.findFirst.mockResolvedValueOnce({
organizationSettings: {
adminGetsNoSlotsNotification: false,
},
});
// Define event and organization details
const eventDetails = {
username: "user1",
eventSlug: "event1",
startTime: dayjs(), // Mocking Dayjs format function
};
const orgDetails = {
currentOrgDomain: "org1",
isValidOrgDomain: true,
};
// Call the function
await handleNotificationWhenNoSlots({ eventDetails, orgDetails });
expect(CalcomEmails.sendOrganizationAdminNoSlotsNotification).not.toHaveBeenCalled();
});
});