store: implement compose start action/reducer
When a compose is started the api call is no longer handled by the CreateImageWizard onSave function. Instead, the CreateImageWizard calls the composeStart thunk. This function calls the api and handles the response. If successful, the compose is added to the store. Otherwise, an error is added to the store. The store's compose object now has a list of the compose ids and an object containing key/value pairs mapping a compose id to the compose for all composes. This "normalized" state will allow more efficiency when selecting individual composes or iterating through all composes. The compose objects in the store now match the composeRequest object instead of having a shape unique to the UI. This can be changed in the future if image-builder's api returns compose objects of a different format. Tests are updated for new compose format and action/reducer types.
This commit is contained in:
parent
8a8a7229a1
commit
f3eed9c28f
8 changed files with 379 additions and 166 deletions
|
|
@ -16,7 +16,6 @@ import WizardStepRegistration from './WizardStepRegistration';
|
|||
import WizardStepReview from './WizardStepReview';
|
||||
import ImageWizardFooter from './ImageWizardFooter';
|
||||
|
||||
import api from './../../api.js';
|
||||
import './CreateImageWizard.scss';
|
||||
|
||||
class CreateImageWizard extends Component {
|
||||
|
|
@ -36,7 +35,6 @@ class CreateImageWizard extends Component {
|
|||
uploadGoogleErrors: {},
|
||||
isSaveInProgress: false,
|
||||
isValidSubscription: true,
|
||||
onSaveError: null,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -114,9 +112,7 @@ class CreateImageWizard extends Component {
|
|||
}
|
||||
|
||||
onSave() {
|
||||
this.setState({
|
||||
isSaveInProgress: true,
|
||||
});
|
||||
this.setState({ isSaveInProgress: true });
|
||||
|
||||
let customizations = {
|
||||
packages: this.props.selectedPackages,
|
||||
|
|
@ -206,41 +202,21 @@ class CreateImageWizard extends Component {
|
|||
customizations,
|
||||
};
|
||||
requests.push(request);
|
||||
|
||||
}
|
||||
|
||||
const composeRequests = [];
|
||||
requests.forEach(request => {
|
||||
const composeRequest = api.composeImage(request).then(response => {
|
||||
let compose = {};
|
||||
compose[response.id] = {
|
||||
image_status: {
|
||||
status: 'pending',
|
||||
},
|
||||
distribution: request.distribution,
|
||||
architecture: request.image_requests[0].architecture,
|
||||
image_type: request.image_requests[0].image_type,
|
||||
upload_type: request.image_requests[0].upload_request.type,
|
||||
};
|
||||
this.props.composeUpdated(compose);
|
||||
});
|
||||
composeRequests.push(composeRequest);
|
||||
});
|
||||
const composeRequests = requests.map(request => this.props.composeStart(request));
|
||||
|
||||
Promise.all(composeRequests)
|
||||
.then(() => {
|
||||
this.props.addNotification({
|
||||
variant: 'success',
|
||||
title: 'Your image is being created',
|
||||
});
|
||||
this.props.history.push('/landing');
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('ERR', err);
|
||||
this.setState({ isSaveInProgress: false });
|
||||
if (err.response.status === 500) {
|
||||
this.setState({ onSaveError: 'Error: Something went wrong serverside' });
|
||||
if (!this.props.composesError) {
|
||||
this.props.addNotification({
|
||||
variant: 'success',
|
||||
title: 'Your image is being created',
|
||||
});
|
||||
this.props.history.push('/landing');
|
||||
}
|
||||
|
||||
this.setState({ isSaveInProgress: false });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -326,7 +302,7 @@ class CreateImageWizard extends Component {
|
|||
isValidUploadDestination={ isValidUploadDestination }
|
||||
isSaveInProgress={ this.state.isSaveInProgress }
|
||||
isValidSubscription={ this.state.isValidSubscription }
|
||||
error={ this.state.onSaveError } /> }
|
||||
error={ this.props.composesError } /> }
|
||||
isOpen />
|
||||
</React.Fragment>
|
||||
);
|
||||
|
|
@ -335,6 +311,7 @@ class CreateImageWizard extends Component {
|
|||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
composesError: state.composes.error,
|
||||
release: state.pendingCompose.release,
|
||||
uploadDestinations: state.pendingCompose.uploadDestinations,
|
||||
uploadAWS: state.pendingCompose.uploadAWS,
|
||||
|
|
@ -349,12 +326,15 @@ function mapStateToProps(state) {
|
|||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
composeUpdated: (compose) => dispatch(actions.composeUpdated(compose)),
|
||||
composeStart: (composeRequest) => dispatch(actions.composeStart(composeRequest)),
|
||||
addNotification: (not) => dispatch(addNotification(not)),
|
||||
};
|
||||
}
|
||||
|
||||
CreateImageWizard.propTypes = {
|
||||
composesError: PropTypes.string,
|
||||
composeUpdated: PropTypes.func,
|
||||
composeStart: PropTypes.func,
|
||||
addNotification: PropTypes.func,
|
||||
history: PropTypes.object,
|
||||
release: PropTypes.object,
|
||||
|
|
|
|||
|
|
@ -52,15 +52,14 @@ class ImagesTable extends Component {
|
|||
|
||||
pollComposeStatuses() {
|
||||
let { composeUpdated, composes } = this.props;
|
||||
Object.entries(composes).map(([ id, compose ]) => {
|
||||
Object.entries(composes.byId).map(([ id, compose ]) => {
|
||||
/* Skip composes that have been complete */
|
||||
if (compose.image_status.status === 'success' || compose.image_status.status === 'failure') {
|
||||
return;
|
||||
}
|
||||
|
||||
api.getComposeStatus(id).then(response => {
|
||||
let newCompose = {};
|
||||
newCompose[id] = Object.assign({}, compose, { image_status: response.image_status });
|
||||
const newCompose = Object.assign({}, compose, { image_status: response.image_status });
|
||||
composeUpdated(newCompose);
|
||||
});
|
||||
});
|
||||
|
|
@ -68,11 +67,11 @@ class ImagesTable extends Component {
|
|||
|
||||
render() {
|
||||
let { composes } = this.props;
|
||||
const rows = Object.entries(composes).map(([ id, compose ]) => {
|
||||
const rows = Object.entries(composes.byId).map(([ id, compose ]) => {
|
||||
return {
|
||||
cells: [
|
||||
id,
|
||||
{ title: <Upload uploadType={ compose.upload_type } /> },
|
||||
{ title: <Upload uploadType={ compose.image_requests[0].image_type } /> },
|
||||
{ title: <Release release={ compose.distribution } /> },
|
||||
{ title: <ImageBuildStatus status={ compose.image_status.status } /> },
|
||||
''
|
||||
|
|
@ -81,7 +80,7 @@ class ImagesTable extends Component {
|
|||
});
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ Object.keys(composes).length === 0 && (
|
||||
{ composes.allIds.length === 0 && (
|
||||
<EmptyState variant={ EmptyStateVariant.large } data-testid="empty-state">
|
||||
<EmptyStateIcon icon={ PlusCircleIcon } />
|
||||
<Title headingLevel="h4" size="lg">
|
||||
|
|
|
|||
|
|
@ -1,12 +1,40 @@
|
|||
import api from '../../api';
|
||||
import types from '../types';
|
||||
|
||||
function composeUpdated(compose) {
|
||||
return {
|
||||
type: types.COMPOSE_UPDATED,
|
||||
compose
|
||||
payload: { compose },
|
||||
};
|
||||
}
|
||||
|
||||
export const composeFailed = (error) => ({
|
||||
type: types.COMPOSE_FAILED,
|
||||
payload: { error }
|
||||
});
|
||||
|
||||
export const composeAdded = (compose) => ({
|
||||
type: types.COMPOSE_ADDED,
|
||||
payload: { compose },
|
||||
});
|
||||
|
||||
export const composeStart = (composeRequest) => async dispatch => {
|
||||
// response will be of the format {id: ''}
|
||||
const request = api.composeImage(composeRequest);
|
||||
return request.then(response => {
|
||||
// add the compose id to the composeRequest object to provide access to the
|
||||
// id if iterating through composes and add an image status of 'pending'.
|
||||
const compose = Object.assign({}, composeRequest, response, { image_status: { status: 'pending' }});
|
||||
dispatch(composeAdded(compose));
|
||||
}).catch(err => {
|
||||
if (err.response.status === 500) {
|
||||
dispatch(composeFailed('Error: Something went wrong serverside'));
|
||||
} else {
|
||||
dispatch(composeFailed('Error: Something went wrong with the compose'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function setRelease({ arch, distro }) {
|
||||
return {
|
||||
type: types.SET_RELEASE,
|
||||
|
|
@ -84,6 +112,7 @@ function setSubscribeNow(subscribeNow) {
|
|||
}
|
||||
|
||||
export default {
|
||||
composeStart,
|
||||
composeUpdated,
|
||||
setRelease,
|
||||
setUploadDestinations,
|
||||
|
|
|
|||
|
|
@ -3,19 +3,63 @@ import types from '../types';
|
|||
// Example of action.compose
|
||||
// {
|
||||
// "77e4c693-0497-4b85-936d-b2a3ad69571b": {
|
||||
// id: "77e4c693-0497-4b85-936d-b2a3ad69571b",
|
||||
// distribution: "rhel-8",
|
||||
// image_requests: [
|
||||
// {
|
||||
// architecture: "x86_64",
|
||||
// image_type: "ami",
|
||||
// upload_request: {
|
||||
// type: "aws",
|
||||
// options: {}
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// image_status: {
|
||||
// status: "uploading",
|
||||
// },
|
||||
// distribution: "rhel-8",
|
||||
// architecture: "x86_64",
|
||||
// image_type: "ami"
|
||||
// }
|
||||
// };
|
||||
|
||||
export function composes(state = { }, action) {
|
||||
const initialComposesState = {
|
||||
allIds: [],
|
||||
byId: {},
|
||||
error: null,
|
||||
};
|
||||
|
||||
export function composes(state = initialComposesState, action) {
|
||||
switch (action.type) {
|
||||
case types.COMPOSE_ADDED:
|
||||
return {
|
||||
...state,
|
||||
allIds: [
|
||||
...state.allIds,
|
||||
action.payload.compose.id
|
||||
],
|
||||
byId: {
|
||||
...state.byId,
|
||||
[action.payload.compose.id]: action.payload.compose,
|
||||
},
|
||||
error: null,
|
||||
};
|
||||
case types.COMPOSE_FAILED:
|
||||
return {
|
||||
...state,
|
||||
error: action.payload.error,
|
||||
};
|
||||
case types.COMPOSE_PENDING:
|
||||
return {
|
||||
...state,
|
||||
error: null,
|
||||
};
|
||||
case types.COMPOSE_UPDATED:
|
||||
return Object.assign({}, state, action.compose);
|
||||
return {
|
||||
...state,
|
||||
byId: {
|
||||
...state.byId,
|
||||
[action.payload.compose.id]: action.payload.compose,
|
||||
}
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
const COMPOSE_ADDED = 'COMPOSE_ADDED';
|
||||
const COMPOSE_FAILED = 'COMPOSE_FAILED';
|
||||
const COMPOSE_UPDATED = 'COMPOSE_UPDATED';
|
||||
const SET_RELEASE = 'SET_RELEASE';
|
||||
const SET_UPLOAD_DESTINATIONS = 'SET_UPLOAD_DESTINATIONS';
|
||||
|
|
@ -9,6 +11,8 @@ const SET_SUBSCRIPTION = 'SET_SUBSCRIPTION';
|
|||
const SET_SUBSCRIBE_NOW = 'SET_SUBSCRIBE_NOW';
|
||||
|
||||
export default {
|
||||
COMPOSE_ADDED,
|
||||
COMPOSE_FAILED,
|
||||
COMPOSE_UPDATED,
|
||||
SET_RELEASE,
|
||||
SET_UPLOAD_DESTINATIONS,
|
||||
|
|
|
|||
|
|
@ -8,119 +8,214 @@ import '@testing-library/jest-dom';
|
|||
|
||||
const store = {
|
||||
composes: {
|
||||
// kept "running" for backward compatibility
|
||||
'c1cfa347-4c37-49b5-8e73-6aa1d1746cfa': {
|
||||
image_status: {
|
||||
status: 'running',
|
||||
errors: null,
|
||||
allIds: [
|
||||
'c1cfa347-4c37-49b5-8e73-6aa1d1746cfa',
|
||||
'edbae1c2-62bc-42c1-ae0c-3110ab718f58',
|
||||
'42ad0826-30b5-4f64-a24e-957df26fd564',
|
||||
'955944a2-e149-4058-8ac1-35b514cb5a16',
|
||||
'f7a60094-b376-4b58-a102-5c8c82dfd18b',
|
||||
'1579d95b-8f1d-4982-8c53-8c2afa4ab04c',
|
||||
'61b0effa-c901-4ee5-86b9-2010b47f1b22',
|
||||
'ca03f120-9840-4959-871e-94a5cb49d1f2',
|
||||
'551de6f6-1533-4b46-a69f-7924051f9bc6',
|
||||
'77fa8b03-7efb-4120-9a20-da66d68c4494',
|
||||
],
|
||||
byId: {
|
||||
// kept "running" for backward compatibility
|
||||
'c1cfa347-4c37-49b5-8e73-6aa1d1746cfa': {
|
||||
id: 'c1cfa347-4c37-49b5-8e73-6aa1d1746cfa',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'running',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_type: 'aws',
|
||||
},
|
||||
'edbae1c2-62bc-42c1-ae0c-3110ab718f58': {
|
||||
image_status: {
|
||||
status: 'pending',
|
||||
'edbae1c2-62bc-42c1-ae0c-3110ab718f58': {
|
||||
id: 'edbae1c2-62bc-42c1-ae0c-3110ab718f58',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'pending',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_type: 'aws',
|
||||
},
|
||||
'42ad0826-30b5-4f64-a24e-957df26fd564': {
|
||||
image_status: {
|
||||
status: 'building',
|
||||
'42ad0826-30b5-4f64-a24e-957df26fd564': {
|
||||
id: '42ad0826-30b5-4f64-a24e-957df26fd564',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'building',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_type: 'aws',
|
||||
},
|
||||
'955944a2-e149-4058-8ac1-35b514cb5a16': {
|
||||
image_status: {
|
||||
status: 'uploading',
|
||||
'955944a2-e149-4058-8ac1-35b514cb5a16': {
|
||||
id: '955944a2-e149-4058-8ac1-35b514cb5a16',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'uploading',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_type: 'aws',
|
||||
},
|
||||
'f7a60094-b376-4b58-a102-5c8c82dfd18b': {
|
||||
image_status: {
|
||||
status: 'registering',
|
||||
'f7a60094-b376-4b58-a102-5c8c82dfd18b': {
|
||||
id: 'f7a60094-b376-4b58-a102-5c8c82dfd18b',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'registering',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_type: 'aws',
|
||||
},
|
||||
'1579d95b-8f1d-4982-8c53-8c2afa4ab04c': {
|
||||
image_status: {
|
||||
status: 'success',
|
||||
upload_status: {
|
||||
options: {
|
||||
ami: 'ami-0217b81d9be50e44b',
|
||||
region: 'us-east-1'
|
||||
},
|
||||
'1579d95b-8f1d-4982-8c53-8c2afa4ab04c': {
|
||||
id: '1579d95b-8f1d-4982-8c53-8c2afa4ab04c',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'success',
|
||||
type: 'aws'
|
||||
}
|
||||
upload_status: {
|
||||
options: {
|
||||
ami: 'ami-0217b81d9be50e44b',
|
||||
region: 'us-east-1'
|
||||
},
|
||||
status: 'success',
|
||||
type: 'aws'
|
||||
}
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_type: 'aws',
|
||||
},
|
||||
'61b0effa-c901-4ee5-86b9-2010b47f1b22': {
|
||||
image_status: {
|
||||
status: 'failure',
|
||||
'61b0effa-c901-4ee5-86b9-2010b47f1b22': {
|
||||
id: '61b0effa-c901-4ee5-86b9-2010b47f1b22',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'failure',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_type: 'gcp',
|
||||
},
|
||||
'ca03f120-9840-4959-871e-94a5cb49d1f2': {
|
||||
image_status: {
|
||||
status: 'success',
|
||||
upload_status: {
|
||||
options: {
|
||||
image_name: 'composer-api-d446d8cb-7c16-4756-bf7d-706293785b05',
|
||||
project_id: 'red-hat-image-builder'
|
||||
},
|
||||
'ca03f120-9840-4959-871e-94a5cb49d1f2': {
|
||||
id: 'ca03f120-9840-4959-871e-94a5cb49d1f2',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_request: {
|
||||
type: 'gcp',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'success',
|
||||
type: 'gcp'
|
||||
}
|
||||
upload_status: {
|
||||
options: {
|
||||
image_name: 'composer-api-d446d8cb-7c16-4756-bf7d-706293785b05',
|
||||
project_id: 'red-hat-image-builder'
|
||||
},
|
||||
status: 'success',
|
||||
type: 'gcp'
|
||||
}
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_type: 'gcp',
|
||||
},
|
||||
'551de6f6-1533-4b46-a69f-7924051f9bc6': {
|
||||
image_status: {
|
||||
status: 'building',
|
||||
'551de6f6-1533-4b46-a69f-7924051f9bc6': {
|
||||
id: '551de6f6-1533-4b46-a69f-7924051f9bc6',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_request: {
|
||||
type: 'azure',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'building',
|
||||
},
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_type: 'azure',
|
||||
},
|
||||
'77fa8b03-7efb-4120-9a20-da66d68c4494': {
|
||||
image_status: {
|
||||
status: 'success',
|
||||
upload_status: {
|
||||
options: {
|
||||
image_name: 'composer-api-cc5920c3-5451-4282-aab3-725d3df7f1cb'
|
||||
},
|
||||
'77fa8b03-7efb-4120-9a20-da66d68c4494': {
|
||||
id: '77fa8b03-7efb-4120-9a20-da66d68c4494',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_request: {
|
||||
type: 'azure',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'success',
|
||||
type: 'azure'
|
||||
}
|
||||
},
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'vhd',
|
||||
upload_type: 'azure',
|
||||
upload_status: {
|
||||
options: {
|
||||
image_name: 'composer-api-cc5920c3-5451-4282-aab3-725d3df7f1cb'
|
||||
},
|
||||
status: 'success',
|
||||
type: 'azure'
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -146,7 +241,7 @@ describe('Images Table', () => {
|
|||
if (col1 === 'Image') // skip header
|
||||
{continue;}
|
||||
|
||||
const compose = store.composes[col1];
|
||||
const compose = store.composes.byId[col1];
|
||||
expect(compose).toBeTruthy();
|
||||
|
||||
// render the expected <ImageBuildStatus /> and compare the text content
|
||||
|
|
@ -155,7 +250,7 @@ describe('Images Table', () => {
|
|||
expect(row.cells[3]).toHaveTextContent(testElement.textContent);
|
||||
|
||||
// do the same for the upload/target column
|
||||
render(<Upload uploadType={ compose.upload_type } />, { container: testElement });
|
||||
render(<Upload uploadType={ compose.image_requests[0].image_type } />, { container: testElement });
|
||||
expect(row.cells[1]).toHaveTextContent(testElement.textContent);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,10 +3,21 @@ import types from '../../../store/types';
|
|||
|
||||
const compose = {
|
||||
'77e4c693-0497-4b85-936d-b2a3ad69571b': {
|
||||
status: 'uploading',
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'qcow2'
|
||||
id: '77e4c693-0497-4b85-936d-b2a3ad69571b',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'uploading',
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -17,6 +28,6 @@ describe('composeUpdated', () => {
|
|||
// this function updates the type attribute and
|
||||
// returns everything else unchanged
|
||||
expect(result.type).toBe(types.COMPOSE_UPDATED);
|
||||
expect(result.compose).toBe(compose);
|
||||
expect(result.payload.compose).toBe(compose);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,12 +2,21 @@ import { composes } from '../../../store/reducers/composes';
|
|||
import types from '../../../store/types';
|
||||
|
||||
const compose = {
|
||||
'77e4c693-0497-4b85-936d-b2a3ad69571b': {
|
||||
id: '77e4c693-0497-4b85-936d-b2a3ad69571b',
|
||||
distribution: 'rhel-8',
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
image_type: 'ami',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
],
|
||||
image_status: {
|
||||
status: 'uploading',
|
||||
distribution: 'fedora-31',
|
||||
architecture: 'x86_64',
|
||||
image_type: 'qcow2'
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
describe('composes', () => {
|
||||
|
|
@ -19,17 +28,59 @@ describe('composes', () => {
|
|||
expect(result).toEqual({});
|
||||
});
|
||||
|
||||
test('returns updates state for types.COMPOSE_UPDATED', () => {
|
||||
test('returns updated state for types.COMPOSE_ADDED', () => {
|
||||
const state = {
|
||||
testAttr: 'test-me'
|
||||
allIds: [],
|
||||
byId: {},
|
||||
errors: null,
|
||||
};
|
||||
const result = composes(state, {
|
||||
type: types.COMPOSE_ADDED,
|
||||
payload: { compose }
|
||||
});
|
||||
|
||||
expect(result.allIds)
|
||||
.toEqual([ '77e4c693-0497-4b85-936d-b2a3ad69571b' ]);
|
||||
expect(result.byId['77e4c693-0497-4b85-936d-b2a3ad69571b'])
|
||||
.toEqual(compose);
|
||||
expect(result.error)
|
||||
.toEqual(null);
|
||||
});
|
||||
|
||||
test('returns updated state for types.COMPOSE_UPDATED', () => {
|
||||
const state = {
|
||||
allIds: [ '77e4c693-0497-4b85-936d-b2a3ad69571b' ],
|
||||
byId: {
|
||||
'77e4c693-0497-4b85-936d-b2a3ad69571b': {},
|
||||
},
|
||||
error: null,
|
||||
};
|
||||
const result = composes(state, {
|
||||
type: types.COMPOSE_UPDATED,
|
||||
compose
|
||||
payload: { compose }
|
||||
});
|
||||
|
||||
expect(result.testAttr).toBe('test-me');
|
||||
expect(result['77e4c693-0497-4b85-936d-b2a3ad69571b'])
|
||||
.toEqual(compose['77e4c693-0497-4b85-936d-b2a3ad69571b']);
|
||||
expect(result.allIds)
|
||||
.toEqual([ '77e4c693-0497-4b85-936d-b2a3ad69571b' ]);
|
||||
expect(result.byId['77e4c693-0497-4b85-936d-b2a3ad69571b'])
|
||||
.toEqual(compose);
|
||||
expect(result.error)
|
||||
.toEqual(null);
|
||||
});
|
||||
|
||||
test('returns updated state for types.COMPOSE_FAILED', () => {
|
||||
const state = {
|
||||
allIds: [],
|
||||
byId: {},
|
||||
error: null,
|
||||
};
|
||||
const result = composes(state, {
|
||||
type: types.COMPOSE_FAILED,
|
||||
payload: { error: 'test error' }
|
||||
});
|
||||
|
||||
expect(result.error)
|
||||
.toEqual('test error');
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue