diff --git a/src/Components/CreateImageWizard/CreateImageWizard.js b/src/Components/CreateImageWizard/CreateImageWizard.js index bc3177b8..520a225b 100644 --- a/src/Components/CreateImageWizard/CreateImageWizard.js +++ b/src/Components/CreateImageWizard/CreateImageWizard.js @@ -122,20 +122,22 @@ const onSave = (values) => { if (values['target-environment']?.gcp) { let share = ''; - switch (values['google-account-type']) { - case 'googleAccount': - share = `user:${values['google-email']}`; - break; - case 'serviceAccount': - share = `serviceAccount:${values['google-email']}`; - break; - case 'googleGroup': - share = `group:${values['google-email']}`; - break; - case 'domain': - share = `domain:${values['google-domain']}`; - break; - // no default + if (values['image_sharing'] === 'gcp-account') { + switch (values['google-account-type']) { + case 'googleAccount': + share = `user:${values['google-email']}`; + break; + case 'serviceAccount': + share = `serviceAccount:${values['google-email']}`; + break; + case 'googleGroup': + share = `group:${values['google-email']}`; + break; + case 'domain': + share = `domain:${values['google-domain']}`; + break; + // no default + } } const request = { @@ -148,15 +150,16 @@ const onSave = (values) => { image_type: 'gcp', upload_request: { type: 'gcp', - options: { - share_with_accounts: [share], - }, + options: {}, }, }, ], customizations, }; + if (share !== '') { + request.options = [share]; + } requests.push(request); } diff --git a/src/Components/CreateImageWizard/steps/googleCloud.js b/src/Components/CreateImageWizard/steps/googleCloud.js index b4def174..29d5ce53 100644 --- a/src/Components/CreateImageWizard/steps/googleCloud.js +++ b/src/Components/CreateImageWizard/steps/googleCloud.js @@ -102,20 +102,48 @@ const googleCloudStep = { name: 'google-cloud-text-component', label: (
- Your image will be uploaded to GCP and shared with the account you - provide below. + Select how to share your image. The image you create can be used to + launch instances on GCP, regardless of which method you select.
), }, { - component: componentTypes.PLAIN_TEXT, - name: 'google-cloud-text-component', - label: ( -- The shared image will expire within 14 days. To permanently - access the image, copy it to your Google Cloud Platform account. -
- ), + component: componentTypes.RADIO, + label: 'Select image sharing', + isRequired: true, + name: 'image-sharing', + initialValue: 'gcp-account', + autoFocus: true, + options: [ + { + label: 'Share image with a Google account', + 'data-testid': 'account-sharing', + autoFocus: true, + description: ( ++ Your image will be uploaded to GCP and shared with the account you + provide below. + The image expires in 14 days. To keep permanent access to + your image, copy it to your GCP project. +
+ ), + value: 'gcp-account', + }, + { + label: 'Share image with Red Hat Insights only', + 'data-testid': 'image-sharing', + description: ( ++ Your image will be uploaded to GCP and shared with Red Hat + Insights. + The image expires in 14 days. You cannot access or + recreate this image in your GCP project. +
+ ), + value: 'insights', + autoFocus: true, + }, + ], }, { component: 'radio-popover', @@ -137,6 +165,10 @@ const googleCloudStep = { type: validatorTypes.REQUIRED, }, ], + condition: { + when: 'image-sharing', + is: 'gcp-account', + }, }, { component: componentTypes.TEXT_FIELD, @@ -145,11 +177,16 @@ const googleCloudStep = { type: 'text', label: 'Principal (e.g. e-mail address)', condition: { - or: [ - { when: 'google-account-type', is: 'googleAccount' }, - { when: 'google-account-type', is: 'serviceAccount' }, - { when: 'google-account-type', is: 'googleGroup' }, - { when: 'google-account-type', is: null }, + and: [ + { when: 'image-sharing', is: 'gcp-account' }, + { + or: [ + { when: 'google-account-type', is: 'googleAccount' }, + { when: 'google-account-type', is: 'serviceAccount' }, + { when: 'google-account-type', is: 'googleGroup' }, + { when: 'google-account-type', is: null }, + ], + }, ], }, isRequired: true, @@ -170,8 +207,10 @@ const googleCloudStep = { type: 'text', label: 'Domain', condition: { - when: 'google-account-type', - is: 'domain', + and: [ + { when: 'image-sharing', is: 'gcp-account' }, + { when: 'google-account-type', is: 'domain' }, + ], }, isRequired: true, validate: [ diff --git a/src/store/typeGuards.ts b/src/store/typeGuards.ts index 576bf6cb..31b1989b 100644 --- a/src/store/typeGuards.ts +++ b/src/store/typeGuards.ts @@ -12,7 +12,7 @@ import { export const isGcpUploadRequestOptions = ( options: UploadRequest['options'] ): options is GcpUploadRequestOptions => { - return (options as GcpUploadRequestOptions).share_with_accounts !== undefined; + return true; }; export const isAwsUploadRequestOptions = ( diff --git a/src/test/Components/CreateImageWizard/CreateImageWizard.test.js b/src/test/Components/CreateImageWizard/CreateImageWizard.test.js index 84cd8e62..543a0c7e 100644 --- a/src/test/Components/CreateImageWizard/CreateImageWizard.test.js +++ b/src/test/Components/CreateImageWizard/CreateImageWizard.test.js @@ -458,7 +458,14 @@ describe('Step Upload to Google', () => { test('clicking Next loads Registration', async () => { await setUp(); - await user.type(screen.getByTestId('input-google-email'), 'test@test.com'); + const shareRadioButton = await screen.findByRole('radio', { + name: /share image with a google account/i, + }); + await user.click(shareRadioButton); + + const googleEmailInput = await screen.findByTestId('input-google-email'); + + await user.type(googleEmailInput, 'test@test.com'); await clickNext(); await screen.findByRole('textbox', { @@ -485,15 +492,22 @@ describe('Step Upload to Google', () => { test('the google account id field is shown and required', async () => { await setUp(); - const accessKeyId = screen.getByTestId('input-google-email'); + await waitFor(() => { + screen.getByTestId('account-sharing'); + }); + + user.click(screen.getByTestId('account-sharing')); + const accessKeyId = await screen.findByTestId('input-google-email'); expect(accessKeyId).toHaveValue(''); expect(accessKeyId).toBeEnabled(); + // expect(accessKeyId).toBeRequired(); // DDf does not support required value }); test('the google email field must be a valid email', async () => { await setUp(); + await user.click(screen.getByTestId('account-sharing')); await user.type(screen.getByTestId('input-google-email'), 'a'); expect(await getNextButton()).toHaveClass('pf-m-disabled'); expect(await getNextButton()).toBeDisabled(); @@ -1033,7 +1047,11 @@ describe('Click through all steps', () => { await user.type(screen.getByTestId('aws-account-id'), '012345678901'); await clickNext(); + await user.click(screen.getByTestId('account-sharing')); + await user.type(screen.getByTestId('input-google-email'), 'test@test.com'); + + await user.click(await screen.findByTestId('image-sharing')); await clickNext(); await user.click(screen.getByTestId('azure-radio-manual')); @@ -1391,10 +1409,8 @@ describe('Keyboard accessibility', () => { await clickNext(); // Target environment google - const googleAccountRadio = screen.getByRole('radio', { - name: /google account/i, - }); - expect(googleAccountRadio).toHaveFocus(); + await user.click(screen.getByTestId('account-sharing')); + expect(screen.getByTestId('account-sharing')).toHaveFocus(); await user.type(screen.getByTestId('input-google-email'), 'test@test.com'); await clickNext(); diff --git a/src/test/jest.setup.js b/src/test/jest.setup.js index ab6dc7a0..843193a6 100644 --- a/src/test/jest.setup.js +++ b/src/test/jest.setup.js @@ -36,6 +36,10 @@ failOnConsole({ ) || errorMessage.includes( "Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application." + ) || + // [2023-09] Suppresses an error that occurs on the GCP step of the Wizard. + errorMessage.includes( + 'Warning: Cannot update a component (`ForwardRef(Field)`) while rendering a different component (`Radio`). To locate the bad setState() call inside `Radio`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render' )) ) { // eslint-disable-next-line no-console