From 99a42823d2ad15eeac4932b7a77f032e571068ff Mon Sep 17 00:00:00 2001 From: mengw15 <125719918+mengw15@users.noreply.github.com> Date: Sun, 7 Jun 2026 03:11:24 -0700 Subject: [PATCH] test(frontend): extend GmailService spec to cover all methods The existing spec (added in #5164) covered sendEmail's success and error toasts. Add the remaining behavior: sendEmail request-body shape (explicit and defaulted receiver) and its console.error logging, getSenderEmail's GET request with no notification side-effect, and notifyUnauthorizedLogin's POST body, success toast, and error toast + console logging. Closes #5456. --- .../service/gmail/gmail.service.spec.ts | 72 +++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/common/service/gmail/gmail.service.spec.ts b/frontend/src/app/common/service/gmail/gmail.service.spec.ts index fd4ce18ca72..08ee8f09bb5 100644 --- a/frontend/src/app/common/service/gmail/gmail.service.spec.ts +++ b/frontend/src/app/common/service/gmail/gmail.service.spec.ts @@ -39,6 +39,7 @@ describe("GmailService", () => { afterEach(() => { httpTestingController.verify(); + vi.restoreAllMocks(); }); it("should show a success toast when the backend accepts the send request", () => { @@ -51,16 +52,77 @@ describe("GmailService", () => { expect(notificationSpy.error).not.toHaveBeenCalled(); }); - it("should show an error toast when the backend returns an HTTP error (e.g. SMTP failure)", () => { + it("sends the correct PUT body for sendEmail with an explicit receiver", () => { service.sendEmail("subj", "body", "to@example.com"); const req = httpTestingController.expectOne(r => r.url.endsWith("/gmail/send") && r.method === "PUT"); - req.flush("Failed to send email: 535-5.7.8 Username and Password not accepted", { - status: 502, - statusText: "Bad Gateway", - }); + expect(req.request.body).toEqual({ receiver: "to@example.com", subject: "subj", content: "body" }); + req.flush(null); + }); + + it("defaults the receiver to an empty string when it is omitted", () => { + service.sendEmail("subj", "body"); + + const req = httpTestingController.expectOne(r => r.url.endsWith("/gmail/send") && r.method === "PUT"); + expect(req.request.body).toEqual({ receiver: "", subject: "subj", content: "body" }); + req.flush(null); + }); + + it("shows an error toast and logs to the console on a failed send", () => { + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + service.sendEmail("subj", "body", "to@example.com"); + + const req = httpTestingController.expectOne(r => r.url.endsWith("/gmail/send") && r.method === "PUT"); + req.flush("boom", { status: 502, statusText: "Bad Gateway" }); expect(notificationSpy.error).toHaveBeenCalledWith("Failed to send email. Please try again or contact admin."); expect(notificationSpy.success).not.toHaveBeenCalled(); + expect(consoleSpy).toHaveBeenCalledWith("Send email error:", "boom"); + }); + + it("issues a GET to the sender-email endpoint and emits the response without notifying", () => { + let emitted: string | undefined; + service.getSenderEmail().subscribe(value => (emitted = value as string)); + + const req = httpTestingController.expectOne( + r => r.url.endsWith("/gmail/sender/email") && r.method === "GET" && r.responseType === "text" + ); + req.flush("sender@example.com"); + + expect(emitted).toBe("sender@example.com"); + expect(notificationSpy.success).not.toHaveBeenCalled(); + expect(notificationSpy.error).not.toHaveBeenCalled(); + }); + + it("sends the correct POST body for notifyUnauthorizedLogin", () => { + service.notifyUnauthorizedLogin("u@example.com", "ACME", "for research"); + + const req = httpTestingController.expectOne( + r => r.url.endsWith("/gmail/notify-unauthorized") && r.method === "POST" + ); + expect(req.request.body).toEqual({ receiver: "u@example.com", affiliation: "ACME", reason: "for research" }); + req.flush(null); + }); + + it("shows a success toast when the unauthorized-login notification is accepted", () => { + service.notifyUnauthorizedLogin("u@example.com", "ACME", "for research"); + + httpTestingController + .expectOne(r => r.url.endsWith("/gmail/notify-unauthorized") && r.method === "POST") + .flush(null); + + expect(notificationSpy.success).toHaveBeenCalledWith("An admin has been notified about your account request."); + }); + + it("shows an error toast and logs to the console when the notification fails", () => { + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + service.notifyUnauthorizedLogin("u@example.com", "ACME", "for research"); + + httpTestingController + .expectOne(r => r.url.endsWith("/gmail/notify-unauthorized") && r.method === "POST") + .flush("boom", { status: 500, statusText: "Internal Server Error" }); + + expect(notificationSpy.error).toHaveBeenCalledWith("Failed to notify admin about your account request."); + expect(consoleSpy).toHaveBeenCalledWith("Notify error:", "boom"); }); });