snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
This commit is contained in:
647
supabase/functions/postmark/addNoteToContact.test.ts
Normal file
647
supabase/functions/postmark/addNoteToContact.test.ts
Normal file
@@ -0,0 +1,647 @@
|
||||
// @vitest-environment node
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import {
|
||||
addNoteToContact,
|
||||
findActiveSaleByEmail,
|
||||
getOrCreateCompanyFromDomain,
|
||||
getOrCreateContactFromEmailInfo,
|
||||
} from "./addNoteToContact";
|
||||
|
||||
const mockFrom = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("../_shared/supabaseAdmin.ts", () => ({
|
||||
supabaseAdmin: {
|
||||
from: (...args: unknown[]) => mockFrom(...args),
|
||||
},
|
||||
}));
|
||||
|
||||
const secondaryLookupResult = (
|
||||
rows: unknown[],
|
||||
error: { message: string } | null = null,
|
||||
) => ({
|
||||
neq: () => ({
|
||||
order: () => ({
|
||||
limit: () => Promise.resolve({ data: error ? null : rows, error }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const primaryLookupMiss = {
|
||||
select: () => ({
|
||||
eq: () => ({
|
||||
neq: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
describe("addNoteToContact", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
afterAll(() => {
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
describe("getOrCreateCompanyFromDomain", () => {
|
||||
it("returns the existing company when it already exists in the database", async () => {
|
||||
const existingCompany = {
|
||||
id: 1,
|
||||
name: "Acme",
|
||||
website: "https://acme.com",
|
||||
sales_id: 42,
|
||||
};
|
||||
mockFrom.mockReturnValue({
|
||||
select: () => ({
|
||||
or: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: existingCompany, error: null }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await getOrCreateCompanyFromDomain({
|
||||
domain: "acme.com",
|
||||
salesId: 42,
|
||||
companyName: "Acme",
|
||||
website: "https://acme.com",
|
||||
});
|
||||
|
||||
expect(result).toEqual(existingCompany);
|
||||
expect(mockFrom).toHaveBeenCalledWith("companies");
|
||||
});
|
||||
|
||||
it("throws when fetching the company fails", async () => {
|
||||
mockFrom.mockReturnValue({
|
||||
select: () => ({
|
||||
or: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: null, error: { message: "DB error" } }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
await expect(
|
||||
getOrCreateCompanyFromDomain({
|
||||
domain: "acme.com",
|
||||
salesId: 42,
|
||||
companyName: "Acme",
|
||||
website: "https://acme.com",
|
||||
}),
|
||||
).rejects.toThrow(
|
||||
"Could not fetch companies from database, name: acme.com, error: DB error",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns null for a known mail provider domain without creating a company", async () => {
|
||||
const result = await getOrCreateCompanyFromDomain({
|
||||
domain: "gmail.com",
|
||||
salesId: 42,
|
||||
companyName: "Gmail",
|
||||
website: "https://gmail.com",
|
||||
});
|
||||
|
||||
expect(result).toBeNull();
|
||||
// No database calls should be made for mail providers
|
||||
expect(mockFrom).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("creates and returns a new company when it does not exist and domain is not a mail provider", async () => {
|
||||
const newCompany = {
|
||||
id: 2,
|
||||
name: "Acme",
|
||||
website: "https://acme.com",
|
||||
sales_id: 42,
|
||||
};
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
// first call: fetch
|
||||
select: () => ({
|
||||
or: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
// second call: insert
|
||||
insert: () => ({
|
||||
select: () => Promise.resolve({ data: [newCompany], error: null }),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await getOrCreateCompanyFromDomain({
|
||||
domain: "acme.com",
|
||||
salesId: 42,
|
||||
companyName: "Acme",
|
||||
website: "https://acme.com",
|
||||
});
|
||||
|
||||
expect(result).toEqual(newCompany);
|
||||
expect(mockFrom).toHaveBeenCalledTimes(2);
|
||||
expect(mockFrom).toHaveBeenNthCalledWith(2, "companies");
|
||||
});
|
||||
|
||||
it("throws when creating the company fails", async () => {
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
or: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
insert: () => ({
|
||||
select: () =>
|
||||
Promise.resolve({
|
||||
data: null,
|
||||
error: { message: "Insert failed" },
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
await expect(
|
||||
getOrCreateCompanyFromDomain({
|
||||
domain: "acme.com",
|
||||
salesId: 42,
|
||||
companyName: "Acme",
|
||||
website: "https://acme.com",
|
||||
}),
|
||||
).rejects.toThrow(
|
||||
"Could not create company in database, domain: acme.com, error: Insert failed",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getOrCreateContactFromEmailInfo", () => {
|
||||
const contactParams = {
|
||||
email: "alice@acme.com",
|
||||
firstName: "Alice",
|
||||
lastName: "Smith",
|
||||
salesId: 42,
|
||||
domain: "acme.com",
|
||||
companyName: "Acme",
|
||||
website: "https://acme.com",
|
||||
};
|
||||
|
||||
it("returns the existing contact when it already exists in the database", async () => {
|
||||
const existingContact = {
|
||||
id: 10,
|
||||
first_name: "Alice",
|
||||
last_name: "Smith",
|
||||
};
|
||||
mockFrom.mockReturnValue({
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: existingContact, error: null }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await getOrCreateContactFromEmailInfo(contactParams);
|
||||
|
||||
expect(result).toEqual(existingContact);
|
||||
expect(mockFrom).toHaveBeenCalledWith("contacts");
|
||||
});
|
||||
|
||||
it("throws when fetching the contact fails", async () => {
|
||||
mockFrom.mockReturnValue({
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: null, error: { message: "DB error" } }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
await expect(
|
||||
getOrCreateContactFromEmailInfo(contactParams),
|
||||
).rejects.toThrow(
|
||||
"Could not fetch contact from database, email: alice@acme.com, error: DB error",
|
||||
);
|
||||
});
|
||||
|
||||
it("creates and returns a new contact with the associated company", async () => {
|
||||
const newContact = {
|
||||
id: 11,
|
||||
first_name: "Alice",
|
||||
last_name: "Smith",
|
||||
company_id: 1,
|
||||
};
|
||||
const existingCompany = {
|
||||
id: 1,
|
||||
name: "Acme",
|
||||
website: "https://acme.com",
|
||||
sales_id: 42,
|
||||
};
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
// 1st call: fetch contact → not found
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
// 2nd call: fetch company → found
|
||||
select: () => ({
|
||||
or: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: existingCompany, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
// 3rd call: insert contact
|
||||
insert: () => ({
|
||||
select: () => Promise.resolve({ data: [newContact], error: null }),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await getOrCreateContactFromEmailInfo(contactParams);
|
||||
|
||||
expect(result).toEqual(newContact);
|
||||
expect(mockFrom).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("creates a contact with null company_id when domain is a mail provider", async () => {
|
||||
const newContact = {
|
||||
id: 12,
|
||||
first_name: "Alice",
|
||||
last_name: "Smith",
|
||||
company_id: null,
|
||||
};
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
// 1st call: fetch contact → not found
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
// 2nd call: insert contact (with null company_id)
|
||||
insert: () => ({
|
||||
select: () => Promise.resolve({ data: [newContact], error: null }),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await getOrCreateContactFromEmailInfo({
|
||||
...contactParams,
|
||||
email: "alice@gmail.com",
|
||||
domain: "gmail.com",
|
||||
companyName: "Gmail",
|
||||
website: "https://gmail.com",
|
||||
});
|
||||
|
||||
expect(result).toEqual(newContact);
|
||||
// Only 2 froms: contacts fetch, contacts insert (no company fetch/insert for mail provider)
|
||||
expect(mockFrom).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("throws when creating the contact fails", async () => {
|
||||
const existingCompany = {
|
||||
id: 1,
|
||||
name: "Acme",
|
||||
website: "https://acme.com",
|
||||
sales_id: 42,
|
||||
};
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
or: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: existingCompany, error: null }),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
insert: () => ({
|
||||
select: () =>
|
||||
Promise.resolve({
|
||||
data: null,
|
||||
error: { message: "Insert failed" },
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
await expect(
|
||||
getOrCreateContactFromEmailInfo(contactParams),
|
||||
).rejects.toThrow(
|
||||
"Could not create contact in database, email: alice@acme.com, error: Insert failed",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findActiveSaleByEmail", () => {
|
||||
it("returns the active sale whose primary email matches the sender", async () => {
|
||||
const salesRecord = { id: 1, email: "sales@company.com" };
|
||||
mockFrom.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
eq: () => ({
|
||||
neq: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: salesRecord, error: null }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await findActiveSaleByEmail("sales@company.com");
|
||||
|
||||
expect(result.data).toEqual(salesRecord);
|
||||
expect(mockFrom).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("looks up the secondary emails when no primary email matches", async () => {
|
||||
const salesRecord = {
|
||||
id: 1,
|
||||
email: "sales@company.com",
|
||||
secondary_emails: ["perso@gmail.com"],
|
||||
};
|
||||
const contains = vi
|
||||
.fn()
|
||||
.mockReturnValue(secondaryLookupResult([salesRecord]));
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
eq: () => ({
|
||||
neq: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({ select: () => ({ contains }) });
|
||||
|
||||
const result = await findActiveSaleByEmail("perso@gmail.com");
|
||||
|
||||
expect(result.data).toEqual(salesRecord);
|
||||
expect(contains).toHaveBeenCalledWith(
|
||||
"secondary_emails",
|
||||
'["perso@gmail.com"]',
|
||||
);
|
||||
});
|
||||
|
||||
it("attributes to nobody when two sales share the same secondary email", async () => {
|
||||
const consoleSpy = vi
|
||||
.spyOn(console, "error")
|
||||
.mockImplementation(() => {});
|
||||
|
||||
mockFrom.mockReturnValueOnce(primaryLookupMiss).mockReturnValueOnce({
|
||||
select: () => ({
|
||||
contains: () =>
|
||||
secondaryLookupResult([
|
||||
{ id: 3, email: "a@company.com" },
|
||||
{ id: 9, email: "b@company.com" },
|
||||
]),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await findActiveSaleByEmail("shared@x.com");
|
||||
|
||||
expect(result.data).toBe(null);
|
||||
expect(result.error).toBe(null);
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("names both sales in the logs when it refuses an ambiguous sender", async () => {
|
||||
const consoleSpy = vi
|
||||
.spyOn(console, "error")
|
||||
.mockImplementation(() => {});
|
||||
|
||||
mockFrom.mockReturnValueOnce(primaryLookupMiss).mockReturnValueOnce({
|
||||
select: () => ({
|
||||
contains: () =>
|
||||
secondaryLookupResult([
|
||||
{ id: 3, email: "a@company.com" },
|
||||
{ id: 9, email: "b@company.com" },
|
||||
]),
|
||||
}),
|
||||
});
|
||||
|
||||
await findActiveSaleByEmail("shared@x.com");
|
||||
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining("shared@x.com"),
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("3, 9"));
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("surfaces a failure of the secondary lookup instead of reporting no sale", async () => {
|
||||
mockFrom.mockReturnValueOnce(primaryLookupMiss).mockReturnValueOnce({
|
||||
select: () => ({
|
||||
contains: () => secondaryLookupResult([], { message: "DB error" }),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await findActiveSaleByEmail("perso@gmail.com");
|
||||
|
||||
expect(result.data).toBe(null);
|
||||
expect(result.error).toEqual({ message: "DB error" });
|
||||
});
|
||||
|
||||
it("returns no sale rather than an error when nothing matches", async () => {
|
||||
mockFrom
|
||||
.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
eq: () => ({
|
||||
neq: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
select: () => ({ contains: () => secondaryLookupResult([]) }),
|
||||
});
|
||||
|
||||
const result = await findActiveSaleByEmail("nobody@x.com");
|
||||
|
||||
expect(result.data).toBe(null);
|
||||
expect(result.error).toBe(null);
|
||||
});
|
||||
|
||||
it("lowercases the sender, since the jsonb lookup is case sensitive unlike the citext column", async () => {
|
||||
const salesRecord = {
|
||||
id: 1,
|
||||
email: "sales@company.com",
|
||||
secondary_emails: ["perso@gmail.com"],
|
||||
};
|
||||
const eq = vi.fn().mockReturnValue({
|
||||
neq: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: null, error: null }),
|
||||
}),
|
||||
});
|
||||
const contains = vi
|
||||
.fn()
|
||||
.mockReturnValue(secondaryLookupResult([salesRecord]));
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce({ select: () => ({ eq }) })
|
||||
.mockReturnValueOnce({ select: () => ({ contains }) });
|
||||
|
||||
const result = await findActiveSaleByEmail(" Perso@Gmail.COM ");
|
||||
|
||||
expect(eq).toHaveBeenCalledWith("email", "perso@gmail.com");
|
||||
expect(contains).toHaveBeenCalledWith(
|
||||
"secondary_emails",
|
||||
'["perso@gmail.com"]',
|
||||
);
|
||||
expect(result.data).toEqual(salesRecord);
|
||||
});
|
||||
|
||||
it("does not look up the secondary emails when the first query fails", async () => {
|
||||
mockFrom.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
eq: () => ({
|
||||
neq: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: null, error: { message: "DB error" } }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await findActiveSaleByEmail("sales@company.com");
|
||||
|
||||
expect(result.error).toEqual({ message: "DB error" });
|
||||
expect(mockFrom).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("addNoteToContact", () => {
|
||||
const sales = { id: 1 };
|
||||
const baseParams = {
|
||||
sales,
|
||||
salesEmail: "sales@company.com",
|
||||
email: "alice@acme.com",
|
||||
domain: "acme.com",
|
||||
firstName: "Alice",
|
||||
lastName: "Smith",
|
||||
noteContent: "A note",
|
||||
attachments: [],
|
||||
companyName: "Acme",
|
||||
website: "https://acme.com",
|
||||
};
|
||||
|
||||
const contactFound = (contact: unknown) => ({
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () => Promise.resolve({ data: contact, error: null }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
it("creates a note and returns undefined on success", async () => {
|
||||
const existingContact = {
|
||||
id: 10,
|
||||
first_name: "Alice",
|
||||
last_name: "Smith",
|
||||
};
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce(contactFound(existingContact))
|
||||
.mockReturnValueOnce({
|
||||
insert: () => Promise.resolve({ error: null }),
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
update: () => ({
|
||||
eq: () => Promise.resolve({ error: null }),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await addNoteToContact(baseParams);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
expect(mockFrom).toHaveBeenCalledTimes(3);
|
||||
expect(mockFrom).toHaveBeenNthCalledWith(2, "contact_notes");
|
||||
expect(mockFrom).toHaveBeenNthCalledWith(3, "contacts");
|
||||
});
|
||||
|
||||
it("files the note under the sale it was given, without looking one up", async () => {
|
||||
const insertNote = vi.fn().mockResolvedValue({ error: null });
|
||||
|
||||
mockFrom
|
||||
.mockReturnValueOnce(contactFound({ id: 10 }))
|
||||
.mockReturnValueOnce({ insert: insertNote })
|
||||
.mockReturnValueOnce({
|
||||
update: () => ({
|
||||
eq: () => Promise.resolve({ error: null }),
|
||||
}),
|
||||
});
|
||||
|
||||
const result = await addNoteToContact({
|
||||
...baseParams,
|
||||
sales: { id: 7 },
|
||||
});
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
expect(insertNote).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ sales_id: 7, contact_id: 10 }),
|
||||
);
|
||||
expect(mockFrom).not.toHaveBeenCalledWith("sales");
|
||||
});
|
||||
|
||||
it("returns 500 when inserting the note into contact_notes fails", async () => {
|
||||
mockFrom
|
||||
.mockReturnValueOnce(contactFound({ id: 10 }))
|
||||
.mockReturnValueOnce({
|
||||
insert: () =>
|
||||
Promise.resolve({ error: { message: "Insert failed" } }),
|
||||
});
|
||||
|
||||
const response = await addNoteToContact(baseParams);
|
||||
|
||||
expect(response).toBeInstanceOf(Response);
|
||||
expect(response!.status).toBe(500);
|
||||
expect(await response!.text()).toBe(
|
||||
"Could not add note to contact alice@acme.com, sales sales@company.com",
|
||||
);
|
||||
expect(mockFrom).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it("returns 500 when getOrCreateContactFromEmailInfo throws", async () => {
|
||||
const consoleSpy = vi
|
||||
.spyOn(console, "error")
|
||||
.mockImplementation(() => {});
|
||||
|
||||
mockFrom.mockReturnValueOnce({
|
||||
select: () => ({
|
||||
contains: () => ({
|
||||
maybeSingle: () =>
|
||||
Promise.resolve({ data: null, error: { message: "DB error" } }),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const response = await addNoteToContact(baseParams);
|
||||
|
||||
expect(response).toBeInstanceOf(Response);
|
||||
expect(response!.status).toBe(500);
|
||||
expect(await response!.text()).toBe(
|
||||
"Could not get or create contact from database, email: alice@acme.com, sales: sales@company.com",
|
||||
);
|
||||
expect(consoleSpy).toHaveBeenCalled();
|
||||
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user