-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: ability to share a preconfigured diff scene #1158
base: main
Are you sure you want to change the base?
Changes from all commits
7fa7881
1fe3e4a
e3b7e3d
853531a
2d28c7f
7c04e61
863bf47
6e3f9ea
6339b11
0b09d4f
2d54f37
caa189c
ae47fa0
70ae6e2
376e21b
e1e4c0a
d8bfd8a
93b959a
6d46d80
4048143
ffda1ca
071e0b5
358c56c
91917f5
a6a47ca
d92df04
377dac8
ea02ec2
73ca49c
c0297ed
ef95f97
90840d4
f883a97
268ecd3
7e8e558
a8965ea
c34fdee
09a0666
c54f9b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,7 +76,10 @@ describe('SideNavMethods', () => { | |
const firstMethod = Object.values(methods)[0].schema.summary | ||
expect(screen.queryByText(firstMethod)).not.toBeInTheDocument() | ||
userEvent.click(screen.getByText(tag)) | ||
expect(mockHistoryPush).toHaveBeenCalledWith(`/${specKey}/methods/${tag}`) | ||
expect(mockHistoryPush).toHaveBeenCalledWith({ | ||
pathname: `/${specKey}/methods/${tag}`, | ||
search: '', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this change won't be needed if |
||
}) | ||
expect(screen.getByRole('link', { name: firstMethod })).toBeInTheDocument() | ||
expect(screen.getAllByRole('link')).toHaveLength( | ||
Object.values(methods).length | ||
|
@@ -98,7 +101,10 @@ describe('SideNavMethods', () => { | |
Object.values(methods).length | ||
) | ||
userEvent.click(screen.getByText(tag)) | ||
expect(mockHistoryPush).toHaveBeenCalledWith(`/${specKey}/methods`) | ||
expect(mockHistoryPush).toHaveBeenCalledWith({ | ||
pathname: `/${specKey}/methods`, | ||
search: '', | ||
}) | ||
Comment on lines
+104
to
+107
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
expect(screen.queryByText(firstMethod)).not.toBeInTheDocument() | ||
expect(screen.queryByRole('link')).not.toBeInTheDocument() | ||
}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,8 +44,7 @@ interface MethodsProps { | |
|
||
export const SideNavMethods = styled( | ||
({ className, methods, tag, specKey, defaultOpen = false }: MethodsProps) => { | ||
const { buildPathWithGlobalParams, navigateWithGlobalParams } = | ||
useNavigation() | ||
const { buildPathWithGlobalParams, navigate } = useNavigation() | ||
const searchPattern = useSelector(selectSearchPattern) | ||
const match = useRouteMatch<{ methodTag: string }>( | ||
`/:specKey/methods/:methodTag/:methodName?` | ||
|
@@ -55,9 +54,9 @@ export const SideNavMethods = styled( | |
const _isOpen = !isOpen | ||
setIsOpen(_isOpen) | ||
if (_isOpen) { | ||
navigateWithGlobalParams(`/${specKey}/methods/${tag}`) | ||
navigate(`/${specKey}/methods/${tag}`, { opts: null }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The scenario to consider here (and with the same change in So, technically, the purpose of this line in plain english is more like "navigate to the tag scene and ONLY keep the tag filter variable if we have one in the URL" This makes me reconsider what we initially had proposed where we have a specific
To better account for case 2, I think having custom navigate methods makes the most sense. Here we'd explicitly have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not |
||
} else { | ||
navigateWithGlobalParams(`/${specKey}/methods`) | ||
navigate(`/${specKey}/methods`, { opts: null }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,9 +54,9 @@ export const SideNavTypes = styled( | |
const _isOpen = !isOpen | ||
setIsOpen(_isOpen) | ||
if (_isOpen) { | ||
navigate(`/${specKey}/types/${tag}`) | ||
navigate(`/${specKey}/types/${tag}`, { opts: null }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
} else { | ||
navigate(`/${specKey}/types`) | ||
navigate(`/${specKey}/types`, { opts: null }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
/* | ||
|
||
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 React from 'react' | ||
import { screen, waitFor, within } from '@testing-library/react' | ||
|
||
import type { SpecItem } from '@looker/sdk-codegen' | ||
import userEvent from '@testing-library/user-event' | ||
import { getLoadedSpecs } from '../../test-data' | ||
import { | ||
createTestStore, | ||
renderWithRouterAndReduxProvider, | ||
} from '../../test-utils' | ||
import { getApixAdaptor } from '../../utils' | ||
import { DiffScene } from './DiffScene' | ||
|
||
const mockHistoryPush = jest.fn() | ||
jest.mock('react-router-dom', () => { | ||
const location = { | ||
pathname: '/3.1/diff', | ||
search: '', | ||
hash: '', | ||
state: {}, | ||
key: '', | ||
} | ||
const ReactRouter = jest.requireActual('react-router-dom') | ||
return { | ||
__esModule: true, | ||
...ReactRouter, | ||
useHistory: () => ({ | ||
push: mockHistoryPush, | ||
location, | ||
}), | ||
useLocation: jest.fn().mockReturnValue(location), | ||
} | ||
}) | ||
|
||
const specs = getLoadedSpecs() | ||
class MockApixAdaptor { | ||
async fetchSpec(spec: SpecItem) { | ||
return new Promise(() => specs[spec.key]) | ||
} | ||
} | ||
|
||
const mockApixAdaptor = new MockApixAdaptor() | ||
jest.mock('../../utils/apixAdaptor', () => { | ||
const apixAdaptor = jest.requireActual('../../utils/apixAdaptor') | ||
return { | ||
__esModule: true, | ||
...apixAdaptor, | ||
getApixAdaptor: jest.fn(), | ||
} | ||
}) | ||
|
||
describe('DiffScene', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
;(getApixAdaptor as jest.Mock).mockReturnValue(mockApixAdaptor) | ||
Element.prototype.scrollTo = jest.fn() | ||
Element.prototype.scrollIntoView = jest.fn() | ||
|
||
const toggleNavigation = () => false | ||
|
||
test('rendering with no url opts param results in default comparison options toggled', () => { | ||
const store = createTestStore({ | ||
specs: { specs, currentSpecKey: '3.1' }, | ||
}) | ||
renderWithRouterAndReduxProvider( | ||
<DiffScene toggleNavigation={toggleNavigation} />, | ||
['/3.1/diff'], | ||
store | ||
) | ||
|
||
expect( | ||
screen.getByRole('option', { | ||
name: 'Missing Delete', | ||
}) | ||
).toBeInTheDocument() | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Parameters Delete', | ||
}) | ||
).toBeInTheDocument() | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Type Delete', | ||
}) | ||
).toBeInTheDocument() | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Body Delete', | ||
}) | ||
).toBeInTheDocument() | ||
expect( | ||
screen.queryByRole('option', { | ||
name: 'Status Delete', | ||
}) | ||
).not.toBeInTheDocument() | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Response Delete', | ||
}) | ||
).toBeInTheDocument() | ||
}) | ||
|
||
test('selecting a comparison option pushes it to url opts param', async () => { | ||
const store = createTestStore({ | ||
specs: { specs, currentSpecKey: '3.1' }, | ||
settings: { diffOptions: [] }, | ||
}) | ||
renderWithRouterAndReduxProvider( | ||
<DiffScene toggleNavigation={toggleNavigation} />, | ||
['/3.1/diff'], | ||
store | ||
) | ||
userEvent.click(screen.getByPlaceholderText('Comparison options')) | ||
await waitFor(() => { | ||
expect(screen.getByRole('dialog')).toBeInTheDocument() | ||
}) | ||
userEvent.click( | ||
screen.getByRole('option', { | ||
name: 'Missing', | ||
}) | ||
) | ||
await waitFor(() => { | ||
expect(mockHistoryPush).toHaveBeenLastCalledWith({ | ||
pathname: '/3.1/diff', | ||
search: 'opts=missing', | ||
}) | ||
}) | ||
}) | ||
|
||
test('unselecting comparison option will remove it from url opts param', async () => { | ||
const store = createTestStore({ | ||
specs: { specs, currentSpecKey: '3.1' }, | ||
settings: { diffOptions: ['missing', 'params'] }, | ||
}) | ||
renderWithRouterAndReduxProvider( | ||
<DiffScene toggleNavigation={toggleNavigation} />, | ||
['/3.1/diff'], | ||
store | ||
) | ||
const missingOption = screen.getByRole('option', { | ||
name: 'Missing Delete', | ||
}) | ||
userEvent.click(within(missingOption).getByRole('button')) | ||
await waitFor(() => { | ||
expect(mockHistoryPush).toHaveBeenLastCalledWith({ | ||
pathname: '/3.1/diff', | ||
search: 'opts=params', | ||
}) | ||
}) | ||
}) | ||
|
||
test('selecting clear option will remove all params from url opts param', async () => { | ||
const store = createTestStore({ | ||
specs: { specs, currentSpecKey: '3.1' }, | ||
}) | ||
renderWithRouterAndReduxProvider( | ||
<DiffScene toggleNavigation={toggleNavigation} />, | ||
['/3.1/diff'], | ||
store | ||
) | ||
userEvent.click( | ||
screen.getByRole('button', { | ||
name: 'Clear Field', | ||
}) | ||
) | ||
await waitFor(() => { | ||
expect(mockHistoryPush).toHaveBeenLastCalledWith({ | ||
pathname: '/3.1/diff', | ||
search: '', | ||
}) | ||
}) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can remove this, but I thought it would be nice to have an integration test ensuring the DiffScene operates properly other than the unit tests which I couldn't make comprehensive due to the spec file bug.