refactor: 💡 convert brokered cred IDs array to simple attribute (#1259)
* refactor: 💡 convert brokered cred IDs array to simple attribute * fix: 🐛 missing test assertion * fix: 🐛 simplify computed * refactor: 💡 convert host sources array to simple attribute (#1260) * refactor: 💡 convert host source IDs array to simple attribute * fix: 🐛 host source tests * Refactor role fragment arrays (#1262) * refactor: 💡 convert grant strings to regular attribute * refactor: 💡 convert principals array to simple attribute * Update ui/admin/app/routes/scopes/scope/roles/role.js Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com> Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com> Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com> * fix: 🐛 remove unused import Co-authored-by: Zhihe Li <zhihe.li@hashicorp.com>
This commit is contained in:
1 parent
83c7b76f48
commit
cde6abd445
28 files changed
+147
-182
No files matched your search
@@ -1,16 +0,0 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class FragmentHostSourceModel extends Fragment {
|
||||
// =attributes
|
||||
|
||||
@attr('string', {
|
||||
description: 'ID of the related host source',
|
||||
})
|
||||
host_source_id;
|
||||
|
||||
@attr('string', {
|
||||
description: 'ID of the catalog to which the host set belongs',
|
||||
})
|
||||
host_catalog_id;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import Fragment from 'ember-data-model-fragments/fragment';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class FragmentPrincipal extends Fragment {
|
||||
// =attributes
|
||||
|
||||
@attr('string', {
|
||||
description: 'ID of the related scope',
|
||||
})
|
||||
scope_id;
|
||||
|
||||
@attr('string', {
|
||||
description: 'ID of the related principal (user or group)',
|
||||
})
|
||||
principal_id;
|
||||
|
||||
@attr('string', {
|
||||
description: 'Type of the related principal (user or group)',
|
||||
})
|
||||
type;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import GeneratedRoleModel from '../generated/models/role';
|
||||
import { fragmentArray, array } from 'ember-data-model-fragments/attributes';
|
||||
import { attr } from '@ember-data/model';
|
||||
|
||||
export default class RoleModel extends GeneratedRoleModel {
|
||||
// =attributes
|
||||
@@ -11,7 +11,7 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
* see obvious. Instead, the application layer is expected to load referenced
|
||||
* users and groups as needed.
|
||||
*/
|
||||
@fragmentArray('fragment-principal', {
|
||||
@attr('principal-array', {
|
||||
readOnly: true,
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
@@ -21,7 +21,7 @@ export default class RoleModel extends GeneratedRoleModel {
|
||||
* Grant strings are read-only. But grants can be persisted via a dedicated
|
||||
* call to `saveGrantStrings(grants)`.
|
||||
*/
|
||||
@array('string', { readOnly: true }) grant_strings;
|
||||
@attr({ readOnly: true, emptyArrayIfMissing: true }) grant_strings;
|
||||
|
||||
/**
|
||||
* Convenience for looking up the grant scope, if loaded.
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import GeneratedTargetModel from '../generated/models/target';
|
||||
import { attr } from '@ember-data/model';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
import { computed } from '@ember/object';
|
||||
|
||||
export default class TargetModel extends GeneratedTargetModel {
|
||||
// =attributes
|
||||
|
||||
@attr('number', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The default port a target should use if present.',
|
||||
description: 'The default port a target should use if present.',
|
||||
})
|
||||
default_port;
|
||||
|
||||
/**
|
||||
* @type {[FragmentHostSourceModel]}
|
||||
* @type Array
|
||||
*/
|
||||
@fragmentArray('fragment-host-source', {
|
||||
@attr('host-source-id-array', {
|
||||
readOnly: true,
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
@@ -25,7 +23,7 @@ export default class TargetModel extends GeneratedTargetModel {
|
||||
* Credential source ids are read only and can be
|
||||
* persisted via a dedicated call to `addBrokeredCredentialSources()`.
|
||||
*/
|
||||
@fragmentArray('fragment-string', {
|
||||
@attr('string-array', {
|
||||
readOnly: true,
|
||||
emptyArrayIfMissing: true,
|
||||
})
|
||||
@@ -37,7 +35,6 @@ export default class TargetModel extends GeneratedTargetModel {
|
||||
* instances). Unresolvable instances are excluded from the array.
|
||||
* @type {[{model: HostSetModel, hostCatalog: HostCatalogModel}]}
|
||||
*/
|
||||
@computed('host_sources.[]', 'store')
|
||||
get hostSets() {
|
||||
return this.host_sources
|
||||
.map(({ host_source_id, host_catalog_id }) => ({
|
||||
@@ -53,7 +50,6 @@ export default class TargetModel extends GeneratedTargetModel {
|
||||
* instances). Unresolvable instances are excluded from the array.
|
||||
* @type {[CredentialLibraryModel, CredentialModel]}
|
||||
*/
|
||||
@computed('brokered_credential_source_ids.[]', 'store')
|
||||
get brokeredCredentialSources() {
|
||||
return this.brokered_credential_source_ids
|
||||
.map((source) => {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentHostSourceSerializer extends JSONSerializer {
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Renames `id` to `host_source_id` because fragments may not have IDs.
|
||||
* Otherwise normalizes as normal.
|
||||
* @param {ModelClass} typeClass
|
||||
* @param {object} resourceHash
|
||||
* @return {object}
|
||||
*/
|
||||
normalize(typeClass, { id: host_source_id, ...obj }) {
|
||||
return super.normalize(typeClass, { host_source_id, ...obj });
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import JSONSerializer from '@ember-data/serializer/json';
|
||||
|
||||
export default class FragmentPrincipalSerializer extends JSONSerializer {
|
||||
// =methods
|
||||
|
||||
/**
|
||||
* Renames `id` to `principal_id` because fragments may not have IDs.
|
||||
* Otherwise normalizes as normal.
|
||||
* @param {ModelClass} typeClass
|
||||
* @param {object} resourceHash
|
||||
* @return {object}
|
||||
*/
|
||||
normalize(typeClass, { id: principal_id, ...obj }) {
|
||||
return super.normalize(typeClass, { principal_id, ...obj });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import Transform from '@ember-data/serializer/transform';
|
||||
|
||||
export default class HostSourceIdArrayTransform extends Transform {
|
||||
deserialize(serialized) {
|
||||
const stringValues = serialized || [];
|
||||
return stringValues.map(({ id: host_source_id, ...obj }) => ({
|
||||
host_source_id,
|
||||
...obj,
|
||||
}));
|
||||
}
|
||||
|
||||
serialize(deserialized) {
|
||||
const strings = deserialized || [];
|
||||
return strings.map(({ host_source_id: id, ...obj }) => ({ id, ...obj }));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import Transform from '@ember-data/serializer/transform';
|
||||
|
||||
export default class PrincipalArrayTransform extends Transform {
|
||||
deserialize(serialized) {
|
||||
const stringValues = serialized || [];
|
||||
return stringValues.map(({ id: principal_id, scope_id, type }) => ({
|
||||
principal_id,
|
||||
scope_id,
|
||||
type,
|
||||
}));
|
||||
}
|
||||
|
||||
serialize(deserialized) {
|
||||
const strings = deserialized || [];
|
||||
return strings.map(({ principal_id: id, scope_id, type }) => ({
|
||||
id,
|
||||
scope_id,
|
||||
type,
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import Transform from '@ember-data/serializer/transform';
|
||||
|
||||
export default class StringArrayTransform extends Transform {
|
||||
deserialize(serialized) {
|
||||
const stringValues = serialized || [];
|
||||
return stringValues.map((value) => ({ value }));
|
||||
}
|
||||
|
||||
serialize(deserialized) {
|
||||
const strings = deserialized || [];
|
||||
return strings.map(({ value }) => value);
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/models/fragment-host-source';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/models/fragment-principal';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/serializers/fragment-host-source';
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from 'api/serializers/fragment-principal';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/transforms/host-source-id-array';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/transforms/principal-array';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'api/transforms/string-array';
|
||||
@@ -1,12 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Model | fragment host source', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('fragment-host-source', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Model | fragment principal', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('fragment-principal', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
@@ -46,10 +46,6 @@ module('Unit | Model | target', function (hooks) {
|
||||
attributes: {},
|
||||
},
|
||||
});
|
||||
// Since `hostSets` is computed on `host_sources`, not the store itself,
|
||||
// it's necessary to do this assignment to kick-off the computed update.
|
||||
// eslint-disable-next-line no-self-assign
|
||||
target.host_sources = target.host_sources;
|
||||
assert.strictEqual(
|
||||
target.host_sources.length,
|
||||
2,
|
||||
@@ -252,7 +248,7 @@ module('Unit | Model | target', function (hooks) {
|
||||
assert.strictEqual(
|
||||
target.brokeredCredentialSources.length,
|
||||
0,
|
||||
'Target has no resolved credentialSources because they are not loaded yet'
|
||||
'Target has no resolved credentialSources, because they are not yet loaded'
|
||||
);
|
||||
store.push({
|
||||
data: {
|
||||
@@ -268,12 +264,6 @@ module('Unit | Model | target', function (hooks) {
|
||||
attributes: {},
|
||||
},
|
||||
});
|
||||
// Since `credentialSources` is computed on `brokered_credential_source_ids`,
|
||||
// not the store itself, it's necessary to do this assignment to kick-off the
|
||||
// computed update.
|
||||
/* eslint-disable no-self-assign */
|
||||
target.brokered_credential_source_ids =
|
||||
target.brokered_credential_source_ids;
|
||||
/* eslint-enable no-self-assign */
|
||||
assert.strictEqual(
|
||||
target.brokered_credential_source_ids.length,
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import FragmentHostSource from 'api/models/fragment-host-source';
|
||||
|
||||
module('Unit | Serializer | fragment host source', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it normalizes `id` into `host_source_id`', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const serializer = store.serializerFor('fragment-host-source');
|
||||
const normalized = serializer.normalize(FragmentHostSource, {
|
||||
id: '2',
|
||||
host_catalog_id: '1',
|
||||
});
|
||||
assert.deepEqual(normalized, {
|
||||
data: {
|
||||
attributes: {
|
||||
host_source_id: '2',
|
||||
host_catalog_id: '1',
|
||||
},
|
||||
id: null,
|
||||
relationships: {},
|
||||
type: 'fragment-host-source',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import FragmentPrincipal from 'api/models/fragment-principal';
|
||||
|
||||
module('Unit | Serializer | fragment principal', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it normalizes `id` into `principal_id`', function (assert) {
|
||||
assert.expect(1);
|
||||
const store = this.owner.lookup('service:store');
|
||||
const serializer = store.serializerFor('fragment-principal');
|
||||
const normalized = serializer.normalize(FragmentPrincipal, {
|
||||
scope_id: '1',
|
||||
principal_id: '2',
|
||||
type: 'user',
|
||||
});
|
||||
assert.deepEqual(normalized, {
|
||||
data: {
|
||||
attributes: {
|
||||
scope_id: '1',
|
||||
principal_id: '2',
|
||||
type: 'user',
|
||||
},
|
||||
id: null,
|
||||
relationships: {},
|
||||
type: 'fragment-principal',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -98,6 +98,7 @@ module('Unit | Serializer | role', function (hooks) {
|
||||
name: 'Role 1',
|
||||
scope: { id: 'o_123', scope_id: 'o_123' },
|
||||
principals: [],
|
||||
grant_strings: [],
|
||||
},
|
||||
relationships: {},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Transform | host source id array', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it deserializes an array of strings to an array of `{value}`', function (assert) {
|
||||
assert.expect(1);
|
||||
const transform = this.owner.lookup('transform:host-source-id-array');
|
||||
const deserialized = transform.deserialize([
|
||||
{ id: '123', host_catalog_id: '1' },
|
||||
]);
|
||||
assert.deepEqual(deserialized, [
|
||||
{ host_source_id: '123', host_catalog_id: '1' },
|
||||
]);
|
||||
});
|
||||
|
||||
test('it serializes an array of `{value}` to an array of strings', function (assert) {
|
||||
assert.expect(1);
|
||||
const transform = this.owner.lookup('transform:host-source-id-array');
|
||||
const serialized = transform.serialize([
|
||||
{ host_source_id: '123', host_catalog_id: '1' },
|
||||
]);
|
||||
assert.deepEqual(serialized, [{ id: '123', host_catalog_id: '1' }]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Transform | principal array', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let transform = this.owner.lookup('transform:principal-array');
|
||||
assert.ok(transform);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Transform | string array', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it deserializes an array of strings to an array of `{value}`', function (assert) {
|
||||
assert.expect(1);
|
||||
const transform = this.owner.lookup('transform:string-array');
|
||||
const deserialized = transform.deserialize(['a', 'bee', 'Hello World']);
|
||||
assert.deepEqual(deserialized, [
|
||||
{ value: 'a' },
|
||||
{ value: 'bee' },
|
||||
{ value: 'Hello World' },
|
||||
]);
|
||||
});
|
||||
|
||||
test('it serializes an array of `{value}` to an array of strings', function (assert) {
|
||||
assert.expect(1);
|
||||
const transform = this.owner.lookup('transform:string-array');
|
||||
const serialized = transform.serialize([
|
||||
{ value: 'a' },
|
||||
{ value: 'bee' },
|
||||
{ value: 'Hello World' },
|
||||
]);
|
||||
assert.deepEqual(serialized, ['a', 'bee', 'Hello World']);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user