feat: 🎸 add host set management support for tagets in API layer

This commit is contained in:
Randall Morey committed 2020-08-24 18:03:45 -04:00
1 parent 6588269274
commit 53a5f91ccf
8 files changed
+230 -3

No files matched your search

@@ -0,0 +1,16 @@
import Fragment from 'ember-data-model-fragments/fragment';
import { attr } from '@ember-data/model';
export default class FragmentHostSetModel extends Fragment {
// =attributes
@attr('string', {
description: 'ID of the related host set'
}) host_set_id;
@attr('string', {
description: 'ID of the catalog to which the host set belongs'
}) host_catalog_id;
}
+37 -1
View File
@@ -1,3 +1,39 @@
import GeneratedTargetModel from '../generated/models/target';
import { fragmentArray } from 'ember-data-model-fragments/attributes';
export default class TargetModel extends GeneratedTargetModel {}
export default class TargetModel extends GeneratedTargetModel {
// =attributes
@fragmentArray('fragment-host-set', {readOnly: true}) host_sets;
// =methods
/**
* Saves the `host_set_ids` array on the via the `set-hosts` method.
* See serializer and adapter for more information.
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
saveHostSets(options={ adapterOptions: {} }) {
const defaultOptions = {
adapterOptions: {
method: 'set-host-sets',
serializeHostSets: true
}
};
// There is no "deep merge" in ES.
// All of this nonsense is here to ensure we get
// a decent merge of `adapterOptions`.
return this.save({
...defaultOptions,
...options,
adapterOptions: {
...defaultOptions.adapterOptions,
...options.adapterOptions
}
});
}
}
+35
View File
@@ -0,0 +1,35 @@
import ApplicationSerializer from './application';
export default class TargetSerializer extends ApplicationSerializer {
// =methods
/**
* If `adapterOptions.serializeHostSets` is true, the serialization should
* include **only host sets** and the version. Normally, host sets are not
* serialized.
* @override
* @param {Snapshot} snapshot
* @return {object}
*/
serialize(snapshot) {
const serializeHostSets = snapshot?.adapterOptions?.serializeHostSets;
let serialized = super.serialize(...arguments);
if (serializeHostSets) serialized = this.serializeWithHostSets(snapshot);
return serialized;
}
/**
* Returns a payload containing only the host_set_ids array.
* @param {Snapshot} snapshot
* @return {object}
*/
serializeWithHostSets(snapshot) {
return {
version: snapshot.attr('version'),
host_set_ids:
snapshot.attr('host_sets').map(hostSet => hostSet.attr('host_set_id'))
};
}
}
@@ -0,0 +1 @@
export { default } from 'api/models/fragment-host-set';
+1
View File
@@ -0,0 +1 @@
export { default } from 'api/serializers/target';
@@ -0,0 +1,13 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Model | fragment host set', function(hooks) {
setupTest(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('fragment-host-set', {});
assert.ok(model);
});
});
+36 -2
View File
@@ -1,13 +1,47 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
module('Unit | Model | target', function(hooks) {
module('Unit | Model | target', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
// Replace this with your real tests.
test('it exists', function(assert) {
let store = this.owner.lookup('service:store');
let model = store.createRecord('target', {});
assert.ok(model);
});
test('it has a `saveHostSets` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post('/v1/scopes/o_1/targets/123abc:set-host-sets', (schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
host_set_ids: ['1', '3'],
version: 1
});
});
const store = this.owner.lookup('service:store');
store.push({
data: {
id: '123abc',
type: 'target',
attributes: {
name: 'Target',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' }
],
version: 1,
scope: {
scope_id: 'o_1',
type: 'scope'
}
}
}
});
const model = store.peekRecord('target', '123abc');
await model.saveHostSets();
});
});
@@ -0,0 +1,91 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Serializer | target', function(hooks) {
setupTest(hooks);
test('it serializes targets normally, without host sets', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const record = store.createRecord('target', {
name: 'User',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' }
],
version: 1
});
const snapshot = record._createSnapshot();
snapshot.adapterOptions = {};
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
name: 'User',
description: 'Description',
version: 1,
protocol: null
});
});
test('it serializes only host sets when `adapterOptions.serializeHostSets` is true', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const record = store.createRecord('target', {
name: 'User',
description: 'Description',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' }
],
version: 1
});
const snapshot = record._createSnapshot();
snapshot.adapterOptions = {
serializeHostSets: true
};
const serializedRecord = serializer.serialize(snapshot);
assert.deepEqual(serializedRecord, {
host_set_ids: ['1', '3'],
version: 1
});
});
test('it normalizes records with array fields', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('target');
const targetModelClass = store.createRecord('target').constructor;
const payload = {
id: '1',
name: 'Target 1',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' }
]
};
const normalized = serializer.normalizeSingleResponse(
store,
targetModelClass,
payload
);
assert.deepEqual(normalized, {
included: [],
data: {
id: '1',
type: 'target',
attributes: {
name: 'Target 1',
host_sets: [
{ host_set_id: '1', host_catalog_id: '2' },
{ host_set_id: '3', host_catalog_id: '4' }
]
},
relationships: {},
},
});
});
});