/** * Copyright (c) HashiCorp, Inc. * SPDX-License-Identifier: BUSL-1.1 */ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; import { setupMirage } from 'ember-cli-mirage/test-support'; import { kvMetadataPath } from 'vault/utils/kv-path'; import { Response } from 'miragejs'; const UTC_DATE = '1994-11-05T00:00:00.000Z'; const EXAMPLE_KV_METADATA_GET_RESPONSE = { request_id: 'foobar', data: { cas_required: true, created_time: 'created-time', current_version: 2, custom_metadata: { application: 'staging' }, delete_version_after: '0s', max_versions: 10, oldest_version: 0, // TODO: is this a bug? payload from real API updated_time: 'updated-time', versions: { 1: { created_time: 'created-time', deletion_time: UTC_DATE, destroyed: false, }, 2: { created_time: 'created-time', deletion_time: '', destroyed: false }, }, }, }; module('Unit | Adapter | kv/metadata', function (hooks) { setupTest(hooks); setupMirage(hooks); hooks.beforeEach(function () { this.store = this.owner.lookup('service:store'); this.secretMountPath = this.owner.lookup('service:secret-mount-path'); this.backend = 'some/kv-back&end'; this.secretMountPath.currentPath = this.backend; this.path = 'beep/bop my/secret'; this.id = kvMetadataPath(this.backend, this.path); this.data = { options: { cas: 2, }, data: { foo: 'bar', }, }; this.payload = { max_versions: 2, cas_required: false, delete_version_after: '0s', custom_metadata: { admin: 'bob', }, }; this.endpoint = kvMetadataPath(this.backend, this.path); }); test('it should make request to correct endpoint on createRecord', async function (assert) { assert.expect(10); const recordData = { backend: this.backend, path: this.path, deleteVersionAfter: '45h', customMetadata: { application: 'staging' }, oldestVersion: 4, currentVersion: 6, createdTime: 'created', updatedTime: 'updated', versions: { 1: { created_time: 'created-time', deletion_time: UTC_DATE, destroyed: false, }, 2: { created_time: 'created-time', deletion_time: '', destroyed: false, }, }, }; const expectedBody = { max_versions: 0, delete_version_after: '45h', cas_required: false, custom_metadata: { application: 'staging' }, }; this.server.post(this.endpoint, (schema, req) => { const body = JSON.parse(req.requestBody); assert.ok('POST request made to correct endpoint when creating new record'); assert.propEqual(body, expectedBody, 'POST request has correct body'); return new Response(204); }); const record = this.store.createRecord('kv/metadata', recordData); await record.save(); assert.strictEqual(record.id, this.id, 'record has correct id'); assert.strictEqual(record.backend, this.backend, 'record has correct backend'); assert.strictEqual(record.path, this.path, 'record has correct path'); assert.strictEqual(record.maxVersions, 0, 'record has default maxVersions'); assert.false(record.casRequired, 'record has correct casRequired'); assert.strictEqual(record.deleteVersionAfter, '45h', 'record has correct deleteVersionAfter'); assert.deepEqual(record.customMetadata, { application: 'staging' }, 'record has correct customMetadata'); assert.deepEqual( record.versions, EXAMPLE_KV_METADATA_GET_RESPONSE.data.versions, 'record has correct versions data' ); }); test('it should make request to correct endpoint on update record', async function (assert) { assert.expect(1); const data = this.server.create('kv-metadatum'); data.id = kvMetadataPath('kv-engine', 'my-secret'); this.store.pushPayload('kv/metadata', { modelName: 'kv/metadata', ...data, }); this.server.post(kvMetadataPath('kv-engine', 'my-secret'), () => { assert.ok(true, 'request made to correct endpoint on delete metadata.'); }); const record = await this.store.peekRecord('kv/metadata', data.id); await record.save(); }); test('it should make request to correct endpoint on queryRecord', async function (assert) { assert.expect(13); this.server.get(this.endpoint, () => { assert.ok(true, 'request is made to correct url on queryRecord.'); return EXAMPLE_KV_METADATA_GET_RESPONSE; }); const record = await this.store.queryRecord('kv/metadata', { backend: this.backend, path: this.path }); assert.strictEqual(record.id, this.id, 'record has correct id'); assert.strictEqual(record.backend, this.backend, 'record has correct backend'); assert.strictEqual(record.path, this.path, 'record has correct path'); assert.strictEqual(record.maxVersions, 10, 'record has correct maxVersions'); assert.true(record.casRequired, 'record has correct casRequired'); assert.strictEqual(record.deleteVersionAfter, '0s', 'record has correct deleteVersionAfter'); assert.deepEqual(record.customMetadata, { application: 'staging' }, 'record has correct customMetadata'); assert.strictEqual(record.createdTime, 'created-time', 'record has correct createdTime'); assert.strictEqual(record.currentVersion, 2, 'record has correct currentVersion'); assert.strictEqual(record.oldestVersion, 0, 'record has correct oldestVersion'); assert.strictEqual(record.updatedTime, 'updated-time', 'record has correct updatedTime'); assert.deepEqual( record.versions, EXAMPLE_KV_METADATA_GET_RESPONSE.data.versions, 'record has correct versions data' ); }); test('it should make request to correct endpoint on query', async function (assert) { assert.expect(1); this.server.get(kvMetadataPath(this.backend, 'directory/'), (schema, req) => { assert.ok(req.queryParams.list, 'list query param sent when listing secrets'); return { data: { keys: [] } }; }); this.store.query('kv/metadata', { backend: this.backend, pathToSecret: 'directory/' }); }); test('it should make request to correct endpoint on delete metadata', async function (assert) { assert.expect(3); const data = this.server.create('kv-metadatum'); data.id = kvMetadataPath('kv-engine', 'my-secret'); this.store.pushPayload('kv/metadata', { modelName: 'kv/metadata', ...data, }); this.server.delete(kvMetadataPath('kv-engine', 'my-secret'), () => { assert.ok(true, 'request made to correct endpoint on delete metadata.'); }); let record = await this.store.peekRecord('kv/metadata', data.id); await record.destroyRecord(); assert.true(record.isDeleted, 'record is deleted'); record = await this.store.peekRecord('kv/metadata', this.id); assert.strictEqual(record, null, 'record is no longer in store'); }); });