Skip to content

Commit

Permalink
feat: implement describeMedia method
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyentoanit committed Feb 13, 2021
1 parent 9155e3a commit 17d4ae5
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/operations/media/sponsored-brands-media-operation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Operation } from '../operation'
import { CompleteMediaParam, CreateUploadLocaltionParam, MediaId, UploadLocation } from './types'
import {
CompleteMediaParam,
CreateUploadLocaltionParam,
MediaId,
MediaResource,
UploadLocation,
} from './types'
import { Decode } from '../../decorators'

export class SponsoredBrandsMediaOperation extends Operation {
Expand Down Expand Up @@ -30,4 +36,16 @@ export class SponsoredBrandsMediaOperation extends Operation {
public completeMedia(param: CompleteMediaParam) {
return this.client.put<MediaId>(`${this.resource}/complete`, param)
}

/**
* API to poll for media status.
* In order to attach media to campaign, media should be in either PendingDeepValidation or Available status.
* Available status guarantees that media has completed processing and published for usage.
* Though media can be attached to campaign once the status of the media transitions to PendingDeepValidation, media could still fail additional validation and transition to Failed status.
* For example in the context of SBV, SBV campaign can be created when status transitions to PendingDeepValidation, it could result in SBV campaign to be rejected later if media transitions to Failed status.
*/
@Decode(MediaResource)
public describeMedia(mediaId: MediaId) {
return this.client.get<MediaResource>(this.paramsFilterTransformer('/describe', { mediaId }))
}
}
27 changes: 27 additions & 0 deletions src/operations/media/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,30 @@ describe('CompleteMediaParam', () => {
expect(isRight(res)).toBeTruthy()
})
})

describe('MediaResource', () => {
it('should pass', () => {
const res = t.MediaResource.decode({
mediaId: 'string',
status: 'Processing',
statusMetadata: [
{
code: 'string',
message: 'string',
},
],
publishedMediaUrl: 'string',
})

expect(isRight(res)).toBeTruthy()
})

it('should pass without optional paramaters', () => {
const res = t.MediaResource.decode({
mediaId: 'string',
status: 'Processing',
})

expect(isRight(res)).toBeTruthy()
})
})
61 changes: 61 additions & 0 deletions src/operations/media/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,64 @@ export type CompleteMediaParam = t.TypeOf<typeof CompleteMediaParam>
*/
export const MediaId = t.string
export type MediaId = t.TypeOf<typeof MediaId>

export const MediaStatus = t.union([
/**
* The media is being processed.
*/
t.literal('Processing'),

/**
* The media is pending additional validation carried out during media conversion.
*/
t.literal('PendingDeepValidation'),

/**
* Media has successfully finished validation and conversion and the media is published.
*/
t.literal('Available'),

/**
* Media processing failed.
*/
t.literal('Failed'),
])
export type MediaStatus = t.TypeOf<typeof MediaStatus>

export const MediaStatusMetadata = t.type({
code: t.string,
message: t.string,
})
export type MediaStatusMetadata = t.TypeOf<typeof MediaStatusMetadata>

/**
* Media Resource.
*/
export const MediaResource = t.intersection([
t.type({
/**
* The Media identifier.
*/
mediaId: MediaId,

/**
* Media status.
*/
status: MediaStatus,
}),
t.partial({
/**
* Additional status metadata.
* It is only available when status is Failed and statusMetadata provides additional detail on why media status is Failed.
* statusMetadata is comprised of code and message.
*/
statusMetadata: t.array(MediaStatusMetadata),

/**
* The preview URL of the media.
* It is only available when status is Available.
*/
publishedMediaUrl: t.string,
}),
])
export type MediaResource = t.TypeOf<typeof MediaResource>
38 changes: 38 additions & 0 deletions test/operations/media/sponsored-brands-media-operation.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
CompleteMediaParam,
CreateUploadLocaltionParam,
MediaId,
SponsoredBrandsMediaOperation,
} from '../../../src'
import { OperationProvider } from '../../../src/operations/operation-provider'
Expand Down Expand Up @@ -44,4 +45,41 @@ describe('SponsoredBrandsMediaOperation', () => {
expect(res).toBeDefined()
})
})

/**
* TODO: Need check on Production API again. Sandbox API return an error:
* ResourceNotFoundError: Could not find resource for full path: https://advertising-api-test.amazon.com/v2/media/describe?mediaId=ABC
*/
describe.skip('describeMedia', () => {
it(`should retrieve media resource by media id`, async () => {
const mediaId: MediaId = 'ABC'
const res = await operation.describeMedia(mediaId)

expect(res.mediaId).toBe(mediaId)
})

it(`should retrieve meta data when media status is failed `, async () => {
expect.assertions(2)

const mediaId: MediaId = 'ABC'
const res = await operation.describeMedia(mediaId)

expect(res.mediaId).toBe(mediaId)
if (res.status === 'Failed') {
expect(res).toHaveProperty('statusMetadata')
}
})

it(`should retrieve published media url when media status is available `, async () => {
expect.assertions(2)

const mediaId: MediaId = 'ABC'
const res = await operation.describeMedia(mediaId)

expect(res.mediaId).toBe(mediaId)
if (res.status === 'Available') {
expect(res).toHaveProperty('publishedMediaUrl')
}
})
})
})

0 comments on commit 17d4ae5

Please sign in to comment.