Skip to content
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

Update usage of summary_fields for execution environments #8217

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import { t } from '@lingui/macro';
import AlertModal from '../AlertModal';
import { KebabifiedContext } from '../../contexts/Kebabified';

const requireNameOrUsername = props => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EE does not have the name field. That is why I decided to rename this function.

const { name, username } = props;
if (!name && !username) {
const requiredField = props => {
const { name, username, image } = props;
if (!name && !username && !image) {
return new Error(
`One of 'name' or 'username' is required by ItemToDelete component.`
`One of 'name', 'username' or 'image' is required by ItemToDelete component.`
);
}
if (name) {
Expand All @@ -41,13 +41,24 @@ const requireNameOrUsername = props => {
'ItemToDelete'
);
}
if (image) {
checkPropTypes(
{
image: string,
},
{ image: props.image },
'prop',
'ItemToDelete'
);
}
return null;
};

const ItemToDelete = shape({
id: number.isRequired,
name: requireNameOrUsername,
username: requireNameOrUsername,
name: requiredField,
username: requiredField,
image: requiredField,
summary_fields: shape({
user_capabilities: shape({
delete: bool.isRequired,
Expand All @@ -56,7 +67,7 @@ const ItemToDelete = shape({
});

function cannotDelete(item) {
return !item.summary_fields?.user_capabilities?.delete;
return !item.summary_fields.user_capabilities.delete;
}

function ToolbarDeleteButton({
Expand Down Expand Up @@ -167,7 +178,7 @@ function ToolbarDeleteButton({
<div>{i18n._(t`This action will delete the following:`)}</div>
{itemsToDelete.map(item => (
<span key={item.id}>
<strong>{item.name || item.username}</strong>
<strong>{item.name || item.username || item.image}</strong>
<br />
</span>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ const executionEnvironments = {
organization: null,
credential: null,
url: '/api/v2/execution_environments/1/',
summary_fields: { user_capabilities: { edit: true, delete: true } },
},
{
id: 2,
image: 'https://registry.com/r/image2/manifest',
organization: null,
credential: null,
url: '/api/v2/execution_environments/2/',
summary_fields: { user_capabilities: { edit: false, delete: true } },
},
],
count: 2,
Expand Down Expand Up @@ -67,6 +69,81 @@ describe('<ExecutionEnvironmentList/>', () => {
expect(ExecutionEnvironmentsAPI.readOptions).toBeCalled();
});

test('should delete item successfully', async () => {
ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments);
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options);

await act(async () => {
wrapper = mountWithContexts(<ExecutionEnvironmentList />);
});
await waitForElement(
wrapper,
'ExecutionEnvironmentList',
el => el.length > 0
);

wrapper
.find('input#select-execution-environment-1')
.simulate('change', executionEnvironments.data.results[0]);
wrapper.update();

expect(
wrapper.find('input#select-execution-environment-1').prop('checked')
).toBe(true);

await act(async () => {
wrapper.find('Button[aria-label="Delete"]').prop('onClick')();
});
wrapper.update();

await act(async () => {
wrapper.find('Button[aria-label="confirm delete"]').prop('onClick')();
});

expect(ExecutionEnvironmentsAPI.destroy).toBeCalledWith(
executionEnvironments.data.results[0].id
);
});

test('should render deletion error modal', async () => {
ExecutionEnvironmentsAPI.destroy.mockRejectedValue(
new Error({
response: {
config: {
method: 'DELETE',
url: '/api/v2/execution_environments',
},
data: 'An error occurred',
},
})
);
ExecutionEnvironmentsAPI.read.mockResolvedValue(executionEnvironments);
ExecutionEnvironmentsAPI.readOptions.mockResolvedValue(options);
await act(async () => {
wrapper = mountWithContexts(<ExecutionEnvironmentList />);
});
waitForElement(wrapper, 'ExecutionEnvironmentList', el => el.length > 0);

wrapper
.find('input#select-execution-environment-1')
.simulate('change', 'a');
wrapper.update();
expect(
wrapper.find('input#select-execution-environment-1').prop('checked')
).toBe(true);

await act(async () =>
wrapper.find('Button[aria-label="Delete"]').prop('onClick')()
);
wrapper.update();

await act(async () =>
wrapper.find('Button[aria-label="confirm delete"]').prop('onClick')()
);
wrapper.update();
expect(wrapper.find('ErrorDetail').length).toBe(1);
});

test('should thrown content error', async () => {
ExecutionEnvironmentsAPI.read.mockRejectedValue(
new Error({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('<ExecutionEnvironmentForm/>', () => {
});

test('should display form fields properly', () => {
expect(wrapper.find('FormGroup[label="Image"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="Image name"]').length).toBe(1);
expect(wrapper.find('FormGroup[label="Description"]').length).toBe(1);
expect(wrapper.find('CredentialLookup').length).toBe(1);
});
Expand Down