mirror of
https://github.com/ansible/awx.git
synced 2026-04-14 06:29:25 -02:30
flush out more type defs; JobDetail tests
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shape, string, bool } from 'prop-types';
|
import { shape } from 'prop-types';
|
||||||
import { toTitleCase } from '@util/strings';
|
import { toTitleCase } from '@util/strings';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import Chip from './Chip';
|
import Chip from './Chip';
|
||||||
|
import { Credential } from '../../types';
|
||||||
|
|
||||||
function CredentialChip ({ credential, i18n, ...props }) {
|
function CredentialChip ({ credential, i18n, ...props }) {
|
||||||
let type;
|
let type;
|
||||||
@@ -23,11 +24,7 @@ function CredentialChip ({ credential, i18n, ...props }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
CredentialChip.propTypes = {
|
CredentialChip.propTypes = {
|
||||||
credential: shape({
|
credential: Credential.isRequired,
|
||||||
cloud: bool,
|
|
||||||
kind: string,
|
|
||||||
name: string.isRequired,
|
|
||||||
}).isRequired,
|
|
||||||
i18n: shape({}).isRequired,
|
i18n: shape({}).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import CredentialChip from './CredentialChip';
|
|||||||
describe('CredentialChip', () => {
|
describe('CredentialChip', () => {
|
||||||
test('should render SSH kind', () => {
|
test('should render SSH kind', () => {
|
||||||
const credential = {
|
const credential = {
|
||||||
|
id: 1,
|
||||||
kind: 'ssh',
|
kind: 'ssh',
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
};
|
};
|
||||||
@@ -17,6 +18,7 @@ describe('CredentialChip', () => {
|
|||||||
|
|
||||||
test('should render AWS kind', () => {
|
test('should render AWS kind', () => {
|
||||||
const credential = {
|
const credential = {
|
||||||
|
id: 1,
|
||||||
kind: 'aws',
|
kind: 'aws',
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
};
|
};
|
||||||
@@ -29,6 +31,7 @@ describe('CredentialChip', () => {
|
|||||||
|
|
||||||
test('should render with "Cloud"', () => {
|
test('should render with "Cloud"', () => {
|
||||||
const credential = {
|
const credential = {
|
||||||
|
id: 1,
|
||||||
cloud: true,
|
cloud: true,
|
||||||
kind: 'other',
|
kind: 'other',
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
@@ -42,6 +45,7 @@ describe('CredentialChip', () => {
|
|||||||
|
|
||||||
test('should render with other kind', () => {
|
test('should render with other kind', () => {
|
||||||
const credential = {
|
const credential = {
|
||||||
|
id: 1,
|
||||||
kind: 'other',
|
kind: 'other',
|
||||||
name: 'foo',
|
name: 'foo',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shape } from 'prop-types';
|
|
||||||
import { Link, withRouter } from 'react-router-dom';
|
import { Link, withRouter } from 'react-router-dom';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
@@ -9,6 +8,7 @@ import { DetailList, Detail } from '@components/DetailList';
|
|||||||
import { ChipGroup, Chip, CredentialChip } from '@components/Chip';
|
import { ChipGroup, Chip, CredentialChip } from '@components/Chip';
|
||||||
import { VariablesInput } from '@components/CodeMirrorInput';
|
import { VariablesInput } from '@components/CodeMirrorInput';
|
||||||
import { toTitleCase } from '@util/strings';
|
import { toTitleCase } from '@util/strings';
|
||||||
|
import { Job } from '../../../types';
|
||||||
|
|
||||||
const ActionButtonWrapper = styled.div`
|
const ActionButtonWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -105,7 +105,7 @@ function JobDetail({ job, i18n }) {
|
|||||||
{labels && labels.count > 0 && (
|
{labels && labels.count > 0 && (
|
||||||
<Detail
|
<Detail
|
||||||
fullWidth
|
fullWidth
|
||||||
label={i18n._(t`Credentials`)}
|
label={i18n._(t`Labels`)}
|
||||||
value={
|
value={
|
||||||
<ChipGroup showOverflowAfter={5}>
|
<ChipGroup showOverflowAfter={5}>
|
||||||
{labels.results.map(l => (
|
{labels.results.map(l => (
|
||||||
@@ -150,7 +150,7 @@ function JobDetail({ job, i18n }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
JobDetail.propTypes = {
|
JobDetail.propTypes = {
|
||||||
job: shape({}).isRequired,
|
job: Job.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withI18n()(withRouter(JobDetail));
|
export default withI18n()(withRouter(JobDetail));
|
||||||
|
|||||||
@@ -1,22 +1,60 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
import { mountWithContexts } from '@testUtils/enzymeHelpers';
|
||||||
|
|
||||||
import JobDetail from './JobDetail';
|
import JobDetail from './JobDetail';
|
||||||
|
|
||||||
describe('<JobDetail />', () => {
|
describe('<JobDetail />', () => {
|
||||||
const mockDetails = {
|
let job;
|
||||||
name: 'Foo',
|
|
||||||
};
|
beforeEach(() => {
|
||||||
|
job = {
|
||||||
|
name: 'Foo',
|
||||||
|
summary_fields: {},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
test('initially renders succesfully', () => {
|
test('initially renders succesfully', () => {
|
||||||
mountWithContexts(<JobDetail job={mockDetails} />);
|
mountWithContexts(<JobDetail job={job} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should display a Close button', () => {
|
test('should display a Close button', () => {
|
||||||
const wrapper = mountWithContexts(<JobDetail job={mockDetails} />);
|
const wrapper = mountWithContexts(<JobDetail job={job} />);
|
||||||
|
|
||||||
expect(wrapper.find('Button[aria-label="close"]').length).toBe(1);
|
expect(wrapper.find('Button[aria-label="close"]').length).toBe(1);
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should display details', () => {
|
||||||
|
job.status = 'Successful';
|
||||||
|
job.started = '2019-07-02T17:35:22.753817Z';
|
||||||
|
job.finished = '2019-07-02T17:35:34.910800Z';
|
||||||
|
|
||||||
|
const wrapper = mountWithContexts(<JobDetail job={job} />);
|
||||||
|
const details = wrapper.find('Detail');
|
||||||
|
|
||||||
|
function assertDetail(detail, label, value) {
|
||||||
|
expect(detail.prop('label')).toEqual(label);
|
||||||
|
expect(detail.prop('value')).toEqual(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertDetail(details.at(0), 'Status', 'Successful');
|
||||||
|
assertDetail(details.at(1), 'Started', job.started);
|
||||||
|
assertDetail(details.at(2), 'Finished', job.finished);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should display credentials', () => {
|
||||||
|
job.summary_fields.credentials = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'Foo',
|
||||||
|
cloud: false,
|
||||||
|
kind: 'ssh',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const wrapper = mountWithContexts(<JobDetail job={job} />);
|
||||||
|
const credentialChip = wrapper.find('CredentialChip');
|
||||||
|
|
||||||
|
expect(credentialChip.prop('credential')).toEqual(
|
||||||
|
job.summary_fields.credentials[0]
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
9
awx/ui_next/src/screens/Job/constants.js
Normal file
9
awx/ui_next/src/screens/Job/constants.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* eslint-disable-next-line import/prefer-default-export */
|
||||||
|
export const JOB_TYPE_URLS = {
|
||||||
|
job: 'playbook',
|
||||||
|
project_update: 'project',
|
||||||
|
system_job: 'system',
|
||||||
|
inventory_update: 'inventory',
|
||||||
|
ad_hoc_command: 'command',
|
||||||
|
workflow_job: 'workflow',
|
||||||
|
};
|
||||||
@@ -65,8 +65,61 @@ export const QSConfig = shape({
|
|||||||
export const JobTemplate = shape({
|
export const JobTemplate = shape({
|
||||||
name: string.isRequired,
|
name: string.isRequired,
|
||||||
description: string,
|
description: string,
|
||||||
inventory: oneOfType([number, string]).isRequired,
|
inventory: number,
|
||||||
job_type: oneOf(['run', 'check']),
|
job_type: oneOf(['run', 'check']),
|
||||||
playbook: string.isRequired,
|
playbook: string,
|
||||||
project: oneOfType([number, string]).isRequired,
|
project: number,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Project = shape({
|
||||||
|
id: number.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Inventory = shape({
|
||||||
|
id: number.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InstanceGroup = shape({
|
||||||
|
id: number.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Label = shape({
|
||||||
|
id: number.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Credential = shape({
|
||||||
|
id: number.isRequired,
|
||||||
|
name: string.isRequired,
|
||||||
|
cloud: bool,
|
||||||
|
kind: string,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Job = shape({
|
||||||
|
status: string,
|
||||||
|
started: string,
|
||||||
|
finished: string,
|
||||||
|
job_type: string,
|
||||||
|
summary_fields: shape({
|
||||||
|
job_template: JobTemplate,
|
||||||
|
project: Project,
|
||||||
|
inventory: Inventory,
|
||||||
|
instance_group: InstanceGroup,
|
||||||
|
credentials: arrayOf(Credential),
|
||||||
|
labels: shape({
|
||||||
|
count: number,
|
||||||
|
results: arrayOf(Label),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
scm_revision: string,
|
||||||
|
limit: oneOfType([number, string]),
|
||||||
|
verbosity: number,
|
||||||
|
execution_mode: string,
|
||||||
|
job_slice_number: number,
|
||||||
|
job_slice_count: number,
|
||||||
|
extra_vars: string,
|
||||||
|
artifacts: shape({}),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user