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

commit dafccec7990fb3aec6b2b07b919051eccc115176
Author: Meng Wang <[email protected]>
AuthorDate: Sun Aug 9 16:09:25 2026 -0700

    test(frontend): extend DatasetFileSelectorComponent template coverage 
(#7472)
    
    ### What changes were proposed in this PR?
    
    The existing tests call `onClickOpenFileSelectionModal` directly, so the
    template
    had never been rendered — it sat at 1/10 statements. Adds 6 tests that
    render it in
    each state it switches on, taking `dataset-file-selector.component.html`
    to 10/10
    with no uncovered branches (and the class to 16/16, its last branch
    being the
    component's own instantiation).
    
    - **enabled, with a path** — the path is shown and the Select File
    button is offered.
    - **enabled, no path yet** — the input is withheld until there is
    something to show;
      only the button renders.
    - **disabled** — no picker to write the path, so the empty input is
    shown instead and
      the button is gone.
    - **the button** — clicking it opens the selection modal; triggering it
    while the flag
    is off does not, which is what the handler's own `isFileSelectionEnabled
    &&` guard is
    for (the `*ngIf` normally removes the button, so the test disables the
    flag without
      re-rendering to reach that guard).
    
    The GUI-config double moved from an inline provider literal to a
    variable so a test
    can flip `selectingFilesFromDatasetsEnabled`; its default is unchanged.
    No production
    code was changed.
    
    **One test pins a defect rather than the intent.**
    `[readOnly]="isFileSelectionEnabled"`
    does not make the input read-only: the camelCase name misses
    `NzInputDirective`'s
    `readonly` input, so it lands on the DOM property, and the directive's
    `[attr.readonly]="readonly() || null"` host binding then clears the
    attribute and
    resets the property. Verified both ways locally — with `[readOnly]` the
    rendered input
    reports `readOnly: false, attr: null`; renaming it to `[readonly]` gives
    `readOnly: true, attr: true`. So the path the picker is meant to own can
    currently be
    typed over. The test asserts the real behaviour with a comment saying
    what to flip when
    the one-word fix lands; the fix itself is a production change and out of
    scope for a
    coverage PR.
    
    ### Any related issues, documentation, discussions?
    
    Closes #7466.
    
    ### How was this PR tested?
    
    `ng test --watch=false --include
    
src/app/workspace/component/dataset-file-selector/dataset-file-selector.component.spec.ts`
    — 11 passed (5 existing + 6 new), run 3x for determinism. Coverage
    (`--coverage`)
    confirms `dataset-file-selector.component.html` at 10/10 statements with
    no uncovered
    branches. The failure path was verified by breaking an assertion (red,
    non-zero exit);
    eslint and prettier are clean.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Opus 4.8 [1M context])
---
 .../dataset-file-selector.component.spec.ts        | 83 +++++++++++++++++++++-
 1 file changed, 82 insertions(+), 1 deletion(-)

diff --git 
a/frontend/src/app/workspace/component/dataset-file-selector/dataset-file-selector.component.spec.ts
 
b/frontend/src/app/workspace/component/dataset-file-selector/dataset-file-selector.component.spec.ts
index cb2874a643..24a2214bfe 100644
--- 
a/frontend/src/app/workspace/component/dataset-file-selector/dataset-file-selector.component.spec.ts
+++ 
b/frontend/src/app/workspace/component/dataset-file-selector/dataset-file-selector.component.spec.ts
@@ -19,6 +19,7 @@
 
 import { ComponentFixture, TestBed } from "@angular/core/testing";
 import { FormControl } from "@angular/forms";
+import { By } from "@angular/platform-browser";
 import { FieldTypeConfig } from "@ngx-formly/core";
 import { of } from "rxjs";
 import { NzModalService } from "ng-zorro-antd/modal";
@@ -33,6 +34,9 @@ describe("DatasetFileSelectorComponent", () => {
   // reads `afterClose` off the returned modal ref. Each test overrides what
   // `afterClose` emits via `mockReturnValue`.
   let modalServiceSpy: { create: ReturnType<typeof vi.fn> };
+  // Held in a variable rather than inlined into the provider so a test can 
flip the
+  // flag; `isFileSelectionEnabled` reads straight through to it.
+  let guiConfigStub: { env: { selectingFilesFromDatasetsEnabled: boolean } };
 
   // Attach a fresh FormControl with a known starting value, since the 
component
   // extends FieldType and reads/writes through `this.formControl`.
@@ -44,13 +48,14 @@ describe("DatasetFileSelectorComponent", () => {
 
   beforeEach(async () => {
     modalServiceSpy = { create: vi.fn() };
+    guiConfigStub = { env: { selectingFilesFromDatasetsEnabled: true } };
 
     await TestBed.configureTestingModule({
       imports: [DatasetFileSelectorComponent],
       providers: [
         { provide: NzModalService, useValue: modalServiceSpy },
         { provide: WorkflowActionService, useValue: {} },
-        { provide: GuiConfigService, useValue: { env: { 
selectingFilesFromDatasetsEnabled: true } } },
+        { provide: GuiConfigService, useValue: guiConfigStub },
       ],
     }).compileComponents();
 
@@ -92,4 +97,80 @@ describe("DatasetFileSelectorComponent", () => {
   it("exposes isFileSelectionEnabled from the GUI config", () => {
     expect(component.isFileSelectionEnabled).toBe(true);
   });
+
+  /**
+   * The tests above call `onClickOpenFileSelectionModal` directly, so the 
template had never
+   * been rendered. What it decides: whether the path is shown at all, whether 
it can be typed
+   * into, and whether the picker is offered — all of which turn on the 
deployment-level
+   * `selectingFilesFromDatasetsEnabled` flag.
+   */
+  describe("template rendering", () => {
+    /** Renders the field with the given path, under the given deployment 
flag. */
+    function render(value: string, fileSelectionEnabled = true): void {
+      guiConfigStub.env.selectingFilesFromDatasetsEnabled = 
fileSelectionEnabled;
+      setFormControl(value);
+      fixture.detectChanges();
+    }
+
+    const input = () => fixture.debugElement.query(By.css("input"));
+    const selectFileButton = () => 
fixture.debugElement.query(By.css("button"));
+
+    it("shows the chosen path alongside the Select File button", () => {
+      render("/dataset/data.csv");
+
+      expect(input().nativeElement.value).toBe("/dataset/data.csv");
+      expect(selectFileButton().nativeElement.textContent.trim()).toBe("Select 
File");
+    });
+
+    it("leaves the path input editable even with file selection enabled", () 
=> {
+      render("/dataset/data.csv");
+
+      // Characterizing a defect rather than asserting the intent: the 
template's
+      // `[readOnly]` is camelCase, so it misses NzInputDirective's `readonly` 
input and
+      // lands on the DOM property; the directive then host-binds
+      // `[attr.readonly]="readonly() || null"`, which clears the attribute 
and resets the
+      // property. So the path the picker is meant to own can still be typed 
over.
+      // Spelling the binding `[readonly]` makes it take effect — a production 
change, out
+      // of scope here. Flip this expectation to `true` when that lands.
+      expect(input().nativeElement.readOnly).toBe(false);
+    });
+
+    it("shows only the Select File button until a path has been chosen", () => 
{
+      render("");
+
+      expect(input()).toBeNull();
+      expect(selectFileButton()).not.toBeNull();
+    });
+
+    it("falls back to a typeable path input when file selection is disabled", 
() => {
+      // No picker to write the path, so the empty input has to be shown and 
be editable.
+      render("", false);
+
+      expect(input()).not.toBeNull();
+      expect(input().nativeElement.readOnly).toBe(false);
+      expect(selectFileButton()).toBeNull();
+    });
+
+    it("opens the selection modal when the Select File button is clicked", () 
=> {
+      modalServiceSpy.create.mockReturnValue({ afterClose: 
of("/dataset/data.csv") });
+      render("");
+
+      selectFileButton().triggerEventHandler("click", null);
+
+      expect(modalServiceSpy.create).toHaveBeenCalledTimes(1);
+    });
+
+    it("does not open the modal if the button is triggered while file 
selection is disabled", () => {
+      render("");
+      const button = selectFileButton();
+
+      // The *ngIf normally removes the button, so reach the handler's own 
guard by disabling
+      // the flag without re-rendering. It is what stops a stale button from 
opening a picker
+      // the deployment has turned off.
+      guiConfigStub.env.selectingFilesFromDatasetsEnabled = false;
+      button.triggerEventHandler("click", null);
+
+      expect(modalServiceSpy.create).not.toHaveBeenCalled();
+    });
+  });
 });

Reply via email to