go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/build/legacy/build_page/change_config_dialog.test.tsx (about) 1 // Copyright 2022 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { 16 act, 17 cleanup, 18 fireEvent, 19 render, 20 screen, 21 } from '@testing-library/react'; 22 import { destroy, Instance, protect, unprotect } from 'mobx-state-tree'; 23 24 import { Store, StoreProvider } from '@/common/store'; 25 26 import { ChangeConfigDialog } from './change_config_dialog'; 27 28 describe('ChangeConfigDialog', () => { 29 let store: Instance<typeof Store>; 30 let setDefaultTabSpy: jest.SpiedFunction<(tab: string) => void>; 31 beforeEach(() => { 32 jest.useFakeTimers(); 33 store = Store.create(); 34 unprotect(store); 35 setDefaultTabSpy = jest.spyOn(store.userConfig.build, 'setDefaultTab'); 36 protect(store); 37 }); 38 39 afterEach(() => { 40 cleanup(); 41 destroy(store); 42 jest.useRealTimers(); 43 }); 44 45 it('should sync local state when opening the dialog', async () => { 46 store.userConfig.build.setDefaultTab('test-results'); 47 const { rerender } = render( 48 <StoreProvider value={store}> 49 <ChangeConfigDialog open /> 50 </StoreProvider>, 51 ); 52 53 const tabSwitch = screen.getByRole('combobox'); 54 55 expect(tabSwitch).toHaveTextContent('Test Results'); 56 57 act(() => store.userConfig.build.setDefaultTab('timeline')); 58 await act(() => jest.runOnlyPendingTimersAsync()); 59 60 // Updating the config while the dialog is still open has no effect. 61 expect(tabSwitch).toHaveTextContent('Test Results'); 62 63 rerender( 64 <StoreProvider value={store}> 65 <ChangeConfigDialog open={false} /> 66 </StoreProvider>, 67 ); 68 69 expect(tabSwitch).toHaveTextContent('Test Results'); 70 }); 71 72 it('should update global config when confirmed', async () => { 73 store.userConfig.build.setDefaultTab('test-results'); 74 const onCloseSpy = jest.fn(); 75 76 render( 77 <StoreProvider value={store}> 78 <ChangeConfigDialog open onClose={onCloseSpy} /> 79 </StoreProvider>, 80 ); 81 82 const tabSwitch = screen.getByRole('combobox'); 83 84 expect(tabSwitch).toHaveTextContent('Test Results'); 85 fireEvent.mouseDown(tabSwitch); 86 87 await act(() => jest.runOnlyPendingTimersAsync()); 88 fireEvent.click(screen.getByText('Timeline')); 89 await act(() => jest.runOnlyPendingTimersAsync()); 90 91 expect(tabSwitch).toHaveTextContent('Timeline'); 92 93 expect(onCloseSpy.mock.calls.length).toStrictEqual(0); 94 expect(setDefaultTabSpy.mock.calls.length).toStrictEqual(1); 95 96 fireEvent.click(screen.getByRole('button', { name: 'Confirm' })); 97 await act(() => jest.runOnlyPendingTimersAsync()); 98 99 expect(onCloseSpy.mock.calls.length).toStrictEqual(1); 100 expect(setDefaultTabSpy.mock.calls.length).toStrictEqual(2); 101 expect(store.userConfig.build.defaultTab).toStrictEqual('timeline'); 102 }); 103 104 it('should not update global config when dismissed', async () => { 105 store.userConfig.build.setDefaultTab('test-results'); 106 const onCloseSpy = jest.fn(); 107 108 render( 109 <StoreProvider value={store}> 110 <ChangeConfigDialog open onClose={onCloseSpy} /> 111 </StoreProvider>, 112 ); 113 114 const tabSwitch = screen.getByRole('combobox'); 115 expect(tabSwitch).toHaveTextContent('Test Results'); 116 117 fireEvent.mouseDown(tabSwitch); 118 await act(() => jest.runOnlyPendingTimersAsync()); 119 fireEvent.click(screen.getByText('Timeline')); 120 await act(() => jest.runOnlyPendingTimersAsync()); 121 122 expect(tabSwitch).toHaveTextContent('Timeline'); 123 124 expect(onCloseSpy.mock.calls.length).toStrictEqual(0); 125 expect(setDefaultTabSpy.mock.calls.length).toStrictEqual(1); 126 127 fireEvent.click(screen.getByRole('button', { name: 'Dismiss' })); 128 await act(() => jest.runOnlyPendingTimersAsync()); 129 130 expect(onCloseSpy.mock.calls.length).toStrictEqual(1); 131 expect(setDefaultTabSpy.mock.calls.length).toStrictEqual(1); 132 expect(store.userConfig.build.defaultTab).toStrictEqual('test-results'); 133 }); 134 });