-
Notifications
You must be signed in to change notification settings - Fork 196
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 23 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 |
---|---|---|
|
@@ -54,9 +54,9 @@ export const SideNavMethods = styled( | |
const _isOpen = !isOpen | ||
setIsOpen(_isOpen) | ||
if (_isOpen) { | ||
navigate(`/${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. why not |
||
} else { | ||
navigate(`/${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,147 @@ | ||
/* | ||
|
||
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 } from '@testing-library/react' | ||
import userEvent from '@testing-library/user-event' | ||
|
||
import type { SpecItem } from '@looker/sdk-codegen' | ||
import { useHistory } from 'react-router-dom' | ||
import * as routerLocation from 'react-router-dom' | ||
import type { Location } from 'history' | ||
import * as reactRedux from 'react-redux' | ||
import { getLoadedSpecs } from '../../test-data' | ||
import { | ||
createTestStore, | ||
renderWithRouterAndReduxProvider, | ||
} from '../../test-utils' | ||
import { getApixAdaptor } from '../../utils' | ||
import { DiffScene } from './DiffScene' | ||
|
||
jest.mock('react-router', () => { | ||
const ReactRouter = jest.requireActual('react-router') | ||
return { | ||
...ReactRouter, | ||
useHistory: jest.fn().mockReturnValue({ push: jest.fn(), location }), | ||
useLocation: jest.fn().mockReturnValue({ pathname: '/', search: '' }), | ||
} | ||
}) | ||
|
||
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 { | ||
...apixAdaptor, | ||
getApixAdaptor: jest.fn(), | ||
} | ||
}) | ||
|
||
describe('DiffScene', () => { | ||
const mockDispatch = jest.fn() | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
;(getApixAdaptor as jest.Mock).mockReturnValue(mockApixAdaptor) | ||
Element.prototype.scrollTo = jest.fn() | ||
Element.prototype.scrollIntoView = jest.fn() | ||
|
||
const toggleNavigation = () => false | ||
test('toggling comparison option pushes param to url', async () => { | ||
const { push } = useHistory() | ||
const store = createTestStore({ | ||
specs: { specs, currentSpecKey: '3.1' }, | ||
settings: { initialized: true }, | ||
}) | ||
renderWithRouterAndReduxProvider( | ||
<DiffScene specs={specs} toggleNavigation={toggleNavigation} />, | ||
['/diff/3.1'], | ||
store | ||
) | ||
userEvent.click(screen.getByPlaceholderText('Comparison options')) | ||
userEvent.click( | ||
screen.getByRole('option', { | ||
name: 'Missing', | ||
}) | ||
) | ||
await waitFor(() => { | ||
expect(push).toHaveBeenCalledWith({ | ||
pathname: '/', | ||
search: 'opts=missing', | ||
}) | ||
}) | ||
// TODO: test URL change leads to store dispatch? - change mock history push implementation to change our location | ||
// TODO: test that toggling another will push both options to store/url | ||
}) | ||
|
||
test.todo( | ||
'rendering scene with opts param in url sets selected options in selector', | ||
async () => { | ||
jest.spyOn(routerLocation, 'useLocation').mockReturnValue({ | ||
pathname: `/`, | ||
search: `opts=missing%2Ctype%2Cresponse`, | ||
} as unknown as Location) | ||
const store = createTestStore({ | ||
specs: { specs, currentSpecKey: '3.1' }, | ||
settings: { initialized: true, diffOptions: [] }, | ||
}) | ||
jest.spyOn(reactRedux, 'useDispatch').mockReturnValue(mockDispatch) | ||
renderWithRouterAndReduxProvider( | ||
<DiffScene specs={specs} toggleNavigation={toggleNavigation} />, | ||
['/diff/3.1'], | ||
store | ||
) | ||
expect(mockDispatch).toHaveBeenLastCalledWith({ | ||
payload: { diffOptions: ['missing', 'type', 'response'] }, | ||
type: 'settings/setDiffOptionsAction', | ||
}) | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Missing', | ||
}) | ||
).toBeInTheDocument() | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Type', | ||
}) | ||
).toBeInTheDocument() | ||
expect( | ||
screen.getByRole('option', { | ||
name: 'Response', | ||
}) | ||
).toBeInTheDocument() | ||
} | ||
) | ||
|
||
test.todo('unselecting comparison option will remove it from url opts param') | ||
test.todo('selecting clear option will remove all params from url opts param') | ||
}) |
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.
The scenario to consider here (and with the same change in
SideNavTypes
): we are in a diff scene with selected options, andopts
param in the url. When we open the sideNav and open a method/tag scene, this opts parameter should no longer persist. The reason we don't usenavigateWithGlobalParams
to remove this parameter is because if we started at a tag scene with a filter selected and want to select another tag, this filter should still persist when we open the new tag scene.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
navigateTo
methods. I think in the long term there will be 2 cases:navigateWithGlobalParams
, etc)To better account for case 2, I think having custom navigate methods makes the most sense. Here we'd explicitly have a
navigateToTagScene
instead of having to explicitly nullify any extra parameters that could persist when navigating to a tag scene from the SideNav.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.
@josephaxisa