@@ -103,7 +103,7 @@ export class AdminContainer extends React.PureComponent<AdminContainerProps, Sta | |||
({ status }) => { | |||
if (this.mounted) { | |||
this.setState({ systemStatus: status }); | |||
document.location.reload(); | |||
window.location.reload(); | |||
} | |||
}, | |||
() => {} |
@@ -17,34 +17,152 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import userEvent from '@testing-library/user-event'; | |||
import * as React from 'react'; | |||
import { Route, useOutletContext } from 'react-router-dom'; | |||
import { getSystemStatus, waitSystemUPStatus } from '../../../api/system'; | |||
import { mockAppState } from '../../../helpers/testMocks'; | |||
import { renderAppRoutes } from '../../../helpers/testReactTestingUtils'; | |||
import { byLabelText, byRole, byText } from '../../../helpers/testSelector'; | |||
import { AdminPagesContext } from '../../../types/admin'; | |||
import { AdminContainer, AdminContainerProps } from '../AdminContainer'; | |||
import AdminContext from '../AdminContext'; | |||
jest.mock('../../../api/navigation', () => ({ | |||
getSettingsNavigation: jest | |||
.fn() | |||
.mockResolvedValue({ extensions: [{ key: 'asd', name: 'asdf' }] }), | |||
})); | |||
jest.mock('../../../api/plugins', () => ({ | |||
getSettingsNavigation: jest.fn().mockResolvedValue({}), | |||
getPendingPlugins: jest.fn().mockResolvedValue({}), | |||
getPendingPlugins: jest.fn().mockResolvedValue({ | |||
installing: [{ key: '1', name: 'installing' }], | |||
updating: [ | |||
{ key: '2', name: 'updating' }, | |||
{ key: '2b', name: 'update this too' }, | |||
], | |||
removing: [{ key: '3', name: 'removing' }], | |||
}), | |||
})); | |||
jest.mock('../../../api/system', () => ({ | |||
getSystemStatus: jest.fn().mockResolvedValue({}), | |||
getSystemStatus: jest.fn().mockResolvedValue({ status: 'DOWN' }), | |||
waitSystemUPStatus: jest.fn().mockResolvedValue({ status: 'RESTARTING' }), | |||
})); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
const originalLocation = window.location; | |||
const reload = jest.fn(); | |||
beforeAll(() => { | |||
Object.defineProperty(window, 'location', { | |||
writable: true, | |||
value: { reload }, | |||
}); | |||
}); | |||
function shallowRender(props: Partial<AdminContainerProps> = {}) { | |||
return shallow( | |||
<AdminContainer | |||
appState={mockAppState({ | |||
canAdmin: true, | |||
})} | |||
{...props} | |||
afterAll(() => { | |||
Object.defineProperty(window, 'location', { | |||
writable: true, | |||
value: originalLocation, | |||
}); | |||
}); | |||
it('should render nav and provide context to children', async () => { | |||
const user = userEvent.setup(); | |||
renderAdminContainer(); | |||
expect(await ui.navHeader.find()).toBeInTheDocument(); | |||
expect(ui.pagesList.byRole('listitem').getAll()).toHaveLength(1); | |||
expect(ui.pagesList.byText('asdf').get()).toBeInTheDocument(); | |||
expect(ui.pluginsInstallingList.byRole('listitem').getAll()).toHaveLength(1); | |||
expect(ui.pluginsInstallingList.byText('installing').get()).toBeInTheDocument(); | |||
expect(ui.pluginsUpdatingList.byRole('listitem').getAll()).toHaveLength(2); | |||
expect(ui.pluginsUpdatingList.byText('updating').get()).toBeInTheDocument(); | |||
expect(ui.pluginsUpdatingList.byText('update this too').get()).toBeInTheDocument(); | |||
expect(ui.pluginsRemovingList.byRole('listitem').getAll()).toHaveLength(1); | |||
expect(ui.pluginsRemovingList.byText('removing').get()).toBeInTheDocument(); | |||
expect(byText('DOWN').get()).toBeInTheDocument(); | |||
// Trigger a status update | |||
jest.mocked(getSystemStatus).mockResolvedValueOnce({ id: '', version: '', status: 'RESTARTING' }); | |||
jest.mocked(waitSystemUPStatus).mockResolvedValueOnce({ id: '', version: '', status: 'UP' }); | |||
await user.click(ui.fetchStatusButton.get()); | |||
expect(await byText('UP').find()).toBeInTheDocument(); | |||
expect(reload).toHaveBeenCalled(); | |||
}); | |||
function renderAdminContainer(props: Partial<AdminContainerProps> = {}) { | |||
return renderAppRoutes('admin', () => ( | |||
<Route | |||
path="admin" | |||
element={ | |||
<AdminContainer | |||
appState={mockAppState({ | |||
canAdmin: true, | |||
})} | |||
{...props} | |||
/> | |||
} | |||
> | |||
<div /> | |||
</AdminContainer> | |||
<Route index element={<TestChildComponent />} /> | |||
</Route> | |||
)); | |||
} | |||
function TestChildComponent() { | |||
const { adminPages } = useOutletContext<AdminPagesContext>(); | |||
const { fetchPendingPlugins, fetchSystemStatus, pendingPlugins, systemStatus } = | |||
React.useContext(AdminContext); | |||
return ( | |||
<div> | |||
<ul aria-label="pages"> | |||
{adminPages.map((page) => ( | |||
<li key={page.key}>{page.name}</li> | |||
))} | |||
</ul> | |||
<ul aria-label="plugins - installing"> | |||
{pendingPlugins.installing.map((p) => ( | |||
<li key={p.key}>{p.name}</li> | |||
))} | |||
</ul> | |||
<ul aria-label="plugins - removing"> | |||
{pendingPlugins.removing.map((p) => ( | |||
<li key={p.key}>{p.name}</li> | |||
))} | |||
</ul> | |||
<ul aria-label="plugins - updating"> | |||
{pendingPlugins.updating.map((p) => ( | |||
<li key={p.key}>{p.name}</li> | |||
))} | |||
</ul> | |||
<button type="button" onClick={fetchPendingPlugins}> | |||
fetch plugins | |||
</button> | |||
{systemStatus} | |||
<button type="button" onClick={fetchSystemStatus}> | |||
fetch status | |||
</button> | |||
</div> | |||
); | |||
} | |||
const ui = { | |||
navHeader: byRole('heading', { name: 'layout.settings' }), | |||
pagesList: byLabelText('pages'), | |||
pluginsInstallingList: byLabelText('plugins - installing'), | |||
pluginsUpdatingList: byLabelText('plugins - updating'), | |||
pluginsRemovingList: byLabelText('plugins - removing'), | |||
fetchPluginsButton: byRole('button', { name: 'fetch plugins' }), | |||
fetchStatusButton: byRole('button', { name: 'fetch status' }), | |||
}; |
@@ -17,32 +17,32 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockAppState } from '../../../helpers/testMocks'; | |||
import { renderComponent } from '../../../helpers/testReactTestingUtils'; | |||
import { App } from '../App'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect( | |||
shallowRender({ | |||
appState: mockAppState({ | |||
settings: { | |||
'sonar.lf.enableGravatar': 'true', | |||
'sonar.lf.gravatarServerUrl': 'http://example.com', | |||
}, | |||
}), | |||
}) | |||
).toMatchSnapshot('with gravatar'); | |||
it('should render correctly with gravatar', () => { | |||
renderApp({ | |||
appState: mockAppState({ | |||
settings: { | |||
'sonar.lf.enableGravatar': 'true', | |||
'sonar.lf.gravatarServerUrl': 'http://example.com', | |||
}, | |||
}), | |||
}); | |||
// eslint-disable-next-line testing-library/no-node-access | |||
expect(document.head.querySelector('link')).toHaveAttribute('href', 'http://example.com'); | |||
}); | |||
it('should correctly set the scrollbar width as a custom property', () => { | |||
shallowRender(); | |||
renderApp(); | |||
expect(document.body.style.getPropertyValue('--sbw')).toBe('0px'); | |||
}); | |||
function shallowRender(props: Partial<App['props']> = {}) { | |||
return shallow<App>( | |||
function renderApp(props: Partial<App['props']> = {}) { | |||
return renderComponent( | |||
<App | |||
appState={mockAppState({ | |||
settings: { |
@@ -17,69 +17,60 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import { act } from '@testing-library/react'; | |||
import userEvent from '@testing-library/user-event'; | |||
import React from 'react'; | |||
import Modal from '../../../components/controls/Modal'; | |||
import { mockEvent } from '../../../helpers/testUtils'; | |||
import { renderComponent } from '../../../helpers/testReactTestingUtils'; | |||
import { byRole } from '../../../helpers/testSelector'; | |||
import KeyboardShortcutsModal from '../KeyboardShortcutsModal'; | |||
jest.mock('react', () => { | |||
let close: () => void; | |||
return { | |||
...jest.requireActual('react'), | |||
useEffect: jest.fn().mockImplementation((f) => { | |||
close = f(); | |||
}), | |||
clean: () => { | |||
close(); | |||
}, | |||
}; | |||
}); | |||
it('should render correctly', async () => { | |||
const user = userEvent.setup(); | |||
renderKeyboardShortcutsModal(); | |||
afterEach(() => { | |||
if ((React as any).clean as () => void) { | |||
(React as any).clean(); | |||
} | |||
}); | |||
expect(ui.modalTitle.query()).not.toBeInTheDocument(); | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('hidden'); | |||
await act(() => user.keyboard('?')); | |||
document.dispatchEvent(new KeyboardEvent('keydown', { key: '?' })); | |||
expect(ui.modalTitle.get()).toBeInTheDocument(); | |||
expect(wrapper).toMatchSnapshot('visible'); | |||
}); | |||
await user.click(ui.closeButton.get()); | |||
it('should close correctly', () => { | |||
const wrapper = shallowRender(); | |||
document.dispatchEvent(new KeyboardEvent('keydown', { key: '?' })); | |||
expect(ui.modalTitle.query()).not.toBeInTheDocument(); | |||
}); | |||
wrapper.find(Modal).props().onRequestClose!(mockEvent()); | |||
it('should ignore other keydownes', async () => { | |||
const user = userEvent.setup(); | |||
renderKeyboardShortcutsModal(); | |||
expect(wrapper.type()).toBeNull(); | |||
}); | |||
await act(() => user.keyboard('!')); | |||
it('should ignore other keydownes', () => { | |||
const wrapper = shallowRender(); | |||
document.dispatchEvent(new KeyboardEvent('keydown', { key: '!' })); | |||
expect(wrapper.type()).toBeNull(); | |||
expect(ui.modalTitle.query()).not.toBeInTheDocument(); | |||
}); | |||
it.each([['input'], ['select'], ['textarea']])('should ignore events on a %s', (type) => { | |||
const wrapper = shallowRender(); | |||
const fakeEvent = new KeyboardEvent('keydown', { key: '!' }); | |||
it('should ignore events in an input', async () => { | |||
const user = userEvent.setup(); | |||
Object.defineProperty(fakeEvent, 'target', { | |||
value: document.createElement(type), | |||
}); | |||
renderKeyboardShortcutsModal(); | |||
document.dispatchEvent(fakeEvent); | |||
await user.click(ui.textInput.get()); | |||
await act(() => user.keyboard('?')); | |||
expect(wrapper.type()).toBeNull(); | |||
expect(ui.modalTitle.query()).not.toBeInTheDocument(); | |||
}); | |||
function shallowRender() { | |||
return shallow(<KeyboardShortcutsModal />); | |||
function renderKeyboardShortcutsModal() { | |||
return renderComponent( | |||
<> | |||
<KeyboardShortcutsModal /> | |||
<input type="text" /> | |||
</> | |||
); | |||
} | |||
const ui = { | |||
modalTitle: byRole('heading', { name: 'keyboard_shortcuts.title' }), | |||
closeButton: byRole('button', { name: 'close' }), | |||
textInput: byRole('textbox'), | |||
}; |
@@ -17,9 +17,11 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { Route } from 'react-router-dom'; | |||
import { getSystemStatus } from '../../../helpers/system'; | |||
import { renderAppRoutes } from '../../../helpers/testReactTestingUtils'; | |||
import { byText } from '../../../helpers/testSelector'; | |||
import MigrationContainer from '../MigrationContainer'; | |||
jest.mock('../../../helpers/system', () => ({ | |||
@@ -49,14 +51,26 @@ afterAll(() => { | |||
it('should render correctly if system is up', () => { | |||
(getSystemStatus as jest.Mock).mockReturnValueOnce('UP'); | |||
expect(shallowRender()).toMatchSnapshot(); | |||
renderMigrationContainer(); | |||
expect(byText('children').get()).toBeInTheDocument(); | |||
}); | |||
it('should render correctly if system is starting', () => { | |||
(getSystemStatus as jest.Mock).mockReturnValueOnce('STARTING'); | |||
expect(shallowRender()).toMatchSnapshot(); | |||
renderMigrationContainer(); | |||
expect( | |||
byText('/maintenance?return_to=%2Fprojects%3Fquery%3Dtoto%23hash').get() | |||
).toBeInTheDocument(); | |||
}); | |||
function shallowRender() { | |||
return shallow(<MigrationContainer />); | |||
function renderMigrationContainer() { | |||
return renderAppRoutes('/', () => ( | |||
<Route element={<MigrationContainer />}> | |||
<Route index element={<div>children</div>} /> | |||
</Route> | |||
)); | |||
} |
@@ -17,12 +17,15 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import userEvent from '@testing-library/user-event'; | |||
import * as React from 'react'; | |||
import { Link } from 'react-router-dom'; | |||
import { installScript } from '../../../helpers/extensions'; | |||
import { getWebAnalyticsPageHandlerFromCache } from '../../../helpers/extensionsHandler'; | |||
import { mockAppState, mockLocation } from '../../../helpers/testMocks'; | |||
import { PageTracker } from '../PageTracker'; | |||
import { mockAppState } from '../../../helpers/testMocks'; | |||
import { renderComponent } from '../../../helpers/testReactTestingUtils'; | |||
import { byRole } from '../../../helpers/testSelector'; | |||
import PageTracker from '../PageTracker'; | |||
jest.mock('../../../helpers/extensions', () => ({ | |||
installScript: jest.fn().mockResolvedValue({}), | |||
@@ -43,28 +46,41 @@ afterEach(() => { | |||
}); | |||
it('should not trigger if no analytics system is given', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot(); | |||
renderPageTracker(); | |||
expect(installScript).not.toHaveBeenCalled(); | |||
}); | |||
it('should work for WebAnalytics plugin', () => { | |||
it('should work for WebAnalytics plugin', async () => { | |||
const user = userEvent.setup({ delay: null }); | |||
const pageChange = jest.fn(); | |||
const webAnalyticsJsPath = '/static/pluginKey/web_analytics.js'; | |||
const wrapper = shallowRender({ appState: mockAppState({ webAnalyticsJsPath }) }); | |||
renderPageTracker(mockAppState({ webAnalyticsJsPath })); | |||
expect(wrapper).toMatchSnapshot(); | |||
expect(wrapper.find('Helmet').prop('onChangeClientState')).toBe(wrapper.instance().trackPage); | |||
expect(installScript).toHaveBeenCalledWith(webAnalyticsJsPath, 'head'); | |||
(getWebAnalyticsPageHandlerFromCache as jest.Mock).mockReturnValueOnce(pageChange); | |||
wrapper.instance().trackPage(); | |||
jest.mocked(getWebAnalyticsPageHandlerFromCache).mockClear().mockReturnValueOnce(pageChange); | |||
// trigger trackPage | |||
await user.click(byRole('link').get()); | |||
jest.runAllTimers(); | |||
expect(pageChange).toHaveBeenCalledWith('/path'); | |||
expect(pageChange).toHaveBeenCalledWith('/newpath'); | |||
}); | |||
function shallowRender(props: Partial<PageTracker['props']> = {}) { | |||
return shallow<PageTracker>( | |||
<PageTracker appState={mockAppState()} location={mockLocation()} {...props} /> | |||
function renderPageTracker(appState = mockAppState()) { | |||
return renderComponent(<WrappingComponent />, '', { appState }); | |||
} | |||
function WrappingComponent() { | |||
const [metatag, setmetatag] = React.useState<React.ReactNode>(null); | |||
return ( | |||
<> | |||
<PageTracker>{metatag}</PageTracker> | |||
<Link to="newpath" onClick={() => setmetatag(<meta name="toto" />)}> | |||
trigger change | |||
</Link> | |||
</> | |||
); | |||
} |
@@ -17,10 +17,12 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { mount, shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { Route } from 'react-router-dom'; | |||
import handleRequiredAuthorization from '../../../app/utils/handleRequiredAuthorization'; | |||
import { mockComponent } from '../../../helpers/mocks/component'; | |||
import { renderAppRoutes } from '../../../helpers/testReactTestingUtils'; | |||
import { byText } from '../../../helpers/testSelector'; | |||
import { ProjectAdminContainer } from '../ProjectAdminContainer'; | |||
jest.mock('../../utils/handleRequiredAuthorization', () => { | |||
@@ -28,30 +30,33 @@ jest.mock('../../utils/handleRequiredAuthorization', () => { | |||
}); | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
renderProjectAdminContainer(); | |||
expect(byText('children').get()).toBeInTheDocument(); | |||
}); | |||
it('should redirect for authorization if needed', () => { | |||
jest.useFakeTimers(); | |||
mountRender({ component: mockComponent({ configuration: { showSettings: false } }) }); | |||
renderProjectAdminContainer({ | |||
component: mockComponent({ configuration: { showSettings: false } }), | |||
}); | |||
jest.runAllTimers(); | |||
expect(handleRequiredAuthorization).toHaveBeenCalled(); | |||
jest.useRealTimers(); | |||
}); | |||
function mountRender(props: Partial<ProjectAdminContainer['props']> = {}) { | |||
return mount(createComponent(props)); | |||
} | |||
function shallowRender(props: Partial<ProjectAdminContainer['props']> = {}) { | |||
return shallow(createComponent(props)); | |||
} | |||
function createComponent(props: Partial<ProjectAdminContainer['props']> = {}) { | |||
return ( | |||
<ProjectAdminContainer | |||
component={mockComponent({ configuration: { showSettings: true } })} | |||
{...props} | |||
/> | |||
); | |||
function renderProjectAdminContainer(props: Partial<ProjectAdminContainer['props']> = {}) { | |||
return renderAppRoutes('project/settings', () => ( | |||
<Route | |||
path="project/settings" | |||
element={ | |||
<ProjectAdminContainer | |||
component={mockComponent({ configuration: { showSettings: true } })} | |||
{...props} | |||
/> | |||
} | |||
> | |||
<Route index element={<div>children</div>} /> | |||
</Route> | |||
)); | |||
} |
@@ -1,47 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
prioritizeSeoTags={false} | |||
titleTemplate="page_title.template.with_category.layout.settings" | |||
/> | |||
<WithLocation | |||
extensions={[]} | |||
fetchPendingPlugins={[Function]} | |||
fetchSystemStatus={[Function]} | |||
pendingPlugins={ | |||
{ | |||
"installing": [], | |||
"removing": [], | |||
"updating": [], | |||
} | |||
} | |||
systemStatus="UP" | |||
/> | |||
<ContextProvider | |||
value={ | |||
{ | |||
"fetchPendingPlugins": [Function], | |||
"fetchSystemStatus": [Function], | |||
"pendingPlugins": { | |||
"installing": [], | |||
"removing": [], | |||
"updating": [], | |||
}, | |||
"systemStatus": "UP", | |||
} | |||
} | |||
> | |||
<Outlet | |||
context={ | |||
{ | |||
"adminPages": [], | |||
} | |||
} | |||
/> | |||
</ContextProvider> | |||
</Fragment> | |||
`; |
@@ -1,22 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: default 1`] = ` | |||
<Fragment> | |||
<withRouter(withAppStateContext(PageTracker)) /> | |||
<Outlet /> | |||
<KeyboardShortcutsModal /> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: with gravatar 1`] = ` | |||
<Fragment> | |||
<withRouter(withAppStateContext(PageTracker))> | |||
<link | |||
href="http://example.com" | |||
rel="preconnect" | |||
/> | |||
</withRouter(withAppStateContext(PageTracker))> | |||
<Outlet /> | |||
<KeyboardShortcutsModal /> | |||
</Fragment> | |||
`; |
@@ -1,583 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: hidden 1`] = `""`; | |||
exports[`should render correctly: visible 1`] = ` | |||
<Modal | |||
contentLabel="keyboard_shortcuts.title" | |||
onRequestClose={[Function]} | |||
size="medium" | |||
> | |||
<div | |||
className="modal-head display-flex-space-between" | |||
> | |||
<h2> | |||
keyboard_shortcuts.title | |||
</h2> | |||
<ForwardRef(Link) | |||
onClick={[Function]} | |||
to="/account" | |||
> | |||
keyboard_shortcuts.disable_link | |||
</ForwardRef(Link)> | |||
</div> | |||
<div | |||
className="modal-body modal-container markdown display-flex-start shortcuts-modal" | |||
> | |||
<div | |||
className="flex-1" | |||
> | |||
<div | |||
className="spacer-bottom" | |||
key="global" | |||
> | |||
<h3 | |||
className="null-spacer-top" | |||
> | |||
keyboard_shortcuts.global.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="search" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="s" | |||
> | |||
s | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.global.search | |||
</td> | |||
</tr> | |||
<tr | |||
key="open_shortcuts" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="?" | |||
> | |||
? | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.global.open_shortcuts | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-bottom" | |||
key="issues_page" | |||
> | |||
<h3 | |||
className="null-spacer-top" | |||
> | |||
keyboard_shortcuts.issues_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="navigate" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.navigate | |||
</td> | |||
</tr> | |||
<tr | |||
key="source_code" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.source_code | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.back | |||
</td> | |||
</tr> | |||
<tr | |||
key="navigate_locations" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="alt" | |||
> | |||
alt | |||
</code> | |||
<span | |||
className="little-spacer-right" | |||
key="+" | |||
> | |||
+ | |||
</span> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.navigate_locations | |||
</td> | |||
</tr> | |||
<tr | |||
key="switch_flows" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="alt" | |||
> | |||
alt | |||
</code> | |||
<span | |||
className="little-spacer-right" | |||
key="+" | |||
> | |||
+ | |||
</span> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.switch_flows | |||
</td> | |||
</tr> | |||
<tr | |||
key="transition" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="f" | |||
> | |||
f | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.transition | |||
</td> | |||
</tr> | |||
<tr | |||
key="assign" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="a" | |||
> | |||
a | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.assign | |||
</td> | |||
</tr> | |||
<tr | |||
key="assign_to_me" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="m" | |||
> | |||
m | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.assign_to_me | |||
</td> | |||
</tr> | |||
<tr | |||
key="severity" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="i" | |||
> | |||
i | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.severity | |||
</td> | |||
</tr> | |||
<tr | |||
key="comment" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="c" | |||
> | |||
c | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.comment | |||
</td> | |||
</tr> | |||
<tr | |||
key="submit_comment" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="ctrl" | |||
> | |||
ctrl | |||
</code> | |||
<span | |||
className="little-spacer-right" | |||
key="+" | |||
> | |||
+ | |||
</span> | |||
<code | |||
className="little-spacer-right" | |||
key="enter" | |||
> | |||
enter | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.submit_comment | |||
</td> | |||
</tr> | |||
<tr | |||
key="tags" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="t" | |||
> | |||
t | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.issues_page.tags | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
<div | |||
className="flex-1 huge-spacer-left" | |||
> | |||
<div | |||
className="spacer-bottom" | |||
key="code_page" | |||
> | |||
<h3 | |||
className="null-spacer-top" | |||
> | |||
keyboard_shortcuts.code_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="select_files" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.code_page.select_files | |||
</td> | |||
</tr> | |||
<tr | |||
key="open_file" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.code_page.open_file | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.code_page.back | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-bottom" | |||
key="measures_page" | |||
> | |||
<h3 | |||
className="null-spacer-top" | |||
> | |||
keyboard_shortcuts.measures_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="select_files" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.measures_page.select_files | |||
</td> | |||
</tr> | |||
<tr | |||
key="open_file" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.measures_page.open_file | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.measures_page.back | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div | |||
className="spacer-bottom" | |||
key="rules_page" | |||
> | |||
<h3 | |||
className="null-spacer-top" | |||
> | |||
keyboard_shortcuts.rules_page.title | |||
</h3> | |||
<table> | |||
<thead> | |||
<tr> | |||
<th> | |||
keyboard_shortcuts.shortcut | |||
</th> | |||
<th> | |||
keyboard_shortcuts.action | |||
</th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<tr | |||
key="navigate" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="↑" | |||
> | |||
↑ | |||
</code> | |||
<code | |||
className="little-spacer-right" | |||
key="↓" | |||
> | |||
↓ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.rules_page.navigate | |||
</td> | |||
</tr> | |||
<tr | |||
key="rule_details" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="→" | |||
> | |||
→ | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.rules_page.rule_details | |||
</td> | |||
</tr> | |||
<tr | |||
key="back" | |||
> | |||
<td> | |||
<code | |||
className="little-spacer-right" | |||
key="←" | |||
> | |||
← | |||
</code> | |||
</td> | |||
<td> | |||
keyboard_shortcuts.rules_page.back | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="modal-foot" | |||
> | |||
<Button | |||
onClick={[Function]} | |||
> | |||
close | |||
</Button> | |||
</div> | |||
</Modal> | |||
`; |
@@ -1,14 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly if system is starting 1`] = ` | |||
<Navigate | |||
to={ | |||
{ | |||
"pathname": "/maintenance", | |||
"search": "return_to=%2Fprojects%3Fquery%3Dtoto%23hash", | |||
} | |||
} | |||
/> | |||
`; | |||
exports[`should render correctly if system is up 1`] = `<Outlet />`; |
@@ -1,18 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should not trigger if no analytics system is given 1`] = ` | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
prioritizeSeoTags={false} | |||
/> | |||
`; | |||
exports[`should work for WebAnalytics plugin 1`] = ` | |||
<Helmet | |||
defer={false} | |||
encodeSpecialCharacters={true} | |||
onChangeClientState={[Function]} | |||
prioritizeSeoTags={false} | |||
/> | |||
`; |
@@ -1,10 +0,0 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<main> | |||
<A11ySkipTarget | |||
anchor="admin_main" | |||
/> | |||
<Outlet /> | |||
</main> | |||
`; |