vault/ui/tests/integration/components/shamir/dr-token-flow-test.js
hashicorp-copywrite[bot] 0b12cdcfd1
[COMPLIANCE] License changes (#22290)
* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License.

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUS-1.1

* Fix test that expected exact offset on hcl file

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
Co-authored-by: Sarah Thompson <sthompson@hashicorp.com>
Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
2023-08-10 18:14:03 -07:00

223 lines
8.9 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import sinon from 'sinon';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'vault/tests/helpers';
import { click, fillIn, render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { setupMirage } from 'ember-cli-mirage/test-support';
module('Integration | Component | shamir/dr-token-flow', function (hooks) {
setupRenderingTest(hooks);
setupMirage(hooks);
test('begin to middle flow works', async function (assert) {
assert.expect(15);
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
assert.ok('Check endpoint is queried on init');
return {};
});
this.server.post('/sys/replication/dr/secondary/generate-operation-token/attempt', function (_, req) {
const requestBody = JSON.parse(req.requestBody);
assert.ok('Starts the token generation');
assert.deepEqual(requestBody, { attempt: true });
return {
started: true,
nonce: 'nonce-1234',
progress: 0,
required: 3,
encoded_token: '',
otp: 'otp-9876',
otp_length: 24,
complete: false,
};
});
this.server.post('/sys/replication/dr/secondary/generate-operation-token/update', function (_, req) {
const requestBody = JSON.parse(req.requestBody);
assert.ok('Makes request at the /update path');
assert.deepEqual(requestBody, { key: 'some-key', nonce: 'nonce-1234' });
return {
started: true,
nonce: 'nonce-1234',
progress: 1,
required: 3,
encoded_token: '',
otp: '',
otp_length: 24,
complete: false,
};
});
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
assert.dom('[data-test-dr-token-flow-step="begin"]').exists('First step shows');
assert.dom('[data-test-use-pgp-key-cta]').hasText('Provide PGP Key');
assert.dom('[data-test-generate-token-cta]').hasText('Generate operation token');
await click('[data-test-generate-token-cta]');
assert.dom('[data-test-dr-token-flow-step="shamir"]').exists('Shows shamir step after start');
assert
.dom('.shamir-progress')
.hasText('0/3 keys provided', 'progress shows reflecting checkStatus response with defaults');
assert.dom('[data-test-otp-info]').exists('OTP info banner shows');
assert.dom('[data-test-otp]').hasText('otp-9876', 'Shows OTP in copy banner');
// Fill in shamir key and submit
await fillIn('[data-test-shamir-key-input]', 'some-key');
await click('[data-test-shamir-submit]');
assert.dom('.shamir-progress').hasText('1/3 keys provided', 'progress shows reflecting attempt response');
assert
.dom('[data-test-otp-info]')
.exists('OTP info still banner shows even when attempt response does not include it');
assert
.dom('[data-test-otp]')
.hasText('otp-9876', 'Still shows OTP in copy banner when attempt response does not include it');
});
test('middle to finish flow works', async function (assert) {
assert.expect(9);
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
assert.ok('Check endpoint is queried on init');
return {
started: true,
nonce: 'nonce-1234',
progress: 2,
required: 3,
encoded_token: '',
otp: '',
otp_length: 24,
complete: false,
};
});
this.server.post('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
assert.notOk('attempt endpoint should not be queried');
});
this.server.post('/sys/replication/dr/secondary/generate-operation-token/update', function (_, req) {
const requestBody = JSON.parse(req.requestBody);
assert.ok('Makes request at the /update path');
assert.deepEqual(requestBody, { key: 'some-key', nonce: 'nonce-1234' });
return {
started: true,
nonce: 'nonce-1234',
progress: 3,
required: 3,
encoded_token: 'encoded-token-here',
otp: '',
otp_length: 24,
complete: true,
};
});
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
assert.dom('[data-test-dr-token-flow-step="shamir"]').exists('Shows shamir step on load');
assert
.dom('.shamir-progress')
.hasText('2/3 keys provided', 'progress shows reflecting checkStatus response');
assert.dom('[data-test-otp-info]').doesNotExist('OTP info banner not shown');
assert.dom('[data-test-otp]').doesNotExist('otp-9876', 'OTP copy banner not shown');
await fillIn('[data-test-shamir-key-input]', 'some-key');
await click('[data-test-shamir-submit]');
assert
.dom('[data-test-dr-token-flow-step="show-token"]')
.exists('updates to show encoded token on complete');
assert
.dom('[data-test-shamir-encoded-token]')
.hasText('encoded-token-here', 'shows encoded token from /update response');
});
test('it works correctly when pgp key chosen', async function (assert) {
assert.expect(3);
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
return {};
});
this.server.post(
'/sys/replication/dr/secondary/generate-operation-token/attempt',
function (schema, req) {
const body = JSON.parse(req.requestBody);
assert.deepEqual(body, { pgp_key: 'some-key-here' }, 'correct payload');
return {
started: true,
progress: 1,
required: 3,
complete: false,
};
}
);
await render(hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" />`);
await click('[data-test-use-pgp-key-cta]');
assert.dom('[data-test-choose-pgp-key-form="begin"]').exists('PGP form shows');
await click('[data-test-text-toggle]');
await fillIn('[data-test-pgp-file-textarea]', 'some-key-here');
await click('[data-test-use-pgp-key-button]');
await click('[data-test-confirm-pgp-key-submit]');
assert.dom('[data-test-dr-token-flow-step="shamir"]').exists('Renders shamir step after PGP key chosen');
});
test('it cancels correctly when generation not started', async function (assert) {
assert.expect(2);
const cancelSpy = sinon.spy();
this.set('onCancel', cancelSpy);
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
return {};
});
this.server.delete('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
assert.notOk('delete endpoint should not be queried');
return {};
});
await render(
hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" @onCancel={{this.onCancel}} />`
);
assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Cancel', 'Close button has correct copy');
await click('[data-test-shamir-modal-cancel-button]');
assert.ok(cancelSpy.calledOnce, 'cancel spy called on click');
});
test('it cancels correctly when generation has started but not finished', async function (assert) {
assert.expect(3);
const cancelSpy = sinon.spy();
this.set('onCancel', cancelSpy);
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
return {
started: true,
progress: 1,
required: 3,
complete: false,
};
});
this.server.delete('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
assert.ok('delete endpoint is queried');
return {};
});
await render(
hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" @onCancel={{this.onCancel}} />`
);
assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Cancel', 'Close button has correct copy');
await click('[data-test-shamir-modal-cancel-button]');
assert.ok(cancelSpy.calledOnce, 'cancel spy called on click');
});
test('it closes correctly when generation is completed', async function (assert) {
assert.expect(2);
const cancelSpy = sinon.spy();
this.set('onCancel', cancelSpy);
this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
return {
started: true,
progress: 3,
required: 3,
complete: true,
encoded_token: 'foobar',
};
});
this.server.delete('/sys/replication/dr/secondary/generate-operation-token/attempt', function () {
assert.notOk('delete endpoint should not be queried');
return {};
});
await render(
hbs`<Shamir::DrTokenFlow @action="generate-dr-operation-token" @onCancel={{this.onCancel}} />`
);
assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Close', 'Close button has correct copy');
await click('[data-test-shamir-modal-cancel-button]');
assert.ok(cancelSpy.calledOnce, 'cancel spy called on click');
});
});