From 3374abeed77a93fd05a2363eac125bdf55b246b8 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Wed, 7 Apr 2021 19:02:52 +0300 Subject: [PATCH] application.get: Add support for retrieving applications by uuid Resolves: #1016 Change-type: minor Signed-off-by: Thodoris Greasidis --- lib/models/application.ts | 41 ++++++++++---------- tests/integration/models/application.spec.ts | 6 ++- tests/integration/setup.ts | 6 ++- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/models/application.ts b/lib/models/application.ts index d8d86dca0..80091223f 100644 --- a/lib/models/application.ts +++ b/lib/models/application.ts @@ -271,7 +271,7 @@ const getApplicationModel = function ( * @function * @memberof balena.models.application * - * @param {String|Number} slugOrId - application slug (string) or id (number) + * @param {String|Number} slugOrUuidOrId - application slug (string), uuid (string) or id (number) * @param {Object} [options={}] - extra pine options to use * @param {String} [context] - extra access filters, undefined or 'directly_accessible' * @fulfil {Object} - application @@ -283,6 +283,11 @@ const getApplicationModel = function ( * }); * * @example + * balena.models.application.get('1bf99a68cf9e4266986e6dec7a6e8f46').then(function(application) { + * console.log(application); + * }); + * + * @example * balena.models.application.get(123).then(function(application) { * console.log(application); * }); @@ -294,17 +299,11 @@ const getApplicationModel = function ( * }); */ async get( - slugOrId: string | number, + slugOrUuidOrId: string | number, options?: PineOptions, context?: 'directly_accessible', ): Promise { - if (options == null) { - options = {}; - } - - if (slugOrId == null) { - throw new errors.BalenaApplicationNotFound(slugOrId); - } + options ??= {}; const accessFilter = context === 'directly_accessible' @@ -312,40 +311,40 @@ const getApplicationModel = function ( : null; let application; - if (isId(slugOrId)) { + if (isId(slugOrUuidOrId)) { application = await pine.get({ resource: 'application', - id: slugOrId, + id: slugOrUuidOrId, options: mergePineOptions( accessFilter != null ? { $filter: accessFilter } : {}, options, ), }); - if (application == null) { - throw new errors.BalenaApplicationNotFound(slugOrId); - } - } else { + } else if (typeof slugOrUuidOrId === 'string') { + const lowerCaseSlugOrUuid = slugOrUuidOrId.toLowerCase(); const applications = await pine.get({ resource: 'application', options: mergePineOptions( { $filter: { ...accessFilter, - slug: slugOrId.toLowerCase(), + $or: { + slug: lowerCaseSlugOrUuid, + uuid: lowerCaseSlugOrUuid, + }, }, }, options, ), }); - if (applications.length === 0) { - throw new errors.BalenaApplicationNotFound(slugOrId); - } - if (applications.length > 1) { - throw new errors.BalenaAmbiguousApplication(slugOrId); + throw new errors.BalenaAmbiguousApplication(slugOrUuidOrId); } application = applications[0]; } + if (application == null) { + throw new errors.BalenaApplicationNotFound(slugOrUuidOrId); + } return normalizeApplication(application); }, diff --git a/tests/integration/models/application.spec.ts b/tests/integration/models/application.spec.ts index 8efe64761..33bda3513 100644 --- a/tests/integration/models/application.spec.ts +++ b/tests/integration/models/application.spec.ts @@ -1764,7 +1764,7 @@ describe('Application Model', function () { before(async function () { const [app] = await balena.models.application.getAll({ $top: 1, - $select: ['id', 'app_name', 'slug', 'is_public'], + $select: ['id', 'app_name', 'slug', 'uuid', 'is_public'], $filter: { is_public: true }, }); expect(app).to.have.property('is_public', true); @@ -1901,7 +1901,7 @@ describe('Application Model', function () { .get({ resource: 'application', options: { - $select: ['id', 'app_name', 'slug', 'is_public'], + $select: ['id', 'app_name', 'slug', 'uuid', 'is_public'], }, }) .then(function (apps) { @@ -1914,6 +1914,7 @@ describe('Application Model', function () { expect(app).to.have.property('id').that.is.a('number'); expect(app).to.have.property('app_name').that.is.a('string'); expect(app).to.have.property('slug').that.is.a('string'); + expect(app).to.have.property('uuid').that.is.a('string'); expect(app).to.have.property('is_public', true); }); }); @@ -1931,6 +1932,7 @@ describe('Application Model', function () { expect(app).to.have.property('id').that.is.a('number'); expect(app).to.have.property('app_name').that.is.a('string'); expect(app).to.have.property('slug').that.is.a('string'); + expect(app).to.have.property('uuid').that.is.a('string'); expect(app).to.have.property('is_public', true); }); }, diff --git a/tests/integration/setup.ts b/tests/integration/setup.ts index 4a71e8f95..21b8dbb59 100644 --- a/tests/integration/setup.ts +++ b/tests/integration/setup.ts @@ -623,5 +623,9 @@ export function givenASupervisorRelease( }); } -export const applicationRetrievalFields = toWritable(['id', 'slug'] as const); +export const applicationRetrievalFields = toWritable([ + 'id', + 'slug', + 'uuid', +] as const); export const deviceUniqueFields = toWritable(['id', 'uuid'] as const);