Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/adapters/REST/endpoints/app-action-call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ async function pollStructuredAppActionCall(

// If backend has not yet written the record, keep polling up to retries
// Otherwise, resolve when status is terminal
if (result?.status === 'succeeded' || result?.status === 'failed') {
if (result?.sys.status === 'succeeded' || result?.sys.status === 'failed') {
resolve(result)
} else if (result?.status === 'processing' && checkCount < retries) {
} else if (result?.sys.status === 'processing' && checkCount < retries) {
checkCount++
await waitFor(retryInterval)
poll()
Expand Down
4 changes: 1 addition & 3 deletions lib/entities/app-action-call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ export type AppActionCallProps = {
* System metadata
*/
sys: AppActionCallSys
status: AppActionCallStatus
result?: JsonValue
error?: AppActionCallErrorProps
}

export type CreateAppActionCallProps = {
Expand Down Expand Up @@ -86,6 +83,7 @@ export interface AppActionCallRawResponseProps {
appInstallation: SysLink
appAction: SysLink
createdAt: string
createdBy: SysLink
}
response: {
headers?: { contentType?: string }
Expand Down
36 changes: 17 additions & 19 deletions test/unit/adapters/REST/endpoints/app-action-call.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ function setup(promise, mockName, params = {}) {
}

describe('Rest App Action Call', { concurrent: true }, () => {
it('should get structured App Action Call via new route', async () => {
it('should get structured App Action Call', async () => {
const structuredCall: any = {
sys: { id: 'call-id', type: 'AppActionCall' },
status: 'processing',
sys: { id: 'call-id', type: 'AppActionCall', status: 'processing' },
}

const { httpMock } = setup(Promise.resolve({ data: structuredCall }), 'appActionCallResponse')
Expand All @@ -38,7 +37,7 @@ describe('Rest App Action Call', { concurrent: true }, () => {
)
})

it('should get raw response via new route', async () => {
it('should get raw response', async () => {
const rawResponse: any = {
sys: { id: 'call-id', type: 'AppActionCallResponse' },
response: { body: 'OK', headers: { contentType: 'application/json' } },
Expand All @@ -61,16 +60,13 @@ describe('Rest App Action Call', { concurrent: true }, () => {
})

it('should create with result and poll until completion', async () => {
// First POST returns the created call with sys.id; then GET returns processing, then succeeded
const createdCall: any = { sys: { id: 'call-id', type: 'AppActionCall' } }
const processing: any = { sys: { id: 'call-id', type: 'AppActionCall' }, status: 'processing' }
// First POST and next GET returns processing call with sys.id; , then succeeded
const processing: any = { sys: { id: 'call-id', type: 'AppActionCall', status: 'processing' } }
const succeeded: any = {
sys: { id: 'call-id', type: 'AppActionCall' },
status: 'succeeded',
result: { ok: true },
sys: { id: 'call-id', type: 'AppActionCall', status: 'succeeded', result: { ok: true } },
}

const { httpMock } = setup(Promise.resolve({ data: createdCall }), 'appActionCallResponse')
const { httpMock } = setup(Promise.resolve({ data: processing }), 'appActionCallResponse')

httpMock.get
.mockImplementationOnce(() => Promise.resolve({ data: processing }))
Expand Down Expand Up @@ -105,10 +101,9 @@ describe('Rest App Action Call', { concurrent: true }, () => {
})

it('createWithResult times out when status stays processing', async () => {
const createdCall: any = { sys: { id: 'call-id', type: 'AppActionCall' } }
const processing: any = { sys: { id: 'call-id', type: 'AppActionCall' }, status: 'processing' }
const processing: any = { sys: { id: 'call-id', type: 'AppActionCall', status: 'processing' } }

const { httpMock } = setup(Promise.resolve({ data: createdCall }), 'appActionCallResponse')
const { httpMock } = setup(Promise.resolve({ data: processing }), 'appActionCallResponse')

// Always return processing to trigger timeout
httpMock.get.mockImplementation(() => Promise.resolve({ data: processing }))
Expand Down Expand Up @@ -140,11 +135,14 @@ describe('Rest App Action Call', { concurrent: true }, () => {
})

it('createWithResult resolves with failed status and error intact', async () => {
const createdCall: any = { sys: { id: 'call-id', type: 'AppActionCall' } }
const createdCall: any = { sys: { id: 'call-id', type: 'AppActionCall', status: 'processing' } }
const failed: any = {
sys: { id: 'call-id', type: 'AppActionCall' },
status: 'failed',
error: { sys: { type: 'Error', id: 'ValidationError' }, message: 'invalid' },
sys: {
id: 'call-id',
type: 'AppActionCall',
status: 'failed',
error: { sys: { type: 'Error', id: 'ValidationError' }, message: 'invalid' },
},
}

const { httpMock } = setup(Promise.resolve({ data: createdCall }), 'appActionCallResponse')
Expand All @@ -167,7 +165,7 @@ describe('Rest App Action Call', { concurrent: true }, () => {
})

it('createWithResult retries on thrown GET errors then times out', async () => {
const createdCall: any = { sys: { id: 'call-id', type: 'AppActionCall' } }
const createdCall: any = { sys: { id: 'call-id', type: 'AppActionCall', status: 'processing' } }
const { httpMock } = setup(Promise.resolve({ data: createdCall }), 'appActionCallResponse')

httpMock.get.mockRejectedValue(new Error('not ready'))
Expand Down