Complete Gmail correspondence workflow
This commit is contained in:
@@ -51,6 +51,30 @@ describe("correspondence Gmail import", () => {
|
||||
correspondenceMessages = [];
|
||||
|
||||
mockedApi.get.mockImplementation((url: string, config?: any) => {
|
||||
if (url === "/jobapplications") {
|
||||
return Promise.resolve({
|
||||
data: {
|
||||
items: [
|
||||
{
|
||||
id: 42,
|
||||
jobTitle: "Backend Developer",
|
||||
status: "Applied",
|
||||
dateApplied: new Date().toISOString(),
|
||||
daysSince: 3,
|
||||
company: { name: "Acme", recruiterEmail: "maria@acme.test", recruiterName: "Maria Recruiter" },
|
||||
},
|
||||
{
|
||||
id: 77,
|
||||
jobTitle: "Platform Engineer",
|
||||
status: "Applied",
|
||||
dateApplied: new Date().toISOString(),
|
||||
daysSince: 1,
|
||||
company: { name: "Beta" },
|
||||
},
|
||||
],
|
||||
},
|
||||
} as any);
|
||||
}
|
||||
if (url === "/jobapplications/42") {
|
||||
return Promise.resolve({
|
||||
data: {
|
||||
@@ -142,6 +166,15 @@ describe("correspondence Gmail import", () => {
|
||||
});
|
||||
|
||||
mockedApi.post.mockImplementation((url: string, body?: any) => {
|
||||
if (url === "/gmail/relink-thread") {
|
||||
correspondenceMessages = [];
|
||||
return Promise.resolve({ data: { threadId: body.threadId, jobApplicationId: body.jobApplicationId, imported: 1, skipped: 0, unlinkedMessages: 1 } } as any);
|
||||
}
|
||||
if (url === "/gmail/unlink-thread") {
|
||||
const removed = correspondenceMessages.filter((message) => message.externalThreadId === body.threadId).length;
|
||||
correspondenceMessages = correspondenceMessages.filter((message) => message.externalThreadId !== body.threadId);
|
||||
return Promise.resolve({ data: { threadId: body.threadId, jobApplicationId: body.jobApplicationId, removedMessages: removed, decision: body.nextDecision || 'review' } } as any);
|
||||
}
|
||||
if (url === "/gmail/refresh-linked-threads") {
|
||||
const hasReply = correspondenceMessages.some((message) => message.externalMessageId === "msg-2");
|
||||
if (!hasReply && correspondenceMessages.some((message) => message.externalThreadId === "thread-1")) {
|
||||
@@ -291,6 +324,72 @@ describe("correspondence Gmail import", () => {
|
||||
expect((await screen.findAllByText(/thread thread-1/i)).length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("lets the user unlink a linked Gmail thread", async () => {
|
||||
correspondenceMessages = [
|
||||
{
|
||||
id: 700,
|
||||
jobApplicationId: 42,
|
||||
from: "Company",
|
||||
content: "Acme wants to schedule a call.",
|
||||
subject: "Backend Developer interview",
|
||||
channel: "Email",
|
||||
date: new Date().toISOString(),
|
||||
externalMessageId: "msg-1",
|
||||
externalThreadId: "thread-1",
|
||||
externalFrom: "Maria Recruiter <maria@acme.test>",
|
||||
externalTo: "user@example.test",
|
||||
},
|
||||
];
|
||||
|
||||
renderDialog();
|
||||
|
||||
fireEvent.click(await screen.findByRole("button", { name: /manage thread-1/i }));
|
||||
fireEvent.click(await screen.findByRole("button", { name: /unlink from this job/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockedApi.post).toHaveBeenCalledWith("/gmail/unlink-thread", expect.objectContaining({
|
||||
jobApplicationId: 42,
|
||||
threadId: "thread-1",
|
||||
nextDecision: "review",
|
||||
}));
|
||||
});
|
||||
|
||||
expect(await screen.findByText(/no messages yet/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("lets the user move a linked Gmail thread to another job", async () => {
|
||||
correspondenceMessages = [
|
||||
{
|
||||
id: 702,
|
||||
jobApplicationId: 42,
|
||||
from: "Company",
|
||||
content: "Second import.",
|
||||
subject: "Backend Developer interview",
|
||||
channel: "Email",
|
||||
date: new Date().toISOString(),
|
||||
externalMessageId: "msg-1",
|
||||
externalThreadId: "thread-1",
|
||||
externalFrom: "Maria Recruiter <maria@acme.test>",
|
||||
externalTo: "user@example.test",
|
||||
},
|
||||
];
|
||||
|
||||
renderDialog();
|
||||
|
||||
fireEvent.click(await screen.findByRole("button", { name: /manage thread-1/i }));
|
||||
fireEvent.mouseDown((await screen.findAllByRole("combobox")).slice(-1)[0]);
|
||||
fireEvent.click(await screen.findByRole("option", { name: /beta • platform engineer/i }));
|
||||
fireEvent.click(screen.getByRole("button", { name: /move thread/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockedApi.post).toHaveBeenCalledWith("/gmail/relink-thread", expect.objectContaining({
|
||||
jobApplicationId: 77,
|
||||
threadId: "thread-1",
|
||||
removeFromOtherJobs: true,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
test("shows Gmail sync state diagnostics alongside linked thread continuity", async () => {
|
||||
renderDialog();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user