diff --git a/addons/api/addon/models/worker.js b/addons/api/addon/models/worker.js index 7afec8f8d..8cd0d8bdb 100644 --- a/addons/api/addon/models/worker.js +++ b/addons/api/addon/models/worker.js @@ -27,15 +27,14 @@ export default class WorkerModel extends GeneratedWorkerModel { } /** - * Returns the number of config tags present on the worker. + * Returns the number of canonical tags present on the worker. * @type {number} */ get tagCount() { - if (!this.config_tags) { + if (!this.canonical_tags) { return 0; } - - return Object.values(this.config_tags).reduce( + return Object.values(this.canonical_tags).reduce( (previousCount, currentTags) => previousCount + currentTags.length, 0, ); @@ -45,16 +44,38 @@ export default class WorkerModel extends GeneratedWorkerModel { * Returns the config tags as an array of key/value pair objects. * @type {[object]} */ - getConfigTagList() { + get configTagList() { if (!this.config_tags) { return null; } return Object.entries(this.config_tags).flatMap(([key, value]) => - value.map((tag) => ({ key, value: tag })), + value.map((tag) => ({ key, value: tag, type: 'config' })), ); } + /** + * Returns the api tags as an array of key/value pair objects. + * @type {[object]} + */ + get apiTagList() { + if (!this.api_tags) { + return null; + } + + return Object.entries(this.api_tags).flatMap(([key, value]) => + value.map((tag) => ({ key, value: tag, type: 'api' })), + ); + } + + /** + * Returns all tags as an array of key/value pair objects with tag type. + * @type {[object]} + */ + get allTags() { + return [...(this.configTagList ?? []), ...(this.apiTagList ?? [])]; + } + @attr({ description: 'The deduplicated union of the tags reported by the worker ' + @@ -70,6 +91,12 @@ export default class WorkerModel extends GeneratedWorkerModel { }) config_tags; + @attr({ + description: 'The api tags set for the worker.\nOutput only.', + readOnly: true, + }) + api_tags; + /** * Method to modify the adapter to handle custom POST route for creating worker. * @param {string} workerGeneratedAuthToken diff --git a/addons/api/tests/unit/models/worker-test.js b/addons/api/tests/unit/models/worker-test.js index 2bc4922cd..83009c6e4 100644 --- a/addons/api/tests/unit/models/worker-test.js +++ b/addons/api/tests/unit/models/worker-test.js @@ -32,8 +32,108 @@ module('Unit | Model | worker', function (hooks) { type: 'global', }, }); + await model.createWorkerLed(workerGeneratedAuthToken); const worker = store.peekRecord('worker', '123abc'); + assert.ok(worker); }); + + test('it has a `configTagList` method that returns an array of key/value pair objects', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker', { + config_tags: { + tag1: ['value1', 'value2'], + tag2: ['value3'], + }, + }); + const expected = [ + { key: 'tag1', value: 'value1', type: 'config' }, + { key: 'tag1', value: 'value2', type: 'config' }, + { key: 'tag2', value: 'value3', type: 'config' }, + ]; + + assert.deepEqual(model.configTagList, expected); + }); + + test('it has a `configTagList` method that returns null if there are no config tags', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker'); + + assert.deepEqual(model.configTagList, null); + }); + + test('it has a `apiTagList` method that returns an array of key/value pair objects', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker', { + api_tags: { + tag1: ['value1', 'value2'], + tag2: ['value3'], + }, + }); + const expected = [ + { key: 'tag1', value: 'value1', type: 'api' }, + { key: 'tag1', value: 'value2', type: 'api' }, + { key: 'tag2', value: 'value3', type: 'api' }, + ]; + + assert.deepEqual(model.apiTagList, expected); + }); + + test('it has a `apiTagList` method that returns null if there are no api tags', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker'); + + assert.deepEqual(model.apiTagList, null); + }); + + test('it has a `allTags` method that returns an array of key/value pair objects with tag type', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker', { + config_tags: { + tag1: ['value1', 'value2'], + tag2: ['value3'], + }, + api_tags: { + tag1: ['value1', 'value2'], + tag2: ['value3'], + }, + }); + const expected = [ + { key: 'tag1', value: 'value1', type: 'config' }, + { key: 'tag1', value: 'value2', type: 'config' }, + { key: 'tag2', value: 'value3', type: 'config' }, + { key: 'tag1', value: 'value1', type: 'api' }, + { key: 'tag1', value: 'value2', type: 'api' }, + { key: 'tag2', value: 'value3', type: 'api' }, + ]; + + assert.deepEqual(model.allTags, expected); + }); + + test('it has a `allTags` method that returns an empty array if there are no config or api tags', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker'); + + assert.deepEqual(model.allTags, []); + }); + + test('tagCount returns the total number of tags', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker', { + canonical_tags: { + tag1: ['value1', 'value2'], + tag2: ['value3'], + }, + }); + + assert.strictEqual(model.tagCount, 3); + }); + + test('tagCount returns 0 if there are no tags', function (assert) { + const store = this.owner.lookup('service:store'); + const model = store.createRecord('worker'); + + assert.strictEqual(model.tagCount, 0); + }); }); diff --git a/ui/admin/app/routes/scopes/scope/workers/index.js b/ui/admin/app/routes/scopes/scope/workers/index.js index b7029c6db..401f573de 100644 --- a/ui/admin/app/routes/scopes/scope/workers/index.js +++ b/ui/admin/app/routes/scopes/scope/workers/index.js @@ -19,7 +19,7 @@ export default class ScopesScopeWorkersIndexRoute extends Route { allowed: (route) => { const configTags = route .modelFor('scopes.scope.workers') - .flatMap((worker) => worker.getConfigTagList()) + .flatMap((worker) => worker.configTagList) .filter(Boolean); // Filter out duplicate tags @@ -56,7 +56,7 @@ export default class ScopesScopeWorkersIndexRoute extends Route { return null; } - const workerTags = worker.getConfigTagList(); + const workerTags = worker.configTagList; return this.tags.some((tag) => workerTags.some( (workerTag) =>