From 19d8e45d051e9f5c90d73d1a1eceba524c70dabc Mon Sep 17 00:00:00 2001 From: Vladislav Tupikin Date: Mon, 9 Oct 2023 14:06:19 +0300 Subject: [PATCH] [#271]: getAvatarImageByID updated for version2 --- src/clients/baseClient.ts | 2 +- src/version2/avatars.ts | 16 ++++++++++---- src/version2/models/avatarWithDetails.ts | 6 +++++ src/version2/models/index.ts | 1 + src/version2/parameters/getAvatarImageByID.ts | 2 +- src/version3/models/avatarWithDetails.ts | 2 ++ src/version3/models/index.ts | 2 +- tests/integration/version2/avatars.test.ts | 22 +++++++++++++++++++ 8 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 src/version2/models/avatarWithDetails.ts create mode 100644 tests/integration/version2/avatars.test.ts diff --git a/src/clients/baseClient.ts b/src/clients/baseClient.ts index b7df0c8a11..70eb8a8043 100644 --- a/src/clients/baseClient.ts +++ b/src/clients/baseClient.ts @@ -10,7 +10,7 @@ const ATLASSIAN_TOKEN_CHECK_FLAG = 'X-Atlassian-Token'; const ATLASSIAN_TOKEN_CHECK_NOCHECK_VALUE = 'no-check'; export class BaseClient implements Client { - public instance: AxiosInstance; + private instance: AxiosInstance; constructor(protected readonly config: Config) { try { diff --git a/src/version2/avatars.ts b/src/version2/avatars.ts index 8d0d69a668..4b0c5f6f30 100644 --- a/src/version2/avatars.ts +++ b/src/version2/avatars.ts @@ -218,7 +218,7 @@ export class Avatars { * - For custom issue type avatars, _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) * for at least one project the issue type is used in. */ - async getAvatarImageByID( + async getAvatarImageByID( parameters: Parameters.GetAvatarImageByID, callback: Callback, ): Promise; @@ -235,21 +235,29 @@ export class Avatars { * - For custom issue type avatars, _Browse projects_ [project permission](https://confluence.atlassian.com/x/yodKLg) * for at least one project the issue type is used in. */ - async getAvatarImageByID(parameters: Parameters.GetAvatarImageByID, callback?: never): Promise; - async getAvatarImageByID( + async getAvatarImageByID(parameters: Parameters.GetAvatarImageByID, callback?: never): Promise; + async getAvatarImageByID( parameters: Parameters.GetAvatarImageByID, callback?: Callback, ): Promise { const config: RequestConfig = { url: `/rest/api/2/universal_avatar/view/type/${parameters.type}/avatar/${parameters.id}`, method: 'GET', + responseType: 'arraybuffer', params: { size: parameters.size, format: parameters.format, }, }; - return this.client.sendRequest(config, callback); + const { + data: avatar, + headers: { 'content-type': contentTypeWithEncoding }, + } = await this.client.sendRequestFullResponse(config); + + const contentType = contentTypeWithEncoding.split(';')[0].trim(); + + return this.client.handleSuccessResponse({ contentType, avatar }, callback); } /** diff --git a/src/version2/models/avatarWithDetails.ts b/src/version2/models/avatarWithDetails.ts new file mode 100644 index 0000000000..15f5f99071 --- /dev/null +++ b/src/version2/models/avatarWithDetails.ts @@ -0,0 +1,6 @@ +export interface AvatarWithDetails { + /** The content type of the avatar. Expected values include 'image/png', 'image/svg+xml', or any other valid MIME type. */ + contentType: 'image/png' | 'image/svg+xml' | string; + /** The binary representation of the avatar image. */ + avatar: ArrayBuffer; +} diff --git a/src/version2/models/index.ts b/src/version2/models/index.ts index f919287b7a..1eafdef71f 100644 --- a/src/version2/models/index.ts +++ b/src/version2/models/index.ts @@ -33,6 +33,7 @@ export * from './availableWorkflowTriggerTypes'; export * from './avatar'; export * from './avatars'; export * from './avatarUrls'; +export * from './avatarWithDetails'; export * from './bulkChangeOwnerDetails'; export * from './bulkCreateCustomFieldOptionRequest'; export * from './bulkCustomFieldOptionCreateRequest'; diff --git a/src/version2/parameters/getAvatarImageByID.ts b/src/version2/parameters/getAvatarImageByID.ts index f79b53c50b..87f3dba8dc 100644 --- a/src/version2/parameters/getAvatarImageByID.ts +++ b/src/version2/parameters/getAvatarImageByID.ts @@ -2,7 +2,7 @@ export interface GetAvatarImageByID { /** The icon type of the avatar. */ type: string; /** The ID of the avatar. */ - id: number; + id: number | string; /** The size of the avatar image. If not provided the default size is returned. */ size?: 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | string; /** The format to return the avatar image in. If not provided the original content format is returned. */ diff --git a/src/version3/models/avatarWithDetails.ts b/src/version3/models/avatarWithDetails.ts index c5c33da195..15f5f99071 100644 --- a/src/version3/models/avatarWithDetails.ts +++ b/src/version3/models/avatarWithDetails.ts @@ -1,4 +1,6 @@ export interface AvatarWithDetails { + /** The content type of the avatar. Expected values include 'image/png', 'image/svg+xml', or any other valid MIME type. */ contentType: 'image/png' | 'image/svg+xml' | string; + /** The binary representation of the avatar image. */ avatar: ArrayBuffer; } diff --git a/src/version3/models/index.ts b/src/version3/models/index.ts index f4727c85d1..08434ae9f3 100644 --- a/src/version3/models/index.ts +++ b/src/version3/models/index.ts @@ -1,4 +1,3 @@ -export * from './avatarWithDetails'; export * from './actorInput'; export * from './actorsMap'; export * from './addField'; @@ -30,6 +29,7 @@ export * from './availableDashboardGadgetsResponse'; export * from './avatar'; export * from './avatars'; export * from './avatarUrls'; +export * from './avatarWithDetails'; export * from './bulkChangeOwnerDetails'; export * from './bulkCreateCustomFieldOptionRequest'; export * from './bulkCustomFieldOptionCreateRequest'; diff --git a/tests/integration/version2/avatars.test.ts b/tests/integration/version2/avatars.test.ts new file mode 100644 index 0000000000..6cecbfa04f --- /dev/null +++ b/tests/integration/version2/avatars.test.ts @@ -0,0 +1,22 @@ +import { Avatar } from '../../../src/version3/models'; +import { getVersion2Client } from '../utils'; +import test from 'ava'; + +const client = getVersion2Client(); + +let avatar: Avatar | undefined; + +test.serial('should get all system avatars', async t => { + const systemAvatars = await client.avatars.getAllSystemAvatars({ type: 'project' }); + + avatar = systemAvatars.system?.[0]; + + t.truthy(!!avatar); +}); + +test.serial('should return avatar image with contentType', async t => { + const avatarWithDetails = await client.avatars.getAvatarImageByID({ id: avatar!.id, type: 'project' }); + + t.is(avatarWithDetails.contentType, 'image/svg+xml'); + t.truthy(avatarWithDetails.avatar instanceof Uint8Array); +});