mirror of
https://github.com/sasjs/adapter.git
synced 2026-06-08 18:20:20 +00:00
test(viya): migrate execution-tasks tests to runAsTask config
This commit is contained in:
@@ -4,55 +4,120 @@ import type { TestSuite } from '../types'
|
|||||||
|
|
||||||
const tableData: any = { table1: [{ col1: 'first col value' }] }
|
const tableData: any = { table1: [{ col1: 'first col value' }] }
|
||||||
const fileData: any = { table1: [{ col1: 'value with ; semicolon' }] }
|
const fileData: any = { table1: [{ col1: 'value with ; semicolon' }] }
|
||||||
|
const multiTableData: any = {
|
||||||
|
table1: [{ col1: 'first col value' }],
|
||||||
|
table2: [{ col2: 'second table value' }]
|
||||||
|
}
|
||||||
|
const multiFileData: any = {
|
||||||
|
table1: [{ col1: 'value with ; semicolon' }],
|
||||||
|
table2: [{ col2: 'another; value' }]
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskConfig: any = { useComputeApi: null, runAsTask: true }
|
||||||
|
const noTaskConfig: any = { useComputeApi: null, runAsTask: false }
|
||||||
|
|
||||||
export const executionTasksTests = (adapter: SASjs): TestSuite => ({
|
export const executionTasksTests = (adapter: SASjs): TestSuite => ({
|
||||||
name: '_executionTasks=true behaviour',
|
name: 'runAsTask behaviour',
|
||||||
tests: [
|
tests: [
|
||||||
{
|
{
|
||||||
title: 'sends table data in body',
|
title: 'no inputs (runAsTask=false)',
|
||||||
description: 'table payload, no _executionTasks flag',
|
description: 'no payload, runAsTask explicitly disabled',
|
||||||
test: () =>
|
test: () =>
|
||||||
adapter
|
adapter
|
||||||
.request('services/common/sendArr', tableData, {
|
.request('services/common/sendArr', null, noTaskConfig)
|
||||||
useComputeApi: null
|
|
||||||
})
|
|
||||||
.then((res: any) => ({ ok: true, res }))
|
.then((res: any) => ({ ok: true, res }))
|
||||||
.catch((e: any) => ({ ok: false, error: e })),
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
assertion: (res: any) => res?.ok === true
|
assertion: (res: any) => res?.ok === true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'sends table data when _executionTasks=true',
|
title: 'no inputs (runAsTask=true)',
|
||||||
description: 'table payload with _executionTasks=true',
|
description: 'no payload, runAsTask=true via config',
|
||||||
test: () =>
|
test: () =>
|
||||||
adapter
|
adapter
|
||||||
.request('services/common/sendArr&_executionTasks=true', tableData, {
|
.request('services/common/sendArr', null, taskConfig)
|
||||||
useComputeApi: null
|
|
||||||
})
|
|
||||||
.then((res: any) => ({ ok: true, res }))
|
.then((res: any) => ({ ok: true, res }))
|
||||||
.catch((e: any) => ({ ok: false, error: e })),
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
assertion: (res: any) => res?.ok === true
|
assertion: (res: any) => res?.ok === true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'uploads as file when payload has semicolons',
|
title: 'one input table (runAsTask=false)',
|
||||||
description: 'semicolon payload, no _executionTasks flag',
|
description: 'single table payload, runAsTask explicitly disabled',
|
||||||
test: () =>
|
test: () =>
|
||||||
adapter
|
adapter
|
||||||
.request('services/common/sendArr', fileData, {
|
.request('services/common/sendArr', tableData, noTaskConfig)
|
||||||
useComputeApi: null
|
|
||||||
})
|
|
||||||
.then((res: any) => ({ ok: true, res }))
|
.then((res: any) => ({ ok: true, res }))
|
||||||
.catch((e: any) => ({ ok: false, error: e })),
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
assertion: (res: any) => res?.ok === true
|
assertion: (res: any) => res?.ok === true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title:
|
title: 'one input table (runAsTask=true)',
|
||||||
'uploads as file when _executionTasks=true and payload has semicolons',
|
description: 'single table payload, runAsTask=true via config',
|
||||||
description: 'semicolon payload with _executionTasks=true',
|
|
||||||
test: () =>
|
test: () =>
|
||||||
adapter
|
adapter
|
||||||
.request('services/common/sendArr&_executionTasks=true', fileData, {
|
.request('services/common/sendArr', tableData, taskConfig)
|
||||||
useComputeApi: null
|
.then((res: any) => ({ ok: true, res }))
|
||||||
})
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
|
assertion: (res: any) => res?.ok === true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'multiple input tables (runAsTask=false)',
|
||||||
|
description: 'multi-table payload, runAsTask explicitly disabled',
|
||||||
|
test: () =>
|
||||||
|
adapter
|
||||||
|
.request('services/common/sendArr', multiTableData, noTaskConfig)
|
||||||
|
.then((res: any) => ({ ok: true, res }))
|
||||||
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
|
assertion: (res: any) => res?.ok === true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'multiple input tables (runAsTask=true)',
|
||||||
|
description: 'multi-table payload, runAsTask=true via config',
|
||||||
|
test: () =>
|
||||||
|
adapter
|
||||||
|
.request('services/common/sendArr', multiTableData, taskConfig)
|
||||||
|
.then((res: any) => ({ ok: true, res }))
|
||||||
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
|
assertion: (res: any) => res?.ok === true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'semicolon payload, single table, blob path (runAsTask=false)',
|
||||||
|
description: 'semicolon payload routes through blob path, runAsTask off',
|
||||||
|
test: () =>
|
||||||
|
adapter
|
||||||
|
.request('services/common/sendArr', fileData, noTaskConfig)
|
||||||
|
.then((res: any) => ({ ok: true, res }))
|
||||||
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
|
assertion: (res: any) => res?.ok === true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'semicolon payload, single table, blob path (runAsTask=true)',
|
||||||
|
description:
|
||||||
|
'semicolon payload (single table) routes through blob path, runAsTask=true',
|
||||||
|
test: () =>
|
||||||
|
adapter
|
||||||
|
.request('services/common/sendArr', fileData, taskConfig)
|
||||||
|
.then((res: any) => ({ ok: true, res }))
|
||||||
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
|
assertion: (res: any) => res?.ok === true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'semicolon payload, multi-table, blob path (runAsTask=false)',
|
||||||
|
description:
|
||||||
|
'semicolon payload (multi-table) routes through blob path, runAsTask off',
|
||||||
|
test: () =>
|
||||||
|
adapter
|
||||||
|
.request('services/common/sendArr', multiFileData, noTaskConfig)
|
||||||
|
.then((res: any) => ({ ok: true, res }))
|
||||||
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
|
assertion: (res: any) => res?.ok === true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'semicolon payload, multi-table, blob path (runAsTask=true)',
|
||||||
|
description:
|
||||||
|
'semicolon payload (multi-table) routes through blob path, runAsTask=true',
|
||||||
|
test: () =>
|
||||||
|
adapter
|
||||||
|
.request('services/common/sendArr', multiFileData, taskConfig)
|
||||||
.then((res: any) => ({ ok: true, res }))
|
.then((res: any) => ({ ok: true, res }))
|
||||||
.catch((e: any) => ({ ok: false, error: e })),
|
.catch((e: any) => ({ ok: false, error: e })),
|
||||||
assertion: (res: any) => res?.ok === true
|
assertion: (res: any) => res?.ok === true
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { WebJobExecutor } from '../WebJobExecutor'
|
|||||||
import { RequestClient } from '../../request/RequestClient'
|
import { RequestClient } from '../../request/RequestClient'
|
||||||
import { SASViyaApiClient } from '../../SASViyaApiClient'
|
import { SASViyaApiClient } from '../../SASViyaApiClient'
|
||||||
|
|
||||||
describe('WebJobExecutor _executionTasks=true behaviour', () => {
|
describe('WebJobExecutor runAsTask behaviour', () => {
|
||||||
const serverUrl = 'https://sample.server.com'
|
const serverUrl = 'https://sample.server.com'
|
||||||
const jobsPath = '/SASJobExecution'
|
const jobsPath = '/SASJobExecution'
|
||||||
|
|
||||||
@@ -31,35 +31,63 @@ describe('WebJobExecutor _executionTasks=true behaviour', () => {
|
|||||||
serverUrl,
|
serverUrl,
|
||||||
serverType: ServerType.SasViya,
|
serverType: ServerType.SasViya,
|
||||||
appLoc: '/Public/app',
|
appLoc: '/Public/app',
|
||||||
|
useComputeApi: false,
|
||||||
debug: false
|
debug: false
|
||||||
}
|
}
|
||||||
|
|
||||||
it('sends table data in body', async () => {
|
it('sends table data in body (runAsTask=false)', async () => {
|
||||||
const { executor, postSpy } = makeExecutor()
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
await executor.execute(
|
await executor.execute(
|
||||||
'services/common/sendArr',
|
'services/common/sendArr',
|
||||||
{ table1: [{ col1: 'v' }] },
|
{ table1: [{ col1: 'v' }] },
|
||||||
baseConfig
|
{ ...baseConfig, runAsTask: false }
|
||||||
)
|
)
|
||||||
|
|
||||||
const [, body, , contentType] = postSpy.mock.calls[0]
|
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
||||||
|
expect(apiUrl).not.toContain('_executionTasks=true')
|
||||||
expect(body).toBeInstanceOf(NodeFormData)
|
expect(body).toBeInstanceOf(NodeFormData)
|
||||||
expect(contentType).toMatch(/^multipart\/form-data/)
|
expect(contentType).toMatch(/^multipart\/form-data/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sends table data when _executionTasks=true', async () => {
|
it('uploads as file when payload has semicolons (runAsTask=false)', async () => {
|
||||||
const { executor, postSpy } = makeExecutor()
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
await executor.execute(
|
await executor.execute(
|
||||||
'services/common/sendArr&_executionTasks=true',
|
'services/common/sendArr',
|
||||||
{ table1: [{ col1: 'v' }] },
|
{ table1: [{ col1: 'has; semicolon' }] },
|
||||||
baseConfig
|
{ ...baseConfig, runAsTask: false }
|
||||||
)
|
)
|
||||||
|
|
||||||
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
||||||
expect(apiUrl).toContain('_program=/Public/app/services/common/sendArr')
|
expect(apiUrl).not.toContain('_executionTasks=')
|
||||||
expect(apiUrl).toContain('_executionTasks=true')
|
expect(body).toBeInstanceOf(NodeFormData)
|
||||||
|
expect(contentType).toMatch(/^multipart\/form-data/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends &_executionTasks=true to URL when runAsTask=true and no data', async () => {
|
||||||
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
|
await executor.execute('services/common/sendArr', null, {
|
||||||
|
...baseConfig,
|
||||||
|
runAsTask: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const [apiUrl] = postSpy.mock.calls[0]
|
||||||
|
expect(apiUrl).toContain('&_executionTasks=true')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends &_executionTasks=true and sends table data when runAsTask=true with one input table', async () => {
|
||||||
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
|
await executor.execute(
|
||||||
|
'services/common/sendArr',
|
||||||
|
{ table1: [{ col1: 'v' }] },
|
||||||
|
{ ...baseConfig, runAsTask: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
||||||
|
expect(apiUrl).toContain('&_executionTasks=true')
|
||||||
expect(body).toBeInstanceOf(NodeFormData)
|
expect(body).toBeInstanceOf(NodeFormData)
|
||||||
expect(contentType).toMatch(/^multipart\/form-data/)
|
expect(contentType).toMatch(/^multipart\/form-data/)
|
||||||
const dump = (body as NodeFormData).getBuffer().toString()
|
const dump = (body as NodeFormData).getBuffer().toString()
|
||||||
@@ -67,42 +95,52 @@ describe('WebJobExecutor _executionTasks=true behaviour', () => {
|
|||||||
expect(dump).toContain('name="sasjs1data"')
|
expect(dump).toContain('name="sasjs1data"')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('uploads as file when payload has semicolons', async () => {
|
it('appends &_executionTasks=true to URL when runAsTask=true with multiple input tables', async () => {
|
||||||
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
|
await executor.execute(
|
||||||
|
'services/common/sendArr',
|
||||||
|
{ table1: [{ col1: 'v' }], table2: [{ col2: 'w' }] },
|
||||||
|
{ ...baseConfig, runAsTask: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
||||||
|
expect(apiUrl).toContain('&_executionTasks=true')
|
||||||
|
expect(body).toBeInstanceOf(NodeFormData)
|
||||||
|
expect(contentType).toMatch(/^multipart\/form-data/)
|
||||||
|
const dump = (body as NodeFormData).getBuffer().toString()
|
||||||
|
expect(dump).toContain('name="sasjs_tables"')
|
||||||
|
expect(dump).toMatch(/table1\s+table2/)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('uploads as file when runAsTask=true and payload has semicolons', async () => {
|
||||||
const { executor, postSpy } = makeExecutor()
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
await executor.execute(
|
await executor.execute(
|
||||||
'services/common/sendArr',
|
'services/common/sendArr',
|
||||||
{ table1: [{ col1: 'has; semicolon' }] },
|
{ table1: [{ col1: 'has; semicolon' }] },
|
||||||
baseConfig
|
{ ...baseConfig, runAsTask: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
||||||
expect(apiUrl).toContain('_program=')
|
expect(apiUrl).toContain('&_executionTasks=true')
|
||||||
expect(apiUrl).not.toContain('_executionTasks=')
|
|
||||||
expect(body).toBeInstanceOf(NodeFormData)
|
expect(body).toBeInstanceOf(NodeFormData)
|
||||||
expect(body).not.toBeInstanceOf(URLSearchParams)
|
|
||||||
expect(contentType).toMatch(/^multipart\/form-data/)
|
expect(contentType).toMatch(/^multipart\/form-data/)
|
||||||
expect(contentType).not.toBe('application/x-www-form-urlencoded')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('uploads as file when _executionTasks=true and payload has semicolons', async () => {
|
|
||||||
const { executor, postSpy } = makeExecutor()
|
|
||||||
|
|
||||||
await executor.execute(
|
|
||||||
'services/common/sendArr&_executionTasks=true',
|
|
||||||
{ table1: [{ col1: 'has; semicolon' }] },
|
|
||||||
baseConfig
|
|
||||||
)
|
|
||||||
|
|
||||||
const [apiUrl, body, , contentType] = postSpy.mock.calls[0]
|
|
||||||
expect(apiUrl).toContain('_program=')
|
|
||||||
expect(apiUrl).toContain('_executionTasks=true')
|
|
||||||
expect(body).toBeInstanceOf(NodeFormData)
|
|
||||||
expect(body).not.toBeInstanceOf(URLSearchParams)
|
|
||||||
expect(contentType).toMatch(/^multipart\/form-data/)
|
|
||||||
expect(contentType).not.toBe('application/x-www-form-urlencoded')
|
|
||||||
const dump = (body as NodeFormData).getBuffer().toString()
|
const dump = (body as NodeFormData).getBuffer().toString()
|
||||||
expect(dump).toContain('filename="table1.csv"')
|
expect(dump).toContain('filename="table1.csv"')
|
||||||
expect(dump).toContain('Content-Type: application/csv')
|
expect(dump).toContain('Content-Type: application/csv')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('does NOT append _executionTasks=true to URL when runAsTask=false', async () => {
|
||||||
|
const { executor, postSpy } = makeExecutor()
|
||||||
|
|
||||||
|
await executor.execute(
|
||||||
|
'services/common/sendArr',
|
||||||
|
{ table1: [{ col1: 'v' }] },
|
||||||
|
{ ...baseConfig, runAsTask: false }
|
||||||
|
)
|
||||||
|
|
||||||
|
const [apiUrl] = postSpy.mock.calls[0]
|
||||||
|
expect(apiUrl).not.toContain('_executionTasks=true')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user