diff --git a/addons/api/addon/generated/models/host-set.js b/addons/api/addon/generated/models/host-set.js index 048badc73..9d8c13d6e 100644 --- a/addons/api/addon/generated/models/host-set.js +++ b/addons/api/addon/generated/models/host-set.js @@ -56,4 +56,11 @@ export default class GeneratedHostSetModel extends BaseModel { readOnly: true, }) plugin; + + // Azure specific + @attr('string', { + description: '', + isNestedAttribute: true, + }) + filter; } diff --git a/addons/api/addon/models/host-set.js b/addons/api/addon/models/host-set.js index b453195d1..98f7cd5e2 100644 --- a/addons/api/addon/models/host-set.js +++ b/addons/api/addon/models/host-set.js @@ -66,6 +66,18 @@ export default class HostSetModel extends GeneratedHostSetModel { }) host_ids; + @fragmentArray('fragment-string', { + emptyArrayIfMissing: true, + }) + preferred_endpoints; + + // AWS specific + @fragmentArray('fragment-string', { + emptyArrayIfMissing: true, + isNestedAttribute: true, + }) + filters; + // =methods /** diff --git a/addons/api/addon/serializers/host-set.js b/addons/api/addon/serializers/host-set.js index f0e0c25ad..613caf1ab 100644 --- a/addons/api/addon/serializers/host-set.js +++ b/addons/api/addon/serializers/host-set.js @@ -1,5 +1,9 @@ import ApplicationSerializer from './application'; +const fieldByType = { + aws: ['preferred_endpoints', 'filters'], + azure: ['preferred_endpoints', 'filter'], +}; export default class HostSetSerializer extends ApplicationSerializer { // =properties @@ -19,10 +23,17 @@ export default class HostSetSerializer extends ApplicationSerializer { * @return {object} */ serialize(snapshot) { - let serialized = super.serialize(...arguments); const hostIDs = snapshot?.adapterOptions?.hostIDs; - if (hostIDs) serialized = this.serializeWithHostIDs(snapshot, hostIDs); - return serialized; + if (hostIDs) { + return this.serializeWithHostIDs(snapshot, hostIDs); + } else { + switch (snapshot.record.compositeType) { + case 'static': + return this.serializeStatic(...arguments); + default: + return super.serialize(...arguments); + } + } } /** @@ -37,4 +48,25 @@ export default class HostSetSerializer extends ApplicationSerializer { host_ids: hostIDs, }; } + + serializeStatic() { + let serialized = super.serialize(...arguments); + // Delete unnecessary fields for static type + delete serialized.attributes; + delete serialized.preferred_endpoints; + return serialized; + } + + serializeAttribute(snapshot, json, key, attribute) { + const value = super.serializeAttribute(...arguments); + const { isPlugin, compositeType } = snapshot.record; + const { options } = attribute; + + if (isPlugin && options.isNestedAttribute) { + if (!fieldByType[compositeType].includes(key)) { + delete json.attributes[key]; + } + } + return value; + } } diff --git a/addons/api/mirage/factories/host-set.js b/addons/api/mirage/factories/host-set.js index 35b26e560..038bf6a7c 100644 --- a/addons/api/mirage/factories/host-set.js +++ b/addons/api/mirage/factories/host-set.js @@ -1,5 +1,6 @@ import factory from '../generated/factories/host-set'; import permissions from '../helpers/permissions'; +import { datatype, internet, database } from 'faker'; export default factory.extend({ id: (i) => `host-set-id-${i}`, @@ -18,4 +19,31 @@ export default factory.extend({ return this.hostCatalog.plugin; } }, + preferred_endpoints() { + if (this.type === 'plugin') { + const enpointsAmount = datatype.number({ min: 1, max: 5 }); + let result = []; + for (let i = 0; i < enpointsAmount; ++i) { + result.push(internet.ip()); + } + return result; + } + }, + // AWS specific + filters() { + if (this.plugin?.name === 'aws') { + const filtersAmount = datatype.number({ min: 1, max: 5 }); + let result = []; + for (let i = 0; i < filtersAmount; ++i) { + result.push(`${datatype.string(3)}=${datatype.string(8)}`); + } + return result; + } + }, + // Azure specific + filter() { + if (this.plugin?.name === 'azure') { + return `${database.column}=${database.collation}`; + } + }, }); diff --git a/addons/api/tests/unit/serializers/host-set-test.js b/addons/api/tests/unit/serializers/host-set-test.js index 9c5c8136e..edb98d519 100644 --- a/addons/api/tests/unit/serializers/host-set-test.js +++ b/addons/api/tests/unit/serializers/host-set-test.js @@ -7,17 +7,14 @@ module('Unit | Serializer | host set', function (hooks) { test('it serializes host sets normally, without host_ids', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const serializer = store.serializerFor('host-set'); const record = store.createRecord('host-set', { name: 'Host Set 1', + compositeType: 'static', description: 'Description', host_catalog_id: '123', version: 1, }); - const snapshot = record._createSnapshot(); - snapshot.adapterOptions = {}; - const serializedRecord = serializer.serialize(snapshot); - assert.deepEqual(serializedRecord, { + assert.deepEqual(record.serialize(), { name: 'Host Set 1', description: 'Description', host_catalog_id: '123', @@ -46,6 +43,54 @@ module('Unit | Serializer | host set', function (hooks) { }); }); + test('it serializes host sets as expected for Aws plugin', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const record = store.createRecord('host-set', { + name: 'Host Set 1', + compositeType: 'aws', + description: 'Description', + host_catalog_id: '123', + version: 1, + preferred_endpoints: [{ value: 'option 1' }, { value: 'option 2' }], + filters: [{ value: 'filter 1' }, { value: 'filter 2' }], + }); + assert.deepEqual(record.serialize(), { + name: 'Host Set 1', + description: 'Description', + host_catalog_id: '123', + version: 1, + preferred_endpoints: ['option 1', 'option 2'], + attributes: { + filters: ['filter 1', 'filter 2'], + }, + }); + }); + + test('it serializes host sets as expected for Azure plugin', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const record = store.createRecord('host-set', { + name: 'Host Set 1', + compositeType: 'azure', + description: 'Description', + host_catalog_id: '123', + version: 1, + preferred_endpoints: [{ value: 'option 1' }, { value: 'option 2' }], + filter: 'filter 1 && filter 2', + }); + assert.deepEqual(record.serialize(), { + name: 'Host Set 1', + description: 'Description', + host_catalog_id: '123', + version: 1, + preferred_endpoints: ['option 1', 'option 2'], + attributes: { + filter: 'filter 1 && filter 2', + }, + }); + }); + test('it normalizes records with array fields', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); @@ -54,22 +99,32 @@ module('Unit | Serializer | host set', function (hooks) { const payload = { id: '1', name: 'Host Set 1', + type: 'static', host_ids: ['1', '2', '3'], + preferred_endpoints: ['endpoint 1', 'endpoint 2'], + filters: ['filter 1', 'filter 2'], }; const normalized = serializer.normalizeSingleResponse( store, hostSetModelClass, payload ); + assert.deepEqual(normalized, { included: [], data: { id: '1', type: 'host-set', attributes: { + type: 'static', authorized_actions: [], name: 'Host Set 1', host_ids: [{ value: '1' }, { value: '2' }, { value: '3' }], + preferred_endpoints: [ + { value: 'endpoint 1' }, + { value: 'endpoint 2' }, + ], + filters: [{ value: 'filter 1' }, { value: 'filter 2' }], }, relationships: {}, }, @@ -101,6 +156,41 @@ module('Unit | Serializer | host set', function (hooks) { name: 'Host Set 1', scope: { scope_id: 'o_123' }, host_ids: [], + preferred_endpoints: [], + filters: [], + }, + relationships: {}, + }, + }); + }); + + test('it normalizes missing array fields to empty array', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-set'); + const hostSet = store.createRecord('host-set').constructor; + const payload = { + id: '1', + name: 'Host Set 1', + scope: { id: 'o_123' }, + }; + const normalized = serializer.normalizeSingleResponse( + store, + hostSet, + payload + ); + assert.deepEqual(normalized, { + included: [], + data: { + id: '1', + type: 'host-set', + attributes: { + authorized_actions: [], + name: 'Host Set 1', + scope: { scope_id: 'o_123' }, + host_ids: [], + preferred_endpoints: [], + filters: [], }, relationships: {}, },