/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { setupEngine } from 'ember-engines/test-support';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { click, findAll, render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { kvMetadataPath, kvDataPath } from 'vault/utils/kv-path';
import { PAGE } from 'vault/tests/helpers/kv/kv-selectors';
import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs';
module('Integration | Component | kv | Page::Secret::Metadata::VersionDiff', function (hooks) {
setupRenderingTest(hooks);
setupEngine(hooks, 'kv');
setupMirage(hooks);
hooks.beforeEach(async function () {
this.backend = 'kv-engine';
this.path = 'my-secret';
this.breadcrumbs = [{ label: 'version history', route: 'secret.metadata.versions' }, { label: 'diff' }];
this.store = this.owner.lookup('service:store');
this.server.post('/sys/capabilities-self', allowAllCapabilitiesStub());
const metadata = this.server.create('kv-metadatum');
metadata.id = kvMetadataPath(this.backend, this.path);
this.store.pushPayload('kv/metadata', { modelName: 'kv/metadata', ...metadata });
this.metadata = this.store.peekRecord('kv/metadata', metadata.id);
// push current secret version record into the store to assert only one request is made
const dataId = kvDataPath(this.backend, this.path, 4);
this.store.pushPayload('kv/data', {
modelName: 'kv/data',
id: dataId,
secret_data: { foo: 'bar' },
version: this.metadata.currentVersion,
});
});
test('it renders empty states when current version is deleted or destroyed', async function (assert) {
assert.expect(4);
this.server.get(`/${this.backend}/data/${this.path}`, () => {});
const { currentVersion } = this.metadata;
// destroyed
this.metadata.versions[currentVersion].destroyed = true;
await render(
hbs`
`,
{ owner: this.engine }
);
assert.dom(PAGE.emptyStateTitle).hasText(`Version ${currentVersion} has been destroyed`);
assert
.dom(PAGE.emptyStateMessage)
.hasText('The current version of this secret has been destroyed. Select another version to compare.');
// deleted
this.metadata.versions[currentVersion].destroyed = false;
this.metadata.versions[currentVersion].deletion_time = '2023-07-25T00:36:19.950545Z';
await render(
hbs`
`,
{ owner: this.engine }
);
assert.dom(PAGE.emptyStateTitle).hasText(`Version ${currentVersion} has been deleted`);
assert
.dom(PAGE.emptyStateMessage)
.hasText('The current version of this secret has been deleted. Select another version to compare.');
});
test('it renders compared data of the two versions and shows icons for deleted, destroyed and current', async function (assert) {
assert.expect(14);
this.server.get(`/${this.backend}/data/${this.path}`, (schema, req) => {
assert.ok('request made to the fetch version 1 data.');
// request should not be made for version 4 (current version) because that record already exists in the store
assert.strictEqual(req.queryParams.version, '1', 'request includes version param');
return {
request_id: 'foobar',
data: {
data: { hello: 'world' },
metadata: {
created_time: '2023-06-20T21:26:47.592306Z',
custom_metadata: null,
deletion_time: '',
destroyed: false,
version: 1,
},
},
};
});
await render(
hbs`
`,
{ owner: this.engine }
);
const [left, right] = findAll(PAGE.detail.versionDropdown);
assert.dom(PAGE.diff.visualDiff).hasText(
`foo\"bar\"hello\"world\"`, // eslint-disable-line no-useless-escape
'correctly pull in the data from version 4 and compared to version 1.'
);
assert.dom(PAGE.diff.deleted).hasText(`hello"world"`);
assert.dom(PAGE.diff.added).hasText(`foo"bar"`);
assert.dom(right).hasText('Version 4', 'shows the current version for the left side default version.');
assert.dom(left).hasText('Version 1', 'shows the latest active version on init.');
await click(left);
for (const num in this.metadata.versions) {
const data = this.metadata.versions[num];
assert.dom(PAGE.detail.version(num)).exists('renders the button for each version.');
if (data.destroyed || data.deletion_time) {
assert
.dom(`${PAGE.detail.version(num)} [data-test-icon="x-square-fill"]`)
.hasClass(`${data.destroyed ? 'has-text-danger' : 'has-text-grey'}`);
}
}
assert
.dom(`${PAGE.detail.version('1')} button`)
.hasClass('is-active', 'correctly shows the selected version 1 as active.');
});
});