You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/08/09 23:18:09 UTC
(texera) branch gh-readonly-queue/main/pr-7472-f00b4ca9a8fa52bd7892b3f50619e2bfffb80936 created (now dafccec799)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-7472-f00b4ca9a8fa52bd7892b3f50619e2bfffb80936
in repository https://gitbox.apache.org/repos/asf/texera.git
at dafccec799 test(frontend): extend DatasetFileSelectorComponent template coverage (#7472)
This branch includes the following new commits:
new dafccec799 test(frontend): extend DatasetFileSelectorComponent template coverage (#7472)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(texera) 01/01: test(frontend): extend DatasetFileSelectorComponent template coverage (#7472)
Posted by gi...@apache.org.
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 <me...@uci.edu>
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();
+ });
+ });
});