Skip to content

Commit

Permalink
make env adaptor globally available
Browse files Browse the repository at this point in the history
- eliminates the need for the envAdaptor context
- Paves the way for envAdaptor usage in sagas
  • Loading branch information
josephaxisa committed Oct 13, 2021
1 parent 474ee93 commit 6a1973d
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 119 deletions.
93 changes: 48 additions & 45 deletions packages/api-explorer/src/ApiExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ import { Aside, ComponentsProvider, Layout, Page } from '@looker/components'
import type { SpecList } from '@looker/sdk-codegen'
import type { RunItSetter } from '@looker/run-it'
import { funFetch, fallbackFetch, OAuthScene } from '@looker/run-it'
import {
SearchContext,
LodeContext,
defaultLodeContextValue,
EnvAdaptorContext,
} from './context'
import { SearchContext, LodeContext, defaultLodeContextValue } from './context'
import type { IApixEnvAdaptor } from './utils'
import { EnvAdaptorConstants, getLoded, oAuthPath } from './utils'
import {
EnvAdaptorConstants,
getLoded,
oAuthPath,
registerEnvAdaptor,
unregisterEnvAdaptor,
} from './utils'
import { Header, SideNav, ErrorBoundary } from './components'
import {
specReducer,
Expand Down Expand Up @@ -71,10 +72,10 @@ const ApiExplorer: FC<ApiExplorerProps> = ({
declarationsLodeUrl = `${apixFilesHost}/declarationsIndex.json`,
headless = false,
}) => {
registerEnvAdaptor(envAdaptor)
const location = useLocation()
const { setSdkLanguageAction } = useActions()
const oauthReturn = location.pathname === `/${oAuthPath}`

const [specState, specDispatch] = useReducer(
specReducer,
initDefaultSpecState(specs, location)
Expand All @@ -97,6 +98,10 @@ const ApiExplorer: FC<ApiExplorerProps> = ({
}
}, [])

useEffect(() => {
return () => unregisterEnvAdaptor()
}, [])

useEffect(() => {
if (headless) {
window.addEventListener('message', hasNavigationToggle)
Expand Down Expand Up @@ -153,47 +158,45 @@ const ApiExplorer: FC<ApiExplorerProps> = ({
themeCustomizations={themeCustomizations}
>
<ErrorBoundary logError={envAdaptor.logError.bind(envAdaptor)}>
<EnvAdaptorContext.Provider value={{ envAdaptor }}>
<LodeContext.Provider value={{ ...lode }}>
<SearchContext.Provider
value={{ searchSettings, setSearchSettings }}
>
<Page style={{ overflow: 'hidden' }}>
{!headless && (
<Header
<LodeContext.Provider value={{ ...lode }}>
<SearchContext.Provider
value={{ searchSettings, setSearchSettings }}
>
<Page style={{ overflow: 'hidden' }}>
{!headless && (
<Header
specs={specs}
spec={spec}
specDispatch={specDispatch}
toggleNavigation={toggleNavigation}
/>
)}
<Layout hasAside height="100%">
{hasNavigation && (
<AsideBorder pt="large" width="20rem">
<SideNav
headless={headless}
specs={specs}
spec={spec}
specDispatch={specDispatch}
/>
</AsideBorder>
)}
{oauthReturn && <OAuthScene />}
{!oauthReturn && spec.api && (
<AppRouter
api={spec.api}
specKey={spec.key}
specs={specs}
spec={spec}
specDispatch={specDispatch}
toggleNavigation={toggleNavigation}
envAdaptor={envAdaptor}
setVersionsUrl={setVersionsUrl}
/>
)}
<Layout hasAside height="100%">
{hasNavigation && (
<AsideBorder pt="large" width="20rem">
<SideNav
headless={headless}
specs={specs}
spec={spec}
specDispatch={specDispatch}
/>
</AsideBorder>
)}
{oauthReturn && <OAuthScene />}
{!oauthReturn && spec.api && (
<AppRouter
api={spec.api}
specKey={spec.key}
specs={specs}
toggleNavigation={toggleNavigation}
envAdaptor={envAdaptor}
setVersionsUrl={setVersionsUrl}
/>
)}
</Layout>
</Page>
</SearchContext.Provider>
</LodeContext.Provider>
</EnvAdaptorContext.Provider>
</Layout>
</Page>
</SearchContext.Provider>
</LodeContext.Provider>
</ErrorBoundary>
</ComponentsProvider>
{!headless && <BodyOverride />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import React from 'react'
import { screen } from '@testing-library/react'
import { renderWithTheme } from '@looker/components-test-utils'

import { renderWithSearch } from '../../test-utils'
import { renderWithSearch, registerTestEnvAdaptor } from '../../test-utils'
import { DocMarkdown } from './DocMarkdown'

describe('DocMarkdown', () => {
beforeEach(() => {
registerTestEnvAdaptor()
})
test('it renders markdown', () => {
renderWithSearch(
<DocMarkdown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import type { FC } from 'react'
import React, { useContext } from 'react'
import { useHistory } from 'react-router-dom'
import { Markdown } from '@looker/code-editor'
import { EnvAdaptorContext, SearchContext } from '../../context'
import { SearchContext } from '../../context'
import { getEnvAdaptor } from '../../utils'
import { transformURL } from './utils'

interface DocMarkdownProps {
Expand All @@ -37,7 +38,7 @@ interface DocMarkdownProps {
}

export const DocMarkdown: FC<DocMarkdownProps> = ({ source, specKey }) => {
const { envAdaptor } = useContext(EnvAdaptorContext)
const envAdaptor = getEnvAdaptor()
const {
searchSettings: { pattern },
} = useContext(SearchContext)
Expand Down
7 changes: 6 additions & 1 deletion packages/api-explorer/src/components/Header/Header.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import { codeGenerators } from '@looker/sdk-codegen'
import userEvent from '@testing-library/user-event'

import { specs, specState } from '../../test-data'
import { renderWithRouter, withReduxProvider } from '../../test-utils'
import {
renderWithRouter,
withReduxProvider,
registerTestEnvAdaptor,
} from '../../test-utils'
import { defaultSettingsState } from '../../state'
import { Header } from './Header'

Expand All @@ -40,6 +44,7 @@ describe('Header', () => {

beforeAll(() => {
window.HTMLElement.prototype.scrollIntoView = jest.fn()
registerTestEnvAdaptor()
})

test('it renders a title', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ import userEvent from '@testing-library/user-event'
import { codeGenerators } from '@looker/sdk-codegen'

import { defaultSettingsState } from '../../state'
import { renderWithReduxProvider } from '../../test-utils'
import {
registerTestEnvAdaptor,
renderWithReduxProvider,
} from '../../test-utils'
import { EnvAdaptorConstants } from '../../utils'
import { SdkLanguageSelector } from './SdkLanguageSelector'

Expand All @@ -38,6 +41,7 @@ describe('SdkLanguageSelector', () => {

beforeEach(() => {
localStorage.clear()
registerTestEnvAdaptor()
})

test('it has the correct default language selected', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,23 @@
*/
import type { FC } from 'react'
import React, { useContext } from 'react'
import React from 'react'
import { codeGenerators } from '@looker/sdk-codegen'
import { Select } from '@looker/components'
import { useSelector } from 'react-redux'
import type { SelectOptionProps } from '@looker/components'

import { useActions } from '../../hooks'
import { getSelectedSdkLanguage } from '../../state'
import { EnvAdaptorContext } from '../../context'
import { EnvAdaptorConstants } from '../../utils'
import { EnvAdaptorConstants, getEnvAdaptor } from '../../utils'

/**
* Allows the user to select their preferred SDK language
*/
export const SdkLanguageSelector: FC = () => {
const { setSdkLanguageAction } = useActions()
const selectedSdkLanguage = useSelector(getSelectedSdkLanguage)
const { envAdaptor } = useContext(EnvAdaptorContext)
const envAdaptor = getEnvAdaptor()

const allSdkLanguages: SelectOptionProps[] = codeGenerators.map((gen) => ({
value: gen.language,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import { codeGenerators } from '@looker/sdk-codegen'
import userEvent from '@testing-library/user-event'

import { specs, specState } from '../../test-data'
import { renderWithRouter, withReduxProvider } from '../../test-utils'
import {
registerTestEnvAdaptor,
renderWithRouter,
withReduxProvider,
} from '../../test-utils'
import { defaultSettingsState } from '../../state'
import { SelectorContainer } from './SelectorContainer'

Expand All @@ -38,6 +42,7 @@ describe('SelectorContainer', () => {

beforeAll(() => {
window.HTMLElement.prototype.scrollIntoView = jest.fn()
registerTestEnvAdaptor()
})

test('it renders a spec selector with the correct default value and options', async () => {
Expand Down
39 changes: 0 additions & 39 deletions packages/api-explorer/src/context/envAdaptor/EnvAdaptorContext.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/api-explorer/src/context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,3 @@
*/
export { LodeContext, defaultLodeContextValue } from './lode'
export { SearchContext, defaultSearchContextValue } from './search'
export { EnvAdaptorContext, defaultEnvAdaptorContextValue } from './envAdaptor'
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
SOFTWARE.
*/
export {
defaultEnvAdaptorContextValue,
EnvAdaptorContext,
} from './EnvAdaptorContext'
import type { IApixEnvAdaptor } from '../utils'
import { registerEnvAdaptor, StandaloneEnvAdaptor } from '../utils'

export const registerTestEnvAdaptor = (envAdaptor?: IApixEnvAdaptor) => {
registerEnvAdaptor(envAdaptor || new StandaloneEnvAdaptor())
}
1 change: 1 addition & 0 deletions packages/api-explorer/src/test-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export {
renderWithReduxProvider,
withReduxProvider,
} from './redux'
export { registerTestEnvAdaptor } from './envAdaptor'
24 changes: 4 additions & 20 deletions packages/api-explorer/src/test-utils/redux.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,27 @@ import type { RenderOptions } from '@testing-library/react'

import type { RootState } from '../state'
import { configureStore } from '../state'
import type { IApixEnvAdaptor } from '../utils'
import { StandaloneEnvAdaptor } from '../utils'
import { EnvAdaptorContext } from '../context'
import { renderWithRouter } from '.'

const defaultStore = configureStore()

export const withReduxProvider = (
consumers: ReactElement<any>,
store: Store<RootState> = defaultStore,
envAdaptor: IApixEnvAdaptor = new StandaloneEnvAdaptor()
store: Store<RootState> = defaultStore
) => {
return (
<Provider store={store}>
<EnvAdaptorContext.Provider value={{ envAdaptor }}>
{consumers}
</EnvAdaptorContext.Provider>
</Provider>
)
return <Provider store={store}>{consumers}</Provider>
}

export const renderWithReduxProvider = (
consumers: ReactElement<any>,
store?: Store<RootState>,
envAdaptor?: IApixEnvAdaptor,
options?: Omit<RenderOptions, 'queries'>
) => renderWithTheme(withReduxProvider(consumers, store, envAdaptor), options)
) => renderWithTheme(withReduxProvider(consumers, store), options)

export const renderWithRouterAndReduxProvider = (
consumers: ReactElement<any>,
initialEntries: string[] = ['/'],
store?: Store<RootState>,
envAdaptor?: IApixEnvAdaptor,
options?: Omit<RenderOptions, 'queries'>
) =>
renderWithRouter(
withReduxProvider(consumers, store, envAdaptor),
initialEntries,
options
)
renderWithRouter(withReduxProvider(consumers, store), initialEntries, options)
26 changes: 26 additions & 0 deletions packages/api-explorer/src/utils/envAdaptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,29 @@ export class StandaloneEnvAdaptor implements IApixEnvAdaptor {
export enum EnvAdaptorConstants {
LOCALSTORAGE_SDK_LANGUAGE_KEY = 'sdkLanguage',
}

let envAdaptor: IApixEnvAdaptor | undefined

/**
* Register the environment adaptor. The API Explorer will automatically call this.
*/
export const registerEnvAdaptor = (adaptor: IApixEnvAdaptor) => {
envAdaptor = adaptor
}

/**
* Unregister the envAdaptor. The ApiExplorer will automatically call this when it is unmounted.
*/
export const unregisterEnvAdaptor = () => {
envAdaptor = undefined
}

/**
* Global access to the envAdaptor. An error will be thrown if accessed prematurely.
*/
export const getEnvAdaptor = () => {
if (!envAdaptor) {
throw new Error('Environment adaptor not initialized.')
}
return envAdaptor
}

0 comments on commit 6a1973d

Please sign in to comment.