-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(system-jobs): enforce system job permissions
- Loading branch information
ismay
committed
Feb 22, 2021
1 parent
0eff8c2
commit 1bae8c7
Showing
12 changed files
with
264 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react' | ||
import { PropTypes } from '@dhis2/prop-types' | ||
import { MenuItem } from '@dhis2/ui' | ||
import i18n from '@dhis2/d2-i18n' | ||
import history from '../../services/history' | ||
|
||
const ViewJobAction = ({ id }) => ( | ||
<MenuItem | ||
dense | ||
onClick={() => history.push(`/view/${id}`)} | ||
label={i18n.t('View')} | ||
/> | ||
) | ||
|
||
const { string } = PropTypes | ||
|
||
ViewJobAction.propTypes = { | ||
id: string.isRequired, | ||
} | ||
|
||
export default ViewJobAction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react' | ||
import { shallow, mount } from 'enzyme' | ||
import history from '../../services/history' | ||
import ViewJobAction from './ViewJobAction' | ||
|
||
jest.mock('../../services/history', () => ({ | ||
push: jest.fn(), | ||
})) | ||
|
||
describe('<ViewJobAction>', () => { | ||
it('renders without errors', () => { | ||
shallow(<ViewJobAction id="id" />) | ||
}) | ||
|
||
it('calls history.push correctly when MenuItem is clicked', () => { | ||
const wrapper = mount(<ViewJobAction id="id" />) | ||
|
||
wrapper.find('a').simulate('click') | ||
|
||
expect(history.push).toHaveBeenCalledWith('/view/id') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React, { useContext } from 'react' | ||
import { useParams } from 'react-router-dom' | ||
import { | ||
Card, | ||
IconInfo16, | ||
Box, | ||
SingleSelectField, | ||
SingleSelectOption, | ||
InputField, | ||
} from '@dhis2/ui' | ||
import i18n from '@dhis2/d2-i18n' | ||
import { StoreContext, selectors } from '../../components/Store' | ||
import { DiscardFormButton } from '../../components/Buttons' | ||
import { JobDetails } from '../../components/JobDetails' | ||
import translateCron from '../../services/translate-cron' | ||
import { jobTypesMap } from '../../services/server-translations' | ||
import styles from './JobView.module.css' | ||
|
||
const infoLink = | ||
'https://docs.dhis2.org/master/en/user/html/dataAdmin_scheduling.html#dataAdmin_scheduling_config' | ||
|
||
const JobView = () => { | ||
const store = useContext(StoreContext) | ||
const { id } = useParams() | ||
const { | ||
name, | ||
created, | ||
lastExecutedStatus, | ||
lastExecuted, | ||
jobType, | ||
cronExpression, | ||
} = selectors.getJobById(store, id) | ||
|
||
return ( | ||
<React.Fragment> | ||
<header className={styles.pageHeader}> | ||
<DiscardFormButton className={styles.pageHeaderButton} small> | ||
{i18n.t('Back to all jobs')} | ||
</DiscardFormButton> | ||
<h2 className={styles.pageHeaderTitle}> | ||
{i18n.t('System job: {{ name }}', { | ||
name, | ||
nsSeparator: '>', | ||
})} | ||
</h2> | ||
</header> | ||
<Card className={styles.card}> | ||
<header className={styles.cardHeader}> | ||
<h3 className={styles.cardHeaderTitle}> | ||
{i18n.t('Configuration')} | ||
</h3> | ||
<a | ||
href={infoLink} | ||
className={styles.cardHeaderLink} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
<span className={styles.cardHeaderInfo}> | ||
<IconInfo16 /> | ||
</span> | ||
{i18n.t('About job configuration')} | ||
</a> | ||
</header> | ||
<div className={styles.jobDetails}> | ||
<JobDetails | ||
created={created} | ||
lastExecutedStatus={lastExecutedStatus} | ||
lastExecuted={lastExecuted} | ||
/> | ||
</div> | ||
<Box maxWidth="600px"> | ||
<InputField label={i18n.t('Name')} disabled value={name} /> | ||
</Box> | ||
<Box marginTop="16px" maxWidth="400px"> | ||
<SingleSelectField | ||
label={i18n.t('Job type')} | ||
disabled | ||
selected={jobType} | ||
> | ||
<SingleSelectOption | ||
value={jobType} | ||
label={jobTypesMap[jobType]} | ||
/> | ||
</SingleSelectField> | ||
</Box> | ||
<Box marginTop="16px" maxWidth="400px"> | ||
<InputField | ||
label={i18n.t('CRON Expression')} | ||
disabled | ||
value={cronExpression} | ||
helpText={translateCron(cronExpression)} | ||
/> | ||
</Box> | ||
<Box marginTop="24px"> | ||
<DiscardFormButton> | ||
{i18n.t('Back to all jobs')} | ||
</DiscardFormButton> | ||
</Box> | ||
</Card> | ||
</React.Fragment> | ||
) | ||
} | ||
|
||
export default JobView |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
.pageHeader { | ||
margin-bottom: var(--spacers-dp32); | ||
} | ||
|
||
.pageHeaderButton { | ||
margin-bottom: var(--spacers-dp16); | ||
} | ||
|
||
.pageHeaderTitle { | ||
font-size: 18px; | ||
font-weight: 400; | ||
line-height: 1; | ||
margin: 0; | ||
} | ||
|
||
.card { | ||
padding: var(--spacers-dp16); | ||
} | ||
|
||
.cardHeader { | ||
align-items: center; | ||
display: inline-flex; | ||
margin-bottom: var(--spacers-dp16); | ||
} | ||
|
||
.cardHeaderTitle { | ||
font-size: 16px; | ||
font-weight: 500; | ||
margin: 0 var(--spacers-dp8) 0 0; | ||
} | ||
|
||
.cardHeaderInfo { | ||
margin-right: var(--spacers-dp4); | ||
} | ||
|
||
.cardHeaderLink { | ||
align-items: center; | ||
display: flex; | ||
font-size: 12px; | ||
color: var(--colors-grey600); | ||
fill: var(--colors-grey600); | ||
} | ||
|
||
.jobDetails { | ||
float: right; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React from 'react' | ||
import { useParams } from 'react-router-dom' | ||
import { shallow } from 'enzyme' | ||
import { StoreContext } from '../../components/Store' | ||
import JobView from './JobView' | ||
|
||
jest.mock('react-router-dom', () => ({ | ||
useParams: jest.fn(), | ||
})) | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks() | ||
}) | ||
|
||
describe('<JobView>', () => { | ||
it('renders without errors', () => { | ||
const id = 'one' | ||
const store = { | ||
jobs: [ | ||
{ | ||
id, | ||
jobType: 'DATA_SET_NOTIFICATION', | ||
cronExpression: '0 0 2 * * ?', | ||
name: 'name', | ||
created: 'now', | ||
lastExecutedStatus: 'COMPLETED', | ||
lastExecuted: 'now', | ||
}, | ||
], | ||
} | ||
|
||
useParams.mockImplementation(() => id) | ||
|
||
shallow( | ||
<StoreContext.Provider value={store}> | ||
<JobView /> | ||
</StoreContext.Provider> | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import JobView from './JobView' | ||
|
||
export { JobView } |