vault/ui/tests/unit/adapters/sync/associations-test.js
claire bontempo 1fbbf9d76b
UI: Ember-data upgrade 5.3.2 prep: use custom service instead of extending ember-data store (#28695)
* rename store to pagination, remove store extension

* initial update of service test

* remove superfluous helper

* replace store with pagination service in main app

* update kmip engine syntax

* add pagination to kmip engine

* update to pagination in config-ui engine

* update sync engine to use pagination service

* use pagination service in kv engine

* use pagination service in ldap engine

* use pagination in pki engine

* update renaming clearDataset functions

* link to jira VAULT-31721

* remove comment
2024-10-17 10:00:57 -07:00

191 lines
6.4 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { setupTest } from 'ember-qunit';
import { module, test } from 'qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { associationsResponse } from 'vault/mirage/handlers/sync';
import sinon from 'sinon';
module('Unit | Adapter | sync | association', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
hooks.beforeEach(function () {
this.store = this.owner.lookup('service:store');
this.pagination = this.owner.lookup('service:pagination');
this.params = [
{ type: 'aws-sm', name: 'us-west-1' },
{ type: 'gh', name: 'baz' },
];
this.params.forEach((params) => {
this.server.create('sync-destination', params.type, { name: params.name });
const association = this.server.create('sync-association', {
...params,
mount: 'foo',
secret_name: 'bar',
});
if (!this.association) {
this.association = association;
}
});
this.newModel = this.store.createRecord('sync/association', {
destinationType: 'aws-sm',
destinationName: 'us-west-1',
mount: 'foo',
secretName: 'bar',
});
});
test('it should make request to correct endpoint when querying', async function (assert) {
assert.expect(2);
this.server.get('/sys/sync/destinations/:type/:name/associations', (schema, req) => {
// list query param not required for this endpoint
assert.deepEqual(req.queryParams, {}, 'query params stripped from request');
assert.deepEqual(req.params, this.params[0], 'request is made to correct endpoint when querying');
return associationsResponse(schema, req);
});
await this.pagination.lazyPaginatedQuery('sync/association', {
responsePath: 'data.keys',
page: 1,
destinationType: 'aws-sm',
destinationName: 'us-west-1',
});
});
test('it should make request to correct endpoint for queryAll associations', async function (assert) {
assert.expect(3);
this.server.get('/sys/sync/associations', (schema, req) => {
assert.ok(true, 'request is made to correct endpoint for queryAll');
assert.propEqual(req.queryParams, { list: 'true' }, 'query params include list: true');
return {
data: {
key_info: {},
keys: [],
total_associations: 5,
total_secrets: 7,
},
};
});
const response = await this.store.adapterFor('sync/association').queryAll();
const expected = { total_associations: 5, total_secrets: 7 };
assert.deepEqual(response, expected, 'It returns correct values for queryAll');
});
test('it should make request to correct endpoint when creating record', async function (assert) {
assert.expect(2);
this.server.post('/sys/sync/destinations/:type/:name/associations/set', (schema, req) => {
assert.deepEqual(req.params, this.params[0], 'request is made to correct endpoint when querying');
assert.deepEqual(
JSON.parse(req.requestBody),
{ mount: 'foo', secret_name: 'bar' },
'Correct payload is sent when creating association'
);
return associationsResponse(schema, req);
});
await this.newModel.save({ adapterOptions: { action: 'set' } });
});
test('it should make request to correct endpoint when updating record', async function (assert) {
assert.expect(2);
this.server.post('/sys/sync/destinations/:type/:name/associations/remove', (schema, req) => {
assert.deepEqual(req.params, this.params[0], 'request is made to correct endpoint when querying');
assert.deepEqual(
JSON.parse(req.requestBody),
{ mount: 'foo', secret_name: 'bar' },
'Correct payload is sent when removing association'
);
return associationsResponse(schema, req);
});
this.store.pushPayload('sync/association', {
modelName: 'sync/association',
destinationType: 'aws-sm',
destinationName: 'us-west-1',
mount: 'foo',
secret_name: 'bar',
sync_status: 'SYNCED',
id: 'foo/bar',
});
const model = this.store.peekRecord('sync/association', 'foo/bar');
await model.save({ adapterOptions: { action: 'remove' } });
});
test('it should parse response from set/remove request', async function (assert) {
this.server.post('/sys/sync/destinations/:type/:name/associations/set', associationsResponse);
const adapter = this.store.adapterFor('sync/association');
// mock snapshot
const snapshot = {
attributes() {
return { destinationName: 'us-west-1', destinationType: 'aws-sm' };
},
serialize() {
return { mount: 'foo', secret_name: 'bar' };
},
adapterOptions: { action: 'set' },
};
const response = await adapter._setOrRemove(this.store, { modelName: 'sync/association' }, snapshot);
const { accessor, mount, secret_name, sync_status, name, type, updated_at } = this.association;
const expected = {
id: 'foo/bar',
accessor,
mount,
secret_name,
sync_status,
updated_at,
destinationType: type,
destinationName: name,
};
assert.deepEqual(
response,
expected,
'Custom create/update record method makes request and parses response'
);
});
test('it should throw error if save action is not passed in adapterOptions', async function (assert) {
assert.expect(1);
try {
await this.newModel.save();
} catch (e) {
assert.strictEqual(
e.message,
"Assertion Failed: action type of set or remove required when saving association => association.save({ adapterOptions: { action: 'set' }})"
);
}
});
test('it should fetch and normalize many associations for fetchByDestinations', async function (assert) {
assert.expect(3);
const handler = this.server.get('/sys/sync/destinations/:type/:name/associations', (schema, req) => {
// list query param not required for this endpoint
assert.deepEqual(
req.params,
this.params[handler.numberOfCalls - 1],
'request is made to correct endpoint when querying'
);
return associationsResponse(schema, req);
});
const spy = sinon.spy(this.store.serializerFor('sync/association'), 'normalizeFetchByDestinations');
await this.store.adapterFor('sync/association').fetchByDestinations(this.params);
assert.true(spy.calledTwice, 'Serializer method used on each response');
});
});