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-6782-1988b1755e0d6d9490fa17b12888e6d6be042759
in repository https://gitbox.apache.org/repos/asf/texera.git

commit e4c294a10a7e67f09350522f14eb7ccc7a9be5cd
Author: Xinyuan Lin <[email protected]>
AuthorDate: Wed Jul 22 17:07:37 2026 -0700

    test(frontend): extend NzModalCommentBoxComponent unit test coverage (#6782)
    
    ### What changes were proposed in this PR?
    
    Extends `nz-modal-comment-box.component.spec.ts` with 7 tests (8 -> 15),
    covering `toggleEditInput` open/close/missing-DOM-target branches, the
    `editComment` no-user guard and DOM-hide tail, and the `window:keydown`
    Ctrl+Enter host-binding. Coverage ~67% -> 100% lines. No existing tests
    modified.
    
    ### Any related issues, documentation, discussions?
    
    Closes #6776.
    
    ### How was this PR tested?
    
    `ng test --include='**/nz-modal-comment-box.component.spec.ts'` -> 15/15
    passing. `yarn format:ci` passes.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8 [1M context])
---
 .../nz-modal-comment-box.component.spec.ts         | 127 ++++++++++++++++++++-
 1 file changed, 126 insertions(+), 1 deletion(-)

diff --git 
a/frontend/src/app/workspace/component/workflow-editor/comment-box-modal/nz-modal-comment-box.component.spec.ts
 
