From 75b54d2c14d97e601ac8784b159cab35f0039e98 Mon Sep 17 00:00:00 2001 From: Marliana Lara Date: Thu, 23 Apr 2020 15:34:23 -0400 Subject: [PATCH] Add unit tests to check for deleted details --- .../{MissingDetail.jsx => DeletedDetail.jsx} | 6 +-- .../src/components/DetailList/index.js | 2 +- .../PromptInventorySourceDetail.jsx | 4 +- .../PromptInventorySourceDetail.test.jsx | 32 ++++++++----- .../PromptDetail/PromptJobTemplateDetail.jsx | 8 ++-- .../PromptJobTemplateDetail.test.jsx | 48 ++++++++++++------- .../PromptDetail/PromptProjectDetail.jsx | 4 +- .../PromptDetail/PromptProjectDetail.test.jsx | 44 ++++++++++------- .../JobTemplateDetail/JobTemplateDetail.jsx | 8 ++-- 9 files changed, 94 insertions(+), 62 deletions(-) rename awx/ui_next/src/components/DetailList/{MissingDetail.jsx => DeletedDetail.jsx} (76%) diff --git a/awx/ui_next/src/components/DetailList/MissingDetail.jsx b/awx/ui_next/src/components/DetailList/DeletedDetail.jsx similarity index 76% rename from awx/ui_next/src/components/DetailList/MissingDetail.jsx rename to awx/ui_next/src/components/DetailList/DeletedDetail.jsx index 94572413a0..e71fc183bd 100644 --- a/awx/ui_next/src/components/DetailList/MissingDetail.jsx +++ b/awx/ui_next/src/components/DetailList/DeletedDetail.jsx @@ -11,12 +11,12 @@ const Detail = styled(_Detail)` } `; -function MissingDetail({ i18n, label }) { +function DeletedDetail({ i18n, label }) { return ; } -MissingDetail.propTypes = { +DeletedDetail.propTypes = { label: node.isRequired, }; -export default withI18n()(MissingDetail); +export default withI18n()(DeletedDetail); diff --git a/awx/ui_next/src/components/DetailList/index.js b/awx/ui_next/src/components/DetailList/index.js index 820f353bf1..8573f1a614 100644 --- a/awx/ui_next/src/components/DetailList/index.js +++ b/awx/ui_next/src/components/DetailList/index.js @@ -1,4 +1,4 @@ export { default as DetailList } from './DetailList'; export { default as Detail, DetailName, DetailValue } from './Detail'; -export { default as MissingDetail } from './MissingDetail'; +export { default as DeletedDetail } from './DeletedDetail'; export { default as UserDateDetail } from './UserDateDetail'; diff --git a/awx/ui_next/src/components/PromptDetail/PromptInventorySourceDetail.jsx b/awx/ui_next/src/components/PromptDetail/PromptInventorySourceDetail.jsx index 0b7b7c9243..f3ec46c003 100644 --- a/awx/ui_next/src/components/PromptDetail/PromptInventorySourceDetail.jsx +++ b/awx/ui_next/src/components/PromptDetail/PromptInventorySourceDetail.jsx @@ -4,7 +4,7 @@ import { t } from '@lingui/macro'; import { Link } from 'react-router-dom'; import { Chip, ChipGroup, List, ListItem } from '@patternfly/react-core'; -import { Detail, MissingDetail } from '@components/DetailList'; +import { Detail, DeletedDetail } from '@components/DetailList'; import { VariablesDetail } from '@components/CodeMirrorInput'; import CredentialChip from '@components/CredentialChip'; @@ -69,7 +69,7 @@ function PromptInventorySourceDetail({ i18n, resource }) { } /> ) : ( - + )} {summary_fields?.inventory && ( { let wrapper; @@ -21,18 +26,13 @@ describe('PromptInventorySourceDetail', () => { }); test('should render expected details', () => { - function assertDetail(label, value) { - expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); - expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); - } - - assertDetail('Inventory', 'Demo Inventory'); - assertDetail('Source', 'scm'); - assertDetail('Project', 'Mock Project'); - assertDetail('Inventory File', 'foo'); - assertDetail('Custom Inventory Script', 'Mock Script'); - assertDetail('Verbosity', '2 (More Verbose)'); - assertDetail('Cache Timeout', '2 Seconds'); + assertDetail(wrapper, 'Inventory', 'Demo Inventory'); + assertDetail(wrapper, 'Source', 'scm'); + assertDetail(wrapper, 'Project', 'Mock Project'); + assertDetail(wrapper, 'Inventory File', 'foo'); + assertDetail(wrapper, 'Custom Inventory Script', 'Mock Script'); + assertDetail(wrapper, 'Verbosity', '2 (More Verbose)'); + assertDetail(wrapper, 'Cache Timeout', '2 Seconds'); expect( wrapper .find('Detail[label="Regions"]') @@ -74,4 +74,12 @@ describe('PromptInventorySourceDetail', () => { ]) ).toEqual(true); }); + + test('should render "Deleted" details', () => { + delete mockInvSource.summary_fields.organization; + wrapper = mountWithContexts( + + ); + assertDetail(wrapper, 'Organization', 'Deleted'); + }); }); diff --git a/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.jsx b/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.jsx index 583381c755..d7502bb942 100644 --- a/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.jsx +++ b/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.jsx @@ -4,7 +4,7 @@ import { t } from '@lingui/macro'; import { Link } from 'react-router-dom'; import { Chip, ChipGroup, List, ListItem } from '@patternfly/react-core'; -import { Detail, MissingDetail } from '@components/DetailList'; +import { Detail, DeletedDetail } from '@components/DetailList'; import { VariablesDetail } from '@components/CodeMirrorInput'; import CredentialChip from '@components/CredentialChip'; import Sparkline from '@components/Sparkline'; @@ -97,7 +97,7 @@ function PromptJobTemplateDetail({ i18n, resource }) { } /> ) : ( - + )} {summary_fields?.inventory ? ( ) : ( !ask_inventory_on_launch && ( - + ) )} {summary_fields?.project ? ( @@ -125,7 +125,7 @@ function PromptJobTemplateDetail({ i18n, resource }) { } /> ) : ( - + )} diff --git a/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.test.jsx b/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.test.jsx index 30f92824ab..7a536f4b73 100644 --- a/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.test.jsx +++ b/awx/ui_next/src/components/PromptDetail/PromptJobTemplateDetail.test.jsx @@ -18,6 +18,11 @@ const mockJT = { ], }; +function assertDetail(wrapper, label, value) { + expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); + expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); +} + describe('PromptJobTemplateDetail', () => { let wrapper; @@ -34,24 +39,19 @@ describe('PromptJobTemplateDetail', () => { }); test('should render expected details', () => { - function assertDetail(label, value) { - expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); - expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); - } - - assertDetail('Job Type', 'Run'); - assertDetail('Inventory', 'Demo Inventory'); - assertDetail('Project', 'Mock Project'); - assertDetail('Source Control Branch', 'Foo branch'); - assertDetail('Playbook', 'ping.yml'); - assertDetail('Forks', '2'); - assertDetail('Limit', 'alpha:beta'); - assertDetail('Verbosity', '3 (Debug)'); - assertDetail('Show Changes', 'Off'); - assertDetail('Job Slicing', '1'); - assertDetail('Host Config Key', 'a1b2c3'); - assertDetail('Webhook Service', 'Github'); - assertDetail('Webhook Key', 'PiM3n2'); + assertDetail(wrapper, 'Job Type', 'Run'); + assertDetail(wrapper, 'Inventory', 'Demo Inventory'); + assertDetail(wrapper, 'Project', 'Mock Project'); + assertDetail(wrapper, 'Source Control Branch', 'Foo branch'); + assertDetail(wrapper, 'Playbook', 'ping.yml'); + assertDetail(wrapper, 'Forks', '2'); + assertDetail(wrapper, 'Limit', 'alpha:beta'); + assertDetail(wrapper, 'Verbosity', '3 (Debug)'); + assertDetail(wrapper, 'Show Changes', 'Off'); + assertDetail(wrapper, 'Job Slicing', '1'); + assertDetail(wrapper, 'Host Config Key', 'a1b2c3'); + assertDetail(wrapper, 'Webhook Service', 'Github'); + assertDetail(wrapper, 'Webhook Key', 'PiM3n2'); expect(wrapper.find('StatusIcon')).toHaveLength(2); expect(wrapper.find('Detail[label="Webhook URL"] dd').text()).toEqual( expect.stringContaining('/api/v2/job_templates/7/github/') @@ -112,4 +112,16 @@ describe('PromptJobTemplateDetail', () => { '---foo: bar' ); }); + + test('should render "Deleted" details', () => { + delete mockJT.summary_fields.inventory; + delete mockJT.summary_fields.organization; + delete mockJT.summary_fields.project; + + wrapper = mountWithContexts(); + + assertDetail(wrapper, 'Inventory', 'Deleted'); + assertDetail(wrapper, 'Organization', 'Deleted'); + assertDetail(wrapper, 'Project', 'Deleted'); + }); }); diff --git a/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.jsx b/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.jsx index fe44985bd3..b783631d14 100644 --- a/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.jsx +++ b/awx/ui_next/src/components/PromptDetail/PromptProjectDetail.jsx @@ -5,7 +5,7 @@ import { Config } from '@contexts/Config'; import { List, ListItem } from '@patternfly/react-core'; import { Link } from 'react-router-dom'; -import { Detail, MissingDetail } from '@components/DetailList'; +import { Detail, DeletedDetail } from '@components/DetailList'; import CredentialChip from '@components/CredentialChip'; import { toTitleCase } from '@util/strings'; @@ -62,7 +62,7 @@ function PromptProjectDetail({ i18n, resource }) { } /> ) : ( - + )} { let wrapper; + const config = { + project_base_dir: 'dir/foo/bar', + }; beforeAll(() => { - const config = { - project_base_dir: 'dir/foo/bar', - }; wrapper = mountWithContexts( , { @@ -27,23 +32,19 @@ describe('PromptProjectDetail', () => { }); test('should render expected details', () => { - function assertDetail(label, value) { - expect(wrapper.find(`Detail[label="${label}"] dt`).text()).toBe(label); - expect(wrapper.find(`Detail[label="${label}"] dd`).text()).toBe(value); - } - - assertDetail('Source Control Type', 'Git'); + assertDetail(wrapper, 'Source Control Type', 'Git'); assertDetail( + wrapper, 'Source Control URL', 'https://github.com/ansible/ansible-tower-samples' ); - assertDetail('Source Control Branch', 'foo'); - assertDetail('Source Control Refspec', 'refs/'); - assertDetail('Cache Timeout', '3 Seconds'); - assertDetail('Ansible Environment', 'mock virtual env'); - assertDetail('Project Base Path', 'dir/foo/bar'); - assertDetail('Playbook Directory', '_6__demo_project'); - assertDetail('Source Control Credential', 'Scm: mock scm'); + assertDetail(wrapper, 'Source Control Branch', 'foo'); + assertDetail(wrapper, 'Source Control Refspec', 'refs/'); + assertDetail(wrapper, 'Cache Timeout', '3 Seconds'); + assertDetail(wrapper, 'Ansible Environment', 'mock virtual env'); + assertDetail(wrapper, 'Project Base Path', 'dir/foo/bar'); + assertDetail(wrapper, 'Playbook Directory', '_6__demo_project'); + assertDetail(wrapper, 'Source Control Credential', 'Scm: mock scm'); expect( wrapper .find('Detail[label="Options"]') @@ -55,4 +56,15 @@ describe('PromptProjectDetail', () => { ]) ).toEqual(true); }); + + test('should render "Deleted" details', () => { + delete mockProject.summary_fields.organization; + wrapper = mountWithContexts( + , + { + context: { config }, + } + ); + assertDetail(wrapper, 'Organization', 'Deleted'); + }); }); diff --git a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx index abdaeeae14..303e82a5c6 100644 --- a/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx +++ b/awx/ui_next/src/screens/Template/JobTemplateDetail/JobTemplateDetail.jsx @@ -20,7 +20,7 @@ import CredentialChip from '@components/CredentialChip'; import { Detail, DetailList, - MissingDetail, + DeletedDetail, UserDateDetail, } from '@components/DetailList'; import DeleteButton from '@components/DeleteButton'; @@ -174,7 +174,7 @@ function JobTemplateDetail({ i18n, template }) { } /> ) : ( - + )} {summary_fields.inventory ? ( ) : ( !ask_inventory_on_launch && ( - + ) )} {summary_fields.project ? ( @@ -199,7 +199,7 @@ function JobTemplateDetail({ i18n, template }) { } /> ) : ( - + )}