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-7547-f2f457e671b341bc499f1ea4169f09a56a6e8369 in repository https://gitbox.apache.org/repos/asf/texera.git
commit 5021bc6f1a96d00cb26aa9c3a82c86fee67da0a9 Author: Xinyuan Lin <[email protected]> AuthorDate: Tue Aug 11 22:34:38 2026 -0700 test(frontend): click the toolbar buttons rather than calling their handlers (#7547) ### What changes were proposed in this PR? The suite calls the handlers directly, which is not the same thing: coverage for `(click)="onClickX()"` lands on the generated listener body, so a button wired to the wrong handler — or to none — looks perfectly tested today. Adds 2 tests that click the real elements. The first is table-driven over six visually near-identical icon buttons, since a copy-paste leaving two of them on the same handler is the realistic defect. The second asserts the converse: clicking auto-layout must not also reset the panels. **Verified by mutation**, all reverted (template diff empty): | Mutation | Result | |---|---| | auto layout wired to reset panels | red | | close panels wired to reset panels | red | | generate report unwired | red | | reset zoom wired to auto layout | red | | add comment unwired | red | | reset panels wired to close panels | red | ### Deliberately not included The four display switches live in the `#executionSettings` popover, which ng-zorro instantiates into a CDK overlay only on open. Opening the first `NzPopoverDirective` on the page yields one switch, not four — locating the right one needs more overlay plumbing than four lines justify. They remain uncovered, and the issue records how to reach them. No production file is touched. ### Any related issues, documentation, discussions? Closes #7546 ### How was this PR tested? ``` npx ng test --watch=false --include="**/menu.component.spec.ts" ``` ``` Test Files 1 passed (1) Tests 83 passed (83) ``` 2 new on top of the existing 81. `yarn format:ci` passes. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 5) --- .../component/menu/menu.component.spec.ts | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/frontend/src/app/workspace/component/menu/menu.component.spec.ts b/frontend/src/app/workspace/component/menu/menu.component.spec.ts index 9a35071cc2..106695d8af 100644 --- a/frontend/src/app/workspace/component/menu/menu.component.spec.ts +++ b/frontend/src/app/workspace/component/menu/menu.component.spec.ts @@ -912,4 +912,60 @@ describe("MenuComponent", () => { expect(openSpy).toHaveBeenCalled(); }); }); + /** + * The toolbar's buttons and switches are wired in the template, and the suite above calls the + * handlers directly. That is not the same thing: coverage for `(click)="onClickX()"` lands on the + * generated listener body, which only runs when the element is really clicked — so a button wired + * to the wrong handler, or to none, looks perfectly tested today. + */ + describe("toolbar wiring", () => { + function host(): HTMLElement { + return fixture.nativeElement as HTMLElement; + } + + /** The button carrying the given title attribute. */ + function button(title: string): HTMLButtonElement { + const found = host().querySelector<HTMLButtonElement>(`button[title="${title}"]`); + expect(found, `no button titled "${title}"`).not.toBeNull(); + return found!; + } + + /** Clicks the button and reports whether the spied handler ran exactly once. */ + function clicking(title: string, owner: object, method: string): boolean { + const spy = vi.spyOn(owner as any, method).mockImplementation(() => {}); + button(title).click(); + const ran = spy.mock.calls.length === 1; + spy.mockRestore(); + return ran; + } + + it("routes each toolbar button to its own handler", () => { + // Table-driven because these buttons are visually near-identical icon buttons; a copy-paste + // that leaves two of them on the same handler is the realistic defect and is invisible on + // screen. Each entry is clicked for real, not invoked. + const wiring: Array<[string, object, string]> = [ + ["close panels", component, "onClickClosePanels"], + ["reset panels", component, "onClickResetPanels"], + ["generate report", component, "onClickGenerateReport"], + ["reset zoom", component, "onClickRestoreZoomOffsetDefault"], + ["auto layout", component, "onClickAutoLayout"], + ["add a comment", component, "onClickAddCommentBox"], + ]; + + const results = wiring.map(([title, owner, method]) => `${title}:${clicking(title, owner, method)}`); + + expect(results).toEqual(wiring.map(([title]) => `${title}:true`)); + }); + + it("does not fire a neighbour's handler when one button is clicked", () => { + // The other half of the same concern: clicking auto-layout must not also reset the panels. + const layout = vi.spyOn(component, "onClickAutoLayout").mockImplementation(() => {}); + const reset = vi.spyOn(component, "onClickResetPanels").mockImplementation(() => {}); + + button("auto layout").click(); + + expect(layout).toHaveBeenCalledTimes(1); + expect(reset).not.toHaveBeenCalled(); + }); + }); });