b/frontend/src/app/workspace/component/workflow-editor/comment-box-modal/nz-modal-comment-box.component.spec.ts
index 7506be96a4..61d41276a2 100644
--- 
a/frontend/src/app/workspace/component/workflow-editor/comment-box-modal/nz-modal-comment-box.component.spec.ts
+++ 
b/frontend/src/app/workspace/component/workflow-editor/comment-box-modal/nz-modal-comment-box.component.spec.ts
@@ -39,6 +39,32 @@ describe("NzModalCommentBoxComponent", () => {
   let addComment: ReturnType<typeof vi.fn>;
   let deleteComment: ReturnType<typeof vi.fn>;
   let editComment: ReturnType<typeof vi.fn>;
+  let lastFixture: ComponentFixture<NzModalCommentBoxComponent> | undefined;
+  let createdEls: HTMLElement[] = [];
+
+  // toggleEditInput / editComment locate their DOM targets by id
+  // ("txarea"|"comment"|"editbtn" + creatorName + creationTime). Build real
+  // elements so those document.getElementById lookups resolve.
+  function makeEl(id: string, opts: { hidden?: boolean; text?: string } = {}): 
HTMLElement {
+    const el = document.createElement("div");
+    el.id = id;
+    if (opts.hidden) {
+      el.setAttribute("hidden", "hidden");
+    }
+    if (opts.text !== undefined) {
+      el.textContent = opts.text;
+    }
+    document.body.appendChild(el);
+    createdEls.push(el);
+    return el;
+  }
+
+  afterEach(() => {
+    lastFixture?.destroy();
+    lastFixture = undefined;
+    createdEls.forEach(el => el.remove());
+    createdEls = [];
+  });
 
   async function createFixture(
     opts: { user?: User; comments?: unknown[] } = {}
@@ -65,7 +91,8 @@ describe("NzModalCommentBoxComponent", () => {
       ],
     }).compileComponents();
 
-    return TestBed.createComponent(NzModalCommentBoxComponent);
+    lastFixture = TestBed.createComponent(NzModalCommentBoxComponent);
+    return lastFixture;
   }
 
   it("should create and render a comment from the box", async () => {
@@ -158,4 +185,102 @@ describe("NzModalCommentBoxComponent", () => {
     component.onKeyDown(new KeyboardEvent("keydown", { key: "a", ctrlKey: true 
}));
     expect(submitSpy).toHaveBeenCalledTimes(1);
   });
+
+  describe("edit flows", () => {
+    it("toggleEditInput is a no-op when its DOM targets are missing", async () 
=> {
+      const fixture = await createFixture({ user: makeUser() });
+      const component = fixture.componentInstance;
+      component.editValue = "preset";
+
+      // No txarea/comment/editbtn elements exist for this name+time.
+      component.toggleEditInput("Ghost", CREATION_TIME);
+
+      expect(component.editValue).toBe("preset"); // early return leaves state 
untouched
+    });
+
+    it("toggleEditInput opens the editor, hides the comment, and loads its 
text", async () => {
+      const fixture = await createFixture({ user: makeUser() });
+      const component = fixture.componentInstance;
+      const name = "Bob";
+      const txarea = makeEl("txarea" + name + CREATION_TIME, { hidden: true });
+      const comment = makeEl("comment" + name + CREATION_TIME, { text: 
"original text" });
+      const btn = makeEl("editbtn" + name + CREATION_TIME, { hidden: true });
+
+      component.toggleEditInput(name, CREATION_TIME);
+
+      expect(txarea.hasAttribute("hidden")).toBe(false);
+      expect(btn.hasAttribute("hidden")).toBe(false);
+      expect(comment.hasAttribute("hidden")).toBe(true);
+      expect(component.editValue).toBe("original text");
+    });
+
+    it("toggleEditInput closes the editor and clears editValue on the second 
toggle", async () => {
+      const fixture = await createFixture({ user: makeUser() });
+      const component = fixture.componentInstance;
+      const name = "Bob";
+      const txarea = makeEl("txarea" + name + CREATION_TIME, { hidden: true });
+      const comment = makeEl("comment" + name + CREATION_TIME, { text: 
"original text" });
+      const btn = makeEl("editbtn" + name + CREATION_TIME, { hidden: true });
+
+      component.toggleEditInput(name, CREATION_TIME); // open
+      component.toggleEditInput(name, CREATION_TIME); // close
+
+      expect(txarea.hasAttribute("hidden")).toBe(true);
+      expect(btn.hasAttribute("hidden")).toBe(true);
+      expect(comment.hasAttribute("hidden")).toBe(false);
+      expect(component.editValue).toBe("");
+    });
+
+    it("editComment is a no-op without a current user and preserves 
editValue", async () => {
+      const fixture = await createFixture({ user: undefined });
+      const component = fixture.componentInstance;
+      component.editValue = "attempted edit";
+
+      component.editComment(1, "Alice", CREATION_TIME);
+
+      expect(editComment).not.toHaveBeenCalled();
+      expect(component.editValue).toBe("attempted edit"); // reset happens 
only past the guard
+    });
+
+    it("editComment saves the new content and then hides the edit textarea and 
button", async () => {
+      const fixture = await createFixture({ user: makeUser() });
+      const component = fixture.componentInstance;
+      const name = "Carol";
+      const txarea = makeEl("txarea" + name + CREATION_TIME); // visible
+      const btn = makeEl("editbtn" + name + CREATION_TIME); // visible
+      component.editValue = "edited body";
+
+      component.editComment(2, name, CREATION_TIME);
+
+      expect(editComment).toHaveBeenCalledWith(2, CREATION_TIME, BOX_ID, 
"edited body");
+      expect(component.editValue).toBe("");
+      expect(txarea.hasAttribute("hidden")).toBe(true);
+      expect(btn.hasAttribute("hidden")).toBe(true);
+    });
+
+    it("editComment still saves when the edit DOM targets are absent (guarded 
tail)", async () => {
+      const fixture = await createFixture({ user: makeUser() });
+      const component = fixture.componentInstance;
+      component.editValue = "no-dom edit";
+
+      // No txarea/editbtn elements: the service call happens, the DOM tail 
short-circuits.
+      component.editComment(3, "Nobody", CREATION_TIME);
+
+      expect(editComment).toHaveBeenCalledWith(3, CREATION_TIME, BOX_ID, 
"no-dom edit");
+      expect(component.editValue).toBe("");
+    });
+  });
+
+  it("the window:keydown host binding submits the comment on Ctrl+Enter", 
async () => {
+    const fixture = await createFixture({ user: makeUser() });
+    fixture.detectChanges(); // register the @HostListener("window:keydown") 
binding
+    fixture.componentInstance.inputValue = "via host listener";
+
+    const event = new KeyboardEvent("keydown", { key: "Enter", ctrlKey: true, 
cancelable: true });
+    window.dispatchEvent(event);
+
+    expect(addComment).toHaveBeenCalledTimes(1);
+    expect(addComment.mock.calls[0][0]).toMatchObject({ content: "via host 
listener" });
+    expect(event.defaultPrevented).toBe(true);
+  });
 });

Reply via email to