store: Insert new composes on top of the table

Fixes #161
This commit is contained in:
Sanne Raymaekers 2021-06-02 13:14:43 +02:00 committed by jkozol
parent 6db456a17c
commit b648ffaca4
4 changed files with 33 additions and 12 deletions

View file

@ -13,9 +13,9 @@ export const composeFailed = (error) => ({
payload: { error }
});
export const composeAdded = (compose) => ({
export const composeAdded = (compose, insert) => ({
type: types.COMPOSE_ADDED,
payload: { compose },
payload: { compose, insert },
});
export const composeStart = (composeRequest) => async dispatch => {
@ -25,7 +25,7 @@ export const composeStart = (composeRequest) => async dispatch => {
// add the compose id to the compose object to provide access to the id if iterating through
// composes and add an image status of 'pending' alongside the compose request.
const compose = Object.assign({}, response, { request: composeRequest }, { image_status: { status: 'pending' }});
dispatch(composeAdded(compose));
dispatch(composeAdded(compose, true));
}).catch(err => {
if (err.response.status === 500) {
dispatch(composeFailed('Error: Something went wrong serverside'));
@ -53,7 +53,7 @@ export const composesUpdatedCount = (count) => ({
export const composesGet = (limit, offset) => async dispatch => {
const request = await api.getComposes(limit, offset);
request.data.map(compose => {
dispatch(composeAdded(compose));
dispatch(composeAdded(compose, false));
dispatch(composeGetStatus(compose.id));
});
dispatch(composesUpdatedCount(request.meta.count));

View file

@ -32,14 +32,24 @@ const initialComposesState = {
};
// only add to array if compose does not exist
const updateAllIds = (allIds, id) => allIds.includes(id) ? allIds : allIds.concat(id);
const updateAllIds = (allIds, id, insert) => {
if (allIds.includes(id)) {
return allIds;
}
if (insert) {
return [ id ].concat(allIds);
}
return allIds.concat(id);
};
export function composes(state = initialComposesState, action) {
switch (action.type) {
case types.COMPOSE_ADDED:
return {
...state,
allIds: updateAllIds(state.allIds, action.payload.compose.id),
allIds: updateAllIds(state.allIds, action.payload.compose.id, action.payload.insert),
byId: {
...state.byId,
[action.payload.compose.id]: action.payload.compose,

View file

@ -8,6 +8,7 @@ import CreateImageWizard from '../../../Components/CreateImageWizard/CreateImage
import api from '../../../api.js';
let historySpy = undefined;
let store = undefined;
function verifyButtons() {
// these buttons exist everywhere
@ -437,7 +438,8 @@ describe('Step Review', () => {
describe('Click through all steps', () => {
beforeEach(() => {
const { _component, history } = renderWithReduxRouter(<CreateImageWizard />);
const { _component, history, reduxStore } = renderWithReduxRouter(<CreateImageWizard />);
store = reduxStore;
historySpy = jest.spyOn(history, 'push');
});
@ -505,10 +507,11 @@ describe('Click through all steps', () => {
await screen.findByText('Register the system on first boot');
// mock the backend API
let ids = [];
const composeImage = jest
.spyOn(api, 'composeImage')
.mockImplementation(body => {
let id;
if (body.image_requests[0].upload_request.type === 'aws') {
expect(body).toEqual({
distribution: 'rhel-8',
@ -533,6 +536,7 @@ describe('Click through all steps', () => {
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f56';
} else if (body.image_requests[0].upload_request.type === 'gcp') {
expect(body).toEqual({
distribution: 'rhel-8',
@ -557,6 +561,7 @@ describe('Click through all steps', () => {
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f57';
} else if (body.image_requests[0].upload_request.type === 'azure') {
expect(body).toEqual({
distribution: 'rhel-8',
@ -582,9 +587,12 @@ describe('Click through all steps', () => {
'base-url': 'https://cdn.redhat.com/'
},
},
}); }
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f58';
}
return Promise.resolve({ id: 'edbae1c2-62bc-42c1-ae0c-3110ab718f58' });
ids.unshift(id);
return Promise.resolve({ id });
});
const create = screen.getByRole('button', { name: /Create/ });
@ -597,6 +605,7 @@ describe('Click through all steps', () => {
// but jsdom will not render the new page so we can't assert on that
await waitFor(() => expect(historySpy).toHaveBeenCalledTimes(1));
await expect(historySpy).toHaveBeenCalledWith('/landing');
expect(store.getStore().getState().composes.allIds).toEqual(ids);
});
test('with missing values', async () => {

View file

@ -8,12 +8,14 @@ import { init, clearStore } from '../store';
export const renderWithReduxRouter = (component, store = {}, route = '/') => {
const history = createMemoryHistory({ initialEntries: [ route ]});
clearStore();
let reduxStore = init(store);
return {
...render(
<Provider store={ init(store).getStore() }>
<Provider store={ reduxStore.getStore() }>
<Router history={ history }>{component}</Router>
</Provider>
),
history
history,
reduxStore
};
};