diff --git a/packages/api-explorer/package.json b/packages/api-explorer/package.json index 5b91b8c1c..d0449f768 100644 --- a/packages/api-explorer/package.json +++ b/packages/api-explorer/package.json @@ -87,7 +87,9 @@ "react": "^16.13.1", "react-diff-viewer": "^3.1.1", "react-dom": "^16.13.1", + "react-helmet-async": "^1.3.0", "react-is": "^16.13.1", + "react-query": "^3.39.2", "react-redux": "^7.2.3", "react-router": "^5.1.2", "react-router-dom": "^5.1.2", diff --git a/packages/api-explorer/src/scenes/DiffScene/DiffScene.spec.tsx b/packages/api-explorer/src/scenes/DiffScene/DiffScene.spec.tsx new file mode 100644 index 000000000..90529e806 --- /dev/null +++ b/packages/api-explorer/src/scenes/DiffScene/DiffScene.spec.tsx @@ -0,0 +1,45 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ + +import type { SpecList } from '@looker/sdk-codegen' +import { getLoadedSpecs } from '../../test-data' +import { createTestStore, preloadedState } from '../../test-utils' + +describe('DiffScene', () => { + Element.prototype.scrollTo = jest.fn() + Element.prototype.scrollIntoView = jest.fn() + + // NOTE: if call getLoadedSpecs, preloadedState = undefined + // if comment out getLoadedSpecs, preloadedState = expected + const specs = getLoadedSpecs() as SpecList + test('calling getLoadedSpecs should not affect preloadedState', () => { + expect(preloadedState).toEqual({}) + const store = createTestStore({ + specs: { specs, currentSpecKey: '4.0' }, + settings: { initialized: true }, + }) + }) +}) diff --git a/packages/api-explorer/src/state/settings/slice.spec.ts b/packages/api-explorer/src/state/settings/slice.spec.ts new file mode 100644 index 000000000..096d43553 --- /dev/null +++ b/packages/api-explorer/src/state/settings/slice.spec.ts @@ -0,0 +1,46 @@ +/* + + MIT License + + Copyright (c) 2021 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import type { SearchCriterionTerm } from '@looker/sdk-codegen' +import { SearchAll, setToCriteria } from '@looker/sdk-codegen' +import { preloadedState } from '../../test-utils' +import { defaultSettingsState } from './slice' + +describe('Settings Slice', () => { + test('defaultSettingsState contains the default initial settings state', () => { + expect(defaultSettingsState).toEqual({ + diffOptions: ['missing', 'params', 'type', 'body', 'response'], + sdkLanguage: 'Python', + searchPattern: '', + searchCriteria: setToCriteria(SearchAll) as SearchCriterionTerm[], + tagFilter: 'ALL', + initialized: false, + }) + }) + + test('preloadedState settings initialized with default settings', () => { + expect(preloadedState.settings).toEqual(defaultSettingsState) + }) +}) diff --git a/packages/api-explorer/src/state/settings/slice.ts b/packages/api-explorer/src/state/settings/slice.ts index a5799e4c0..c0f93b1cb 100644 --- a/packages/api-explorer/src/state/settings/slice.ts +++ b/packages/api-explorer/src/state/settings/slice.ts @@ -36,6 +36,7 @@ export interface UserDefinedSettings { } export interface SettingState extends UserDefinedSettings { + diffOptions: string[] searchPattern: string searchCriteria: SearchCriterionTerm[] tagFilter: string @@ -44,6 +45,7 @@ export interface SettingState extends UserDefinedSettings { } export const defaultSettings = { + diffOptions: ['missing', 'params', 'type', 'body', 'response'], sdkLanguage: 'Python', searchPattern: '', searchCriteria: setToCriteria(SearchAll) as SearchCriterionTerm[], @@ -55,6 +57,7 @@ export const defaultSettingsState: SettingState = { initialized: false, } +type SetDiffOptionsAction = Pick type SetSearchPatternAction = Pick type SetSdkLanguageAction = Pick type SetTagFilterAction = Pick @@ -78,6 +81,9 @@ export const settingsSlice = createSlice({ state.error = action.payload state.initialized = false }, + setDiffOptionsAction(state, action: PayloadAction) { + state.diffOptions = action.payload.diffOptions + }, setSdkLanguageAction(state, action: PayloadAction) { state.sdkLanguage = action.payload.sdkLanguage }, diff --git a/packages/api-explorer/src/test-utils/redux.tsx b/packages/api-explorer/src/test-utils/redux.tsx index f0f6023a8..fbea3c8be 100644 --- a/packages/api-explorer/src/test-utils/redux.tsx +++ b/packages/api-explorer/src/test-utils/redux.tsx @@ -78,13 +78,15 @@ type DeepPartial = { [P in keyof T]?: DeepPartial } -export const createTestStore = (overrides?: DeepPartial) => - createStore({ +export const createTestStore = (overrides?: DeepPartial) => { + // TODO: revert back to implicit return after fixing default initialization issue + const settings = { + ...preloadedState.settings, + ...overrides?.settings, + } as SettingState + return createStore({ preloadedState: { - settings: { - ...preloadedState.settings, - ...overrides?.settings, - } as SettingState, + settings, lodes: { ...defaultLodesState, ...overrides?.lodes, @@ -100,3 +102,4 @@ export const createTestStore = (overrides?: DeepPartial) => specs: specsSlice.reducer, }, }) +} diff --git a/packages/api-explorer/src/utils/index.ts b/packages/api-explorer/src/utils/index.ts index 1eaca523a..a0959f5ab 100644 --- a/packages/api-explorer/src/utils/index.ts +++ b/packages/api-explorer/src/utils/index.ts @@ -30,4 +30,5 @@ export { getLoded } from './lodeUtils' export { useWindowSize } from './useWindowSize' export * from './apixAdaptor' export * from './adaptorUtils' +export { MockedProvider, mockHistory } from './testReduxUtils' export { useNavigation, useGlobalStoreSync, useQuery } from './hooks' diff --git a/packages/api-explorer/src/utils/testReduxUtils.tsx b/packages/api-explorer/src/utils/testReduxUtils.tsx new file mode 100644 index 000000000..bc54819f0 --- /dev/null +++ b/packages/api-explorer/src/utils/testReduxUtils.tsx @@ -0,0 +1,75 @@ +/* + + MIT License + + Copyright (c) 2022 Looker Data Sciences, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + */ +import { ComponentsProvider } from '@looker/components' +import type { Store } from '@looker/redux' +import React from 'react' +import { QueryClient, QueryClientProvider } from 'react-query' +import { Provider } from 'react-redux' +import { Router } from 'react-router' +import { HelmetProvider } from 'react-helmet-async' +import type { MemoryHistoryBuildOptions, History } from 'history' +import { createMemoryHistory } from 'history' +import type { RootState } from '../state' +import { createTestStore } from '../test-utils' + +export interface MockedProviderProps { + history?: History + store?: Store +} + +/** + * Mocks all providers needed to render any component or scene + */ +export const MockedProvider: React.FC = ({ + children, + history = mockHistory(), + store = createTestStore(), +}) => { + return ( + + + + + + {children} + + + + + + ) +} + +export const mockHistory = ( + /** + * Set the current route by passing in a string or to mock the entire + * history stack pass in MemoryHistoryBuildOptions + */ + route?: string | MemoryHistoryBuildOptions +) => + createMemoryHistory( + typeof route === 'string' ? { initialEntries: [route] } : route + )