mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 18:30:32 -06:00
test: unit test for display services (#1832)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
committed by
GitHub
parent
f6f45d74d5
commit
82302360fa
@@ -34,6 +34,7 @@ const selectDisplay = {
|
||||
surveyId: true,
|
||||
responseId: true,
|
||||
personId: true,
|
||||
status: true,
|
||||
};
|
||||
|
||||
export const getDisplay = async (displayId: string): Promise<TDisplay | null> => {
|
||||
@@ -42,7 +43,7 @@ export const getDisplay = async (displayId: string): Promise<TDisplay | null> =>
|
||||
validateInputs([displayId, ZId]);
|
||||
|
||||
try {
|
||||
const display = await prisma.response.findUnique({
|
||||
const display = await prisma.display.findUnique({
|
||||
where: {
|
||||
id: displayId,
|
||||
},
|
||||
@@ -143,7 +144,6 @@ export const updateDisplayLegacy = async (
|
||||
data,
|
||||
select: selectDisplay,
|
||||
});
|
||||
|
||||
displayCache.revalidate({
|
||||
id: display.id,
|
||||
surveyId: display.surveyId,
|
||||
@@ -164,7 +164,6 @@ export const createDisplay = async (displayInput: TDisplayCreateInput): Promise<
|
||||
validateInputs([displayInput, ZDisplayCreateInput]);
|
||||
|
||||
const { environmentId, userId, surveyId } = displayInput;
|
||||
|
||||
try {
|
||||
let person;
|
||||
if (userId) {
|
||||
@@ -191,13 +190,11 @@ export const createDisplay = async (displayInput: TDisplayCreateInput): Promise<
|
||||
},
|
||||
select: selectDisplay,
|
||||
});
|
||||
|
||||
displayCache.revalidate({
|
||||
id: display.id,
|
||||
personId: display.personId,
|
||||
surveyId: display.surveyId,
|
||||
});
|
||||
|
||||
return display;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
@@ -337,7 +334,6 @@ export const deleteDisplayByResponseId = async (
|
||||
personId: display.personId,
|
||||
surveyId,
|
||||
});
|
||||
|
||||
return display;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
|
||||
76
packages/lib/display/tests/__mocks__/data.mock.ts
Normal file
76
packages/lib/display/tests/__mocks__/data.mock.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
TDisplay,
|
||||
TDisplayCreateInput,
|
||||
TDisplayLegacyCreateInput,
|
||||
TDisplayLegacyUpdateInput,
|
||||
TDisplayUpdateInput,
|
||||
} from "@formbricks/types/displays";
|
||||
|
||||
export const mockEnvironmentId = "clqkr5961000108jyfnjmbjhi";
|
||||
export const mockSingleUseId = "qj57j3opsw8b5sxgea20fgcq";
|
||||
export const mockSurveyId = "clqkr8dlv000308jybb08evgr";
|
||||
export const mockUserId = "qwywazmugeezyfr3zcg9jk8a";
|
||||
export const mockDisplayId = "clqkr5smu000208jy50v6g5k4";
|
||||
export const mockId = "ars2tjk8hsi8oqk1uac00mo8";
|
||||
export const mockPersonId = "clqnj99r9000008lebgf8734j";
|
||||
export const mockResponseId = "clqnfg59i000208i426pb4wcv";
|
||||
|
||||
function createMockDisplay(overrides = {}) {
|
||||
return {
|
||||
id: mockDisplayId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
surveyId: mockSurveyId,
|
||||
responseId: null,
|
||||
personId: null,
|
||||
status: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export const mockDisplay: TDisplay = createMockDisplay();
|
||||
|
||||
export const mockDisplayWithPersonId: TDisplay = createMockDisplay({ personId: mockPersonId });
|
||||
|
||||
export const mockDisplayWithResponseId: TDisplay = createMockDisplay({
|
||||
personId: mockPersonId,
|
||||
responseId: mockResponseId,
|
||||
});
|
||||
|
||||
export const mockDisplayInput: TDisplayCreateInput = {
|
||||
environmentId: mockEnvironmentId,
|
||||
surveyId: mockSurveyId,
|
||||
};
|
||||
export const mockDisplayInputWithUserId: TDisplayCreateInput = {
|
||||
...mockDisplayInput,
|
||||
userId: mockUserId,
|
||||
};
|
||||
export const mockDisplayInputWithResponseId: TDisplayCreateInput = {
|
||||
...mockDisplayInputWithUserId,
|
||||
responseId: mockResponseId,
|
||||
};
|
||||
|
||||
export const mockDisplayLegacyInput: TDisplayLegacyCreateInput = {
|
||||
responseId: mockResponseId,
|
||||
surveyId: mockSurveyId,
|
||||
};
|
||||
export const mockDisplayLegacyInputWithPersonId: TDisplayLegacyCreateInput = {
|
||||
...mockDisplayLegacyInput,
|
||||
personId: mockPersonId,
|
||||
};
|
||||
|
||||
export const mockDisplayUpdate: TDisplayUpdateInput = {
|
||||
environmentId: mockEnvironmentId,
|
||||
userId: mockUserId,
|
||||
responseId: mockResponseId,
|
||||
};
|
||||
|
||||
export const mockDisplayLegacyUpdateInput: TDisplayLegacyUpdateInput = {
|
||||
personId: mockPersonId,
|
||||
responseId: mockResponseId,
|
||||
};
|
||||
|
||||
export const mockDisplayLegacyWithRespondedStatus: TDisplay = {
|
||||
...mockDisplayWithPersonId,
|
||||
status: "responded",
|
||||
};
|
||||
287
packages/lib/display/tests/display.unit.ts
Normal file
287
packages/lib/display/tests/display.unit.ts
Normal file
@@ -0,0 +1,287 @@
|
||||
import { mockPerson } from "../../response/tests/__mocks__/data.mock";
|
||||
import {
|
||||
mockDisplay,
|
||||
mockDisplayInput,
|
||||
mockDisplayInputWithUserId,
|
||||
mockDisplayLegacyInput,
|
||||
mockDisplayLegacyInputWithPersonId,
|
||||
mockDisplayLegacyUpdateInput,
|
||||
mockDisplayLegacyWithRespondedStatus,
|
||||
mockDisplayUpdate,
|
||||
mockDisplayWithPersonId,
|
||||
mockDisplayWithResponseId,
|
||||
mockResponseId,
|
||||
mockSurveyId,
|
||||
} from "./__mocks__/data.mock";
|
||||
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
import { prismaMock } from "@formbricks/database/src/jestClient";
|
||||
import { DatabaseError, ValidationError } from "@formbricks/types/errors";
|
||||
|
||||
import {
|
||||
createDisplay,
|
||||
createDisplayLegacy,
|
||||
deleteDisplayByResponseId,
|
||||
getDisplay,
|
||||
getDisplayCountBySurveyId,
|
||||
getDisplaysByPersonId,
|
||||
markDisplayRespondedLegacy,
|
||||
updateDisplay,
|
||||
updateDisplayLegacy,
|
||||
} from "../service";
|
||||
|
||||
const testInputValidation = async (service: Function, ...args: any[]): Promise<void> => {
|
||||
it("it should throw a ValidationError if the inputs are invalid", async () => {
|
||||
await expect(service(...args)).rejects.toThrow(ValidationError);
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
prismaMock.person.findFirst.mockResolvedValue(mockPerson);
|
||||
});
|
||||
|
||||
describe("Tests for getDisplay", () => {
|
||||
describe("Happy Path", () => {
|
||||
it("Returns display associated with a given display ID", async () => {
|
||||
prismaMock.display.findUnique.mockResolvedValue(mockDisplay);
|
||||
|
||||
const display = await getDisplay(mockDisplay.id);
|
||||
expect(display).toEqual(mockDisplay);
|
||||
});
|
||||
|
||||
it("Returns all displays associated with a given person ID", async () => {
|
||||
prismaMock.display.findMany.mockResolvedValue([mockDisplayWithPersonId]);
|
||||
|
||||
const displays = await getDisplaysByPersonId(mockPerson.id);
|
||||
expect(displays).toEqual([mockDisplayWithPersonId]);
|
||||
});
|
||||
|
||||
it("Returns an empty array when no displays are found for the given person ID", async () => {
|
||||
prismaMock.display.findMany.mockResolvedValue([]);
|
||||
|
||||
const displays = await getDisplaysByPersonId(mockPerson.id);
|
||||
expect(displays).toEqual([]);
|
||||
});
|
||||
|
||||
it("Returns display count for the given survey ID", async () => {
|
||||
prismaMock.display.count.mockResolvedValue(1);
|
||||
|
||||
const displaCount = await getDisplayCountBySurveyId(mockSurveyId);
|
||||
expect(displaCount).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sad Path", () => {
|
||||
testInputValidation(getDisplaysByPersonId, "123", 1);
|
||||
|
||||
it("Throws a DatabaseError error if there is a PrismaClientKnownRequestError", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
const errToThrow = new Prisma.PrismaClientKnownRequestError(mockErrorMessage, {
|
||||
code: "P2002",
|
||||
clientVersion: "0.0.1",
|
||||
});
|
||||
|
||||
prismaMock.display.findMany.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(getDisplaysByPersonId(mockPerson.id)).rejects.toThrow(DatabaseError);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for unexpected exceptions", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.display.findMany.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(getDisplaysByPersonId(mockPerson.id)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Tests for createDisplay service", () => {
|
||||
describe("Happy Path", () => {
|
||||
it("Creates a new display when a userId exists", async () => {
|
||||
prismaMock.display.create.mockResolvedValue(mockDisplayWithPersonId);
|
||||
|
||||
const display = await createDisplay(mockDisplayInputWithUserId);
|
||||
expect(display).toEqual(mockDisplayWithPersonId);
|
||||
});
|
||||
|
||||
it("Creates a new display when a userId does not exists", async () => {
|
||||
prismaMock.display.create.mockResolvedValue(mockDisplay);
|
||||
|
||||
const display = await createDisplay(mockDisplayInput);
|
||||
expect(display).toEqual(mockDisplay);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sad Path", () => {
|
||||
testInputValidation(createDisplay, "123");
|
||||
|
||||
it("Throws DatabaseError on PrismaClientKnownRequestError occurrence", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
const errToThrow = new Prisma.PrismaClientKnownRequestError(mockErrorMessage, {
|
||||
code: "P2002",
|
||||
clientVersion: "0.0.1",
|
||||
});
|
||||
|
||||
prismaMock.display.create.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(createDisplay(mockDisplayInputWithUserId)).rejects.toThrow(DatabaseError);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for other exceptions", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.display.create.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(createDisplay(mockDisplayInput)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Tests for updateDisplay Service", () => {
|
||||
describe("Happy Path", () => {
|
||||
it("Updates a display (responded)", async () => {
|
||||
prismaMock.display.update.mockResolvedValue(mockDisplayWithResponseId);
|
||||
|
||||
const display = await updateDisplay(mockDisplay.id, mockDisplayUpdate);
|
||||
expect(display).toEqual(mockDisplayWithResponseId);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sad Path", () => {
|
||||
testInputValidation(updateDisplay, "123", "123");
|
||||
|
||||
it("Throws DatabaseError on PrismaClientKnownRequestError", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
const errToThrow = new Prisma.PrismaClientKnownRequestError(mockErrorMessage, {
|
||||
code: "P2002",
|
||||
clientVersion: "0.0.1",
|
||||
});
|
||||
|
||||
prismaMock.display.update.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(updateDisplay(mockDisplay.id, mockDisplayUpdate)).rejects.toThrow(DatabaseError);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for other unexpected issues", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.display.update.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(updateDisplay(mockDisplay.id, mockDisplayUpdate)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Tests for createDisplayLegacy service", () => {
|
||||
describe("Happy Path", () => {
|
||||
it("Creates a display when a person ID exist", async () => {
|
||||
prismaMock.display.create.mockResolvedValue(mockDisplayWithPersonId);
|
||||
|
||||
const display = await createDisplayLegacy(mockDisplayLegacyInputWithPersonId);
|
||||
expect(display).toEqual(mockDisplayWithPersonId);
|
||||
});
|
||||
it("Creates a display when a person ID does not exist", async () => {
|
||||
prismaMock.display.create.mockResolvedValue(mockDisplay);
|
||||
|
||||
const display = await createDisplayLegacy(mockDisplayLegacyInput);
|
||||
expect(display).toEqual(mockDisplay);
|
||||
});
|
||||
});
|
||||
describe("Sad Path", () => {
|
||||
testInputValidation(createDisplayLegacy, "123");
|
||||
|
||||
it("Throws DatabaseError on PrismaClientKnownRequestError occurrence", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
const errToThrow = new Prisma.PrismaClientKnownRequestError(mockErrorMessage, {
|
||||
code: "P2002",
|
||||
clientVersion: "0.0.1",
|
||||
});
|
||||
|
||||
prismaMock.display.create.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(createDisplayLegacy(mockDisplayLegacyInputWithPersonId)).rejects.toThrow(DatabaseError);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for other exceptions", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.display.create.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(createDisplayLegacy(mockDisplayLegacyInputWithPersonId)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Tests for updateDisplayLegacy Service", () => {
|
||||
describe("Happy Path", () => {
|
||||
it("Updates a display", async () => {
|
||||
prismaMock.display.update.mockResolvedValue(mockDisplayWithPersonId);
|
||||
|
||||
const display = await updateDisplayLegacy(mockDisplay.id, mockDisplayLegacyUpdateInput);
|
||||
expect(display).toEqual(mockDisplayWithPersonId);
|
||||
});
|
||||
|
||||
it("marks display as responded legacy", async () => {
|
||||
prismaMock.display.update.mockResolvedValue(mockDisplayLegacyWithRespondedStatus);
|
||||
|
||||
const display = await markDisplayRespondedLegacy(mockDisplay.id);
|
||||
expect(display).toEqual(mockDisplayLegacyWithRespondedStatus);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Sad Path", () => {
|
||||
testInputValidation(updateDisplayLegacy, "123", "123");
|
||||
|
||||
it("Throws DatabaseError on PrismaClientKnownRequestError", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
const errToThrow = new Prisma.PrismaClientKnownRequestError(mockErrorMessage, {
|
||||
code: "P2002",
|
||||
clientVersion: "0.0.1",
|
||||
});
|
||||
|
||||
prismaMock.display.update.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(updateDisplayLegacy(mockDisplay.id, mockDisplayLegacyUpdateInput)).rejects.toThrow(
|
||||
DatabaseError
|
||||
);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for other unexpected issues", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.display.update.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(updateDisplayLegacy(mockDisplay.id, mockDisplayLegacyUpdateInput)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Tests for deleteDisplayByResponseId service", () => {
|
||||
describe("Happy Path", () => {
|
||||
it("Deletes a display when a response associated to it is deleted", async () => {
|
||||
prismaMock.display.delete.mockResolvedValue(mockDisplayWithResponseId);
|
||||
|
||||
const display = await deleteDisplayByResponseId(mockResponseId, mockSurveyId);
|
||||
expect(display).toEqual(mockDisplayWithResponseId);
|
||||
});
|
||||
});
|
||||
describe("Sad Path", () => {
|
||||
testInputValidation(createDisplayLegacy, "123");
|
||||
|
||||
it("Throws DatabaseError on PrismaClientKnownRequestError occurrence", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
const errToThrow = new Prisma.PrismaClientKnownRequestError(mockErrorMessage, {
|
||||
code: "P2002",
|
||||
clientVersion: "0.0.1",
|
||||
});
|
||||
|
||||
prismaMock.display.delete.mockRejectedValue(errToThrow);
|
||||
|
||||
await expect(deleteDisplayByResponseId(mockResponseId, mockSurveyId)).rejects.toThrow(DatabaseError);
|
||||
});
|
||||
|
||||
it("Throws a generic Error for other exceptions", async () => {
|
||||
const mockErrorMessage = "Mock error message";
|
||||
prismaMock.display.delete.mockRejectedValue(new Error(mockErrorMessage));
|
||||
|
||||
await expect(deleteDisplayByResponseId(mockResponseId, mockSurveyId)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -89,6 +89,7 @@ export const mockDisplay: TDisplay = {
|
||||
surveyId: mockSurveyId,
|
||||
personId: mockPersonId,
|
||||
responseId: mockResponseId,
|
||||
status: null,
|
||||
};
|
||||
|
||||
export const mockResponse: ResponseMock = {
|
||||
|
||||
@@ -7,7 +7,7 @@ export const ZDisplay = z.object({
|
||||
personId: z.string().cuid().nullable(),
|
||||
surveyId: z.string().cuid(),
|
||||
responseId: z.string().cuid().nullable(),
|
||||
status: z.enum(["seen", "responded"]).optional(),
|
||||
status: z.enum(["seen", "responded"]).nullable(),
|
||||
});
|
||||
|
||||
export type TDisplay = z.infer<typeof ZDisplay>;
|
||||
|
||||
Reference in New Issue
Block a user