From 1ed723813e49fc659e26b1bb57b0c21b5e7a38e8 Mon Sep 17 00:00:00 2001 From: Bo Majewski Date: Mon, 19 Dec 2022 23:28:41 +0000 Subject: [PATCH] [Files]: Updates the query state in the store. Updates the query on user input or clear calls. Adds a unit tests for search container. Bug: b:241868715 Change-Id: Id8621bd3e6cb5f595af56aef38074bd1cefabcbd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4113041 Reviewed-by: Luciano Pacheco Commit-Queue: Bo Majewski Cr-Commit-Position: refs/heads/main@{#1085190} --- .../ash/file_manager/file_manager_jstest.cc | 12 ++- .../containers/search_container.ts | 14 ++- .../containers/search_container_unittest.ts | 88 +++++++++++++++++++ .../file_manager/state/reducers/search.ts | 6 +- ui/file_manager/file_names.gni | 1 + 5 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 ui/file_manager/file_manager/containers/search_container_unittest.ts diff --git a/chrome/browser/ash/file_manager/file_manager_jstest.cc b/chrome/browser/ash/file_manager/file_manager_jstest.cc index b61b04c3566af..4b66303d1d536 100644 --- a/chrome/browser/ash/file_manager/file_manager_jstest.cc +++ b/chrome/browser/ash/file_manager/file_manager_jstest.cc @@ -326,6 +326,14 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ReducerSearch) { RunTestURL("state/reducers/search_unittest.js"); } +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, NudgeContainer) { + RunTestURL("containers/nudge_container_unittest.js"); +} + +IN_PROC_BROWSER_TEST_F(FileManagerJsTest, SearchContainer) { + RunTestURL("containers/search_container_unittest.js"); +} + IN_PROC_BROWSER_TEST_F(FileManagerJsTest, XfConflictDialog) { RunTestURL("widgets/xf_conflict_dialog_unittest.js"); } @@ -346,10 +354,6 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, XfSplitter) { RunTestURL("widgets/xf_splitter_unittest.js"); } -IN_PROC_BROWSER_TEST_F(FileManagerJsTest, NudgeContainer) { - RunTestURL("containers/nudge_container_unittest.js"); -} - IN_PROC_BROWSER_TEST_F(FileManagerJsTest, XfTree) { RunTestURL("widgets/xf_tree_unittest.js"); } diff --git a/ui/file_manager/file_manager/containers/search_container.ts b/ui/file_manager/file_manager/containers/search_container.ts index 1f9a460e62d8d..274330c52633d 100644 --- a/ui/file_manager/file_manager/containers/search_container.ts +++ b/ui/file_manager/file_manager/containers/search_container.ts @@ -152,7 +152,7 @@ export class SearchContainer extends EventTarget { const value = this.inputElement_.value; if (value !== '') { this.inputElement_.value = ''; - this.postQueryChangedEvent(); + this.onQueryChanged_(); requestAnimationFrame(() => { this.closeSearch(); }); @@ -488,7 +488,7 @@ export class SearchContainer extends EventTarget { } }); this.inputElement_.addEventListener('input', () => { - this.postQueryChangedEvent(); + this.onQueryChanged_(); }); this.inputElement_.addEventListener('keydown', (event: KeyboardEvent) => { if (!this.inputElement_.value) { @@ -582,14 +582,20 @@ export class SearchContainer extends EventTarget { * Generates a custom event with the current value of the input element as the * search query. */ - private postQueryChangedEvent() { + private onQueryChanged_() { + const query = this.inputElement_.value.trimStart(); this.dispatchEvent(new CustomEvent(SEARCH_QUERY_CHANGED, { bubbles: true, composed: true, detail: { - query: this.inputElement_.value, + query: query, }, })); + this.store_.dispatch(updateSearch({ + query: query, + status: undefined, // do not change + options: undefined, // do not change + })); } private postItemChangedEvent() { diff --git a/ui/file_manager/file_manager/containers/search_container_unittest.ts b/ui/file_manager/file_manager/containers/search_container_unittest.ts new file mode 100644 index 0000000000000..305279e336e36 --- /dev/null +++ b/ui/file_manager/file_manager/containers/search_container_unittest.ts @@ -0,0 +1,88 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.js'; + +import {EntryLocation} from '../externs/entry_location.js'; +import {State} from '../externs/ts/state.js'; +import {VolumeManager} from '../externs/volume_manager.js'; +import {waitDeepEquals} from '../state/for_tests.js'; +import {getEmptyState, getStore, Store} from '../state/store.js'; + +import {SearchContainer} from './search_container.js'; + + +const searchWrapper: HTMLElement = document.createElement('div'); +const optionsContainer: HTMLElement = document.createElement('div'); +const pathContainer: HTMLElement = document.createElement('div'); + +let store: Store|undefined; +let searchContainer: SearchContainer|undefined; + +function setupStore(): Store { + const store = getStore(); + store.init(getEmptyState()); + return store; +} + +/** + * Creates new element for each test. + */ +export function setUp() { + const root = document.createElement('div'); + document.body.replaceChildren(root); + searchWrapper.innerHTML = ` + +
+
+ `; + root.appendChild(searchWrapper); + root.appendChild(optionsContainer); + root.appendChild(pathContainer); + + store = setupStore(); + const volumeManager: VolumeManager = { + getLocationInfo: (_entry: Entry): EntryLocation => { + return new EntryLocation(); + }, + } as unknown as VolumeManager; + + searchContainer = new SearchContainer( + volumeManager, searchWrapper, optionsContainer, pathContainer); +} + +export async function testQueryUpdated() { + // Test 1: Enter a query. + const input = searchWrapper.querySelector('cr-input') as CrInputElement; + input.value = 'hello'; + input.dispatchEvent(new Event('input', { + bubbles: true, + cancelable: true, + })); + const want1 = { + query: 'hello', + status: undefined, + options: undefined, + }; + await waitDeepEquals(store!, want1, (state: State) => { + return state.search; + }); + + // Test 2: Clear the query. + searchContainer!.clear(); + const want2 = { + query: '', + status: undefined, + options: undefined, + }; + await waitDeepEquals(store!, want2, (state: State) => { + return state.search; + }); +} diff --git a/ui/file_manager/file_manager/state/reducers/search.ts b/ui/file_manager/file_manager/state/reducers/search.ts index 3df770cb13015..2cdd8a28fcd3b 100644 --- a/ui/file_manager/file_manager/state/reducers/search.ts +++ b/ui/file_manager/file_manager/state/reducers/search.ts @@ -25,13 +25,13 @@ export function search(state: State, action: SearchAction): State { // as store customers are free to cache it and check for changes. If we modify // the original object the check for changes incorrectly return false. const search: SearchData = {...currentSearch}; - if (payload.query) { + if (payload.query !== undefined) { search.query = payload.query; } - if (payload.status) { + if (payload.status !== undefined) { search.status = payload.status; } - if (payload.options) { + if (payload.options !== undefined) { search.options = payload.options; } return {...state, search}; diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni index 70ccae61ae294..c88007724510f 100644 --- a/ui/file_manager/file_names.gni +++ b/ui/file_manager/file_names.gni @@ -312,6 +312,7 @@ ts_test_files = [ # Containers "file_manager/containers/breadcrumb_container_unittest.ts", "file_manager/containers/nudge_container_unittest.ts", + "file_manager/containers/search_container_unittest.ts", # Lib: "file_manager/lib/base_store_unittest.ts",