This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-5460-6032413f6f1e65b6a32e53542c4668f00698ec26 in repository https://gitbox.apache.org/repos/asf/texera.git
commit 515d37221adb3d3e2ae282a8bd82151f547c3d51 Author: Meng Wang <[email protected]> AuthorDate: Sat Jun 13 10:18:45 2026 -0700 test(frontend): extend GmailService spec to cover all methods (#5460) ### What changes were proposed in this PR? Extends the existing `gmail.service.spec.ts` (added in #5164, which covered `sendEmail`'s success/error toasts) to cover the remaining surface of the 3-method service: - `sendEmail` request-body shape — explicit receiver, and the empty-string default when omitted - `sendEmail` error branch also logs `console.error("Send email error:", …)` - `getSenderEmail()` — a `GET` to `/gmail/sender/email` (text) that emits the body with no `NotificationService` side-effect - `notifyUnauthorizedLogin` — POST body shape, success toast, and error toast + `console.error` logging Follows `frontend/TESTING.md` (Vitest, `HttpClientTestingModule`). ### Any related issues, documentation, discussions? Closes #5456. Builds on #5164. ### How was this PR tested? `yarn test --include='**/gmail.service.spec.ts'` → 9 passed. `prettier --check` clean. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (claude-opus-4-7) --- .../app/common/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 fd4ce18ca7..08ee8f09bb 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", "[email protected]"); 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: "[email protected]", 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", "[email protected]"); + + 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("[email protected]"); + + expect(emitted).toBe("[email protected]"); + expect(notificationSpy.success).not.toHaveBeenCalled(); + expect(notificationSpy.error).not.toHaveBeenCalled(); + }); + + it("sends the correct POST body for notifyUnauthorizedLogin", () => { + service.notifyUnauthorizedLogin("[email protected]", "ACME", "for research"); + + const req = httpTestingController.expectOne( + r => r.url.endsWith("/gmail/notify-unauthorized") && r.method === "POST" + ); + expect(req.request.body).toEqual({ receiver: "[email protected]", affiliation: "ACME", reason: "for research" }); + req.flush(null); + }); + + it("shows a success toast when the unauthorized-login notification is accepted", () => { + service.notifyUnauthorizedLogin("[email protected]", "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("[email protected]", "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"); }); });
