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-6763-3ad76c60016c9803be6fbbd2de4ce8bb749876c5 in repository https://gitbox.apache.org/repos/asf/texera.git
commit ca49239fc96b86b4ba1cf85029ecf57d27698aae Author: Meng Wang <[email protected]> AuthorDate: Wed Jul 22 18:24:56 2026 -0700 test(frontend): cover FiltersComponent master-filter-list building and dropdown reset (#6763) ### What changes were proposed in this PR? Extends the existing `FiltersComponent` spec to cover the filter-list helpers it had left untested (`frontend/src/app/dashboard/component/user/filters/filters.component.ts`). > Note: most of the methods the issue lists are already covered — search-parameter > assembly (`getSearchKeywords` / `getSearchFilterParameters`), operator/owner/id > backend setup (`searchParameterBackendSetup`, asserted via the logged-out init > test), the `updateSelected*` handlers, `updateDropdownMenus`, and > `buildMasterFilterList` date handling. This PR fills the remaining gaps. 6 tests cover: - `checkIfWorkflowName` — a plain tag is a name, a known-prefix tag (`owner: …`) is a filter, an unrecognized prefix is still a name; - `updateMasterFilterList` — appends new tags, replaces the `ctime` tag in place, and drops tags absent from the new list; - `setMasterFilterList` — emits on `masterFilterListChange` only when the list actually changes; - `removeInvalidFilterTag` — drops the given tag; - `setDropdownSelectionsToUnchecked` — clears every dropdown checkbox. Per the issue's timezone note, `getFormattedDateString` is left to the existing TZ-safe date tests (which read the local calendar fields, matching the component's local `new Date(y, m, d)`); no new timezone-dependent assertion is introduced. No production code was changed. ### Any related issues, documentation, discussions? Closes #6751 ### How was this PR tested? Extended unit tests, run locally in `frontend/` (all green; the failure path was verified by breaking an assertion to confirm the suite goes red): ``` ng test --watch=false --include src/app/dashboard/component/user/filters/filters.component.spec.ts # Test Files 1 passed (1) | Tests 38 passed (38) prettier --write <spec> # clean eslint <spec> # clean ``` ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 4.8 [1M context]) --- .../user/filters/filters.component.spec.ts | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/frontend/src/app/dashboard/component/user/filters/filters.component.spec.ts b/frontend/src/app/dashboard/component/user/filters/filters.component.spec.ts index 5a0a7e0b03..9fab7d2a07 100644 --- a/frontend/src/app/dashboard/component/user/filters/filters.component.spec.ts +++ b/frontend/src/app/dashboard/component/user/filters/filters.component.spec.ts @@ -416,4 +416,80 @@ describe("FiltersComponent", () => { expect(component.getSearchKeywords()).toEqual(["hello", "world"]); }); }); + + describe("master-filter-list building and dropdown reset", () => { + // These are private helpers reached through the public setter / build path; + // cast to exercise them directly without going through the DOM. + const asPrivate = () => + component as unknown as { + checkIfWorkflowName: (tag: string) => boolean; + updateMasterFilterList: (master: ReadonlyArray<string>, items: string[]) => string[]; + setMasterFilterList: (value: ReadonlyArray<string>, updateDropdown: boolean) => void; + removeInvalidFilterTag: (tag: string) => void; + setDropdownSelectionsToUnchecked: () => void; + }; + + it("checkIfWorkflowName distinguishes plain names from known-prefix filter tags", () => { + const filters = asPrivate(); + // no colon -> a workflow name + expect(filters.checkIfWorkflowName("my workflow")).toBe(true); + // a known search-criteria prefix -> a filter tag, not a name + expect(filters.checkIfWorkflowName("owner: alice")).toBe(false); + // an unrecognized prefix -> still treated as a name + expect(filters.checkIfWorkflowName("weird: value")).toBe(true); + }); + + it("updateMasterFilterList appends new tags and replaces the ctime tag in place", () => { + const result = asPrivate().updateMasterFilterList( + ["keyword", "ctime: 2022-01-01 ~ 2022-02-01"], + ["keyword", "ctime: 2023-03-03 ~ 2023-04-04", "owner: alice"] + ); + expect(result).toEqual(["keyword", "ctime: 2023-03-03 ~ 2023-04-04", "owner: alice"]); + }); + + it("updateMasterFilterList drops tags absent from the new list", () => { + expect(asPrivate().updateMasterFilterList(["a", "b", "c"], ["a", "c"])).toEqual(["a", "c"]); + }); + + it("setMasterFilterList emits on masterFilterListChange only when the list changes", () => { + const filters = asPrivate(); + const emitted: ReadonlyArray<string>[] = []; + component.masterFilterListChange.subscribe(value => emitted.push(value)); + + filters.setMasterFilterList(["owner: alice"], false); + expect(component.masterFilterList).toEqual(["owner: alice"]); + expect(emitted).toHaveLength(1); + + // identical content -> guarded, no re-emit + filters.setMasterFilterList(["owner: alice"], false); + expect(emitted).toHaveLength(1); + }); + + it("removeInvalidFilterTag drops the given tag from the master list", () => { + const filters = asPrivate(); + filters.setMasterFilterList(["owner: alice", "keyword", "id: 5"], false); + filters.removeInvalidFilterTag("id: 5"); + expect(component.masterFilterList).toEqual(["owner: alice", "keyword"]); + }); + + it("setDropdownSelectionsToUnchecked clears every dropdown checkbox", () => { + component.owners = [{ userName: "alice", checked: true }]; + component.wids = [{ id: "1", checked: true }]; + component.operators = new Map([ + ["group", [{ userFriendlyName: "Scan", operatorType: "ScanSource", operatorGroup: "group", checked: true }]], + ]); + component.userProjectsDropdown = [{ pid: 1, name: "p", checked: true }]; + + asPrivate().setDropdownSelectionsToUnchecked(); + + expect(component.owners.every(owner => !owner.checked)).toBe(true); + expect(component.wids.every(wid => !wid.checked)).toBe(true); + expect( + Array.from(component.operators.values()) + .flat() + .every(operator => !operator.checked) + ).toBe(true); + expect(component.userProjectsDropdown.every(project => !project.checked)).toBe(true); + }); + }); });
