backport of commit e3c3a52b7b9f8d41c1d04f26b469b53c585587ec (#21242)
Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>
This commit is contained in:
parent
7385e73a15
commit
67feccc7dd
|
@ -1,6 +1,15 @@
|
|||
<div class="box is-sideless is-fullwidth is-marginless">
|
||||
{{#if this.errorBanner}}
|
||||
<AlertBanner @type="danger" @message={{this.errorBanner}} data-test-error-banner />
|
||||
{{#if this.errors}}
|
||||
<AlertBanner @type="danger" data-test-error-banner>
|
||||
<ul class={{if (gt this.errors.length 1) "bullet"}}>
|
||||
{{#each this.errors as |error|}}
|
||||
<li>
|
||||
<code>POST config/{{error.modelName}}</code>:
|
||||
{{error.message}}
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</AlertBanner>
|
||||
{{/if}}
|
||||
<form {{on "submit" (perform this.save)}}>
|
||||
<fieldset class="is-shadowless is-marginless is-borderless is-fullwidth" data-test-cluster-config-edit-section>
|
||||
|
|
|
@ -37,13 +37,18 @@ interface PkiConfigCrlBooleans {
|
|||
disable: boolean;
|
||||
ocspDisable: boolean;
|
||||
}
|
||||
|
||||
interface ErrorObject {
|
||||
modelName: string;
|
||||
message: string;
|
||||
}
|
||||
export default class PkiConfigurationEditComponent extends Component<Args> {
|
||||
@service declare readonly router: RouterService;
|
||||
@service declare readonly flashMessages: FlashMessageService;
|
||||
@service declare readonly version: VersionService;
|
||||
|
||||
@tracked invalidFormAlert = '';
|
||||
@tracked errorBanner = '';
|
||||
@tracked errors: Array<ErrorObject> = [];
|
||||
|
||||
get isEnterprise() {
|
||||
return this.version.isEnterprise;
|
||||
|
@ -53,18 +58,32 @@ export default class PkiConfigurationEditComponent extends Component<Args> {
|
|||
@waitFor
|
||||
*save(event: Event) {
|
||||
event.preventDefault();
|
||||
try {
|
||||
for (const model of ['cluster', 'acme', 'urls', 'crl']) {
|
||||
// only call save() if user has permission
|
||||
if (this.args[model as keyof Args].canSet) {
|
||||
yield this.args[model as keyof Args].save();
|
||||
this.flashMessages.success(`Successfully updated ${model} config`);
|
||||
}
|
||||
// first clear errors and sticky flash messages
|
||||
this.errors = [];
|
||||
this.flashMessages.clearMessages();
|
||||
|
||||
// modelName is also the API endpoint (i.e. pki/config/cluster)
|
||||
for (const modelName of ['cluster', 'acme', 'urls', 'crl']) {
|
||||
const model = this.args[modelName as keyof Args];
|
||||
// skip saving and continue to next iteration if user does not have permission
|
||||
if (!model.canSet) continue;
|
||||
try {
|
||||
yield model.save();
|
||||
this.flashMessages.success(`Successfully updated config/${modelName}`);
|
||||
} catch (error) {
|
||||
const errorObject: ErrorObject = {
|
||||
modelName,
|
||||
message: errorMessage(error),
|
||||
};
|
||||
this.flashMessages.danger(`Error updating config/${modelName}`, { sticky: true });
|
||||
this.errors.pushObject(errorObject);
|
||||
}
|
||||
this.router.transitionTo('vault.cluster.secrets.backend.pki.configuration.index');
|
||||
} catch (error) {
|
||||
}
|
||||
|
||||
if (this.errors.length) {
|
||||
this.invalidFormAlert = 'There was an error submitting this form.';
|
||||
this.errorBanner = errorMessage(error);
|
||||
} else {
|
||||
this.router.transitionTo('vault.cluster.secrets.backend.pki.configuration.index');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { click, fillIn, render } from '@ember/test-helpers';
|
|||
import { setupEngine } from 'ember-engines/test-support';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { Response } from 'miragejs';
|
||||
import { SELECTORS } from 'vault/tests/helpers/pki/page/pki-configuration-edit';
|
||||
import sinon from 'sinon';
|
||||
import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs';
|
||||
|
@ -19,10 +20,14 @@ module('Integration | Component | page/pki-configuration-edit', function (hooks)
|
|||
setupMirage(hooks);
|
||||
|
||||
hooks.beforeEach(async function () {
|
||||
// test context setup
|
||||
this.server.post('/sys/capabilities-self', allowAllCapabilitiesStub());
|
||||
this.context = { owner: this.engine }; // this.engine set by setupEngine
|
||||
this.store = this.owner.lookup('service:store');
|
||||
this.cancelSpy = sinon.spy();
|
||||
this.router = this.owner.lookup('service:router');
|
||||
sinon.stub(this.router, 'transitionTo');
|
||||
|
||||
// component data setup
|
||||
this.backend = 'pki-engine';
|
||||
// both models only use findRecord. API parameters for pki/crl
|
||||
// are set by default backend values when the engine is mounted
|
||||
|
@ -59,6 +64,10 @@ module('Integration | Component | page/pki-configuration-edit', function (hooks)
|
|||
this.urls = this.store.peekRecord('pki/config/urls', this.backend);
|
||||
});
|
||||
|
||||
hooks.afterEach(function () {
|
||||
this.router.transitionTo.restore();
|
||||
});
|
||||
|
||||
test('it renders with config data and updates config', async function (assert) {
|
||||
assert.expect(32);
|
||||
this.server.post(`/${this.backend}/config/acme`, (schema, req) => {
|
||||
|
@ -401,4 +410,49 @@ module('Integration | Component | page/pki-configuration-edit', function (hooks)
|
|||
"You do not have permission to set this mount's revocation configuration Ask your administrator if you think you should have access to: POST /pki-engine/config/crl"
|
||||
);
|
||||
});
|
||||
|
||||
test('it renders alert banner and endpoint respective error', async function (assert) {
|
||||
assert.expect(4);
|
||||
this.server.post(`/${this.backend}/config/acme`, () => {
|
||||
return new Response(500, {}, { errors: ['something wrong with acme'] });
|
||||
});
|
||||
this.server.post(`/${this.backend}/config/cluster`, () => {
|
||||
return new Response(500, {}, { errors: ['something wrong with cluster'] });
|
||||
});
|
||||
this.server.post(`/${this.backend}/config/crl`, () => {
|
||||
return new Response(500, {}, { errors: ['something wrong with crl'] });
|
||||
});
|
||||
this.server.post(`/${this.backend}/config/urls`, () => {
|
||||
return new Response(500, {}, { errors: ['something wrong with urls'] });
|
||||
});
|
||||
await render(
|
||||
hbs`
|
||||
<Page::PkiConfigurationEdit
|
||||
@acme={{this.acme}}
|
||||
@cluster={{this.cluster}}
|
||||
@urls={{this.urls}}
|
||||
@crl={{this.crl}}
|
||||
@backend={{this.backend}}
|
||||
/>
|
||||
`,
|
||||
this.context
|
||||
);
|
||||
|
||||
await click(SELECTORS.saveButton);
|
||||
assert
|
||||
.dom(SELECTORS.errorBanner)
|
||||
.hasText(
|
||||
'Error POST config/cluster: something wrong with cluster POST config/acme: something wrong with acme POST config/urls: something wrong with urls POST config/crl: something wrong with crl'
|
||||
);
|
||||
assert.dom(`${SELECTORS.errorBanner} ul`).hasClass('bullet');
|
||||
|
||||
// change 3 out of 4 requests to be successful to assert single error renders correctly
|
||||
this.server.post(`/${this.backend}/config/acme`, () => new Response(200));
|
||||
this.server.post(`/${this.backend}/config/cluster`, () => new Response(200));
|
||||
this.server.post(`/${this.backend}/config/crl`, () => new Response(200));
|
||||
|
||||
await click(SELECTORS.saveButton);
|
||||
assert.dom(SELECTORS.errorBanner).hasText('Error POST config/urls: something wrong with urls');
|
||||
assert.dom(`${SELECTORS.errorBanner} ul`).doesNotHaveClass('bullet');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue