Add tests for REST pagination

This commit is contained in:
Andrew Kingston 2022-01-07 10:49:31 +00:00
parent 422c0a3033
commit bf22c5130f
2 changed files with 293 additions and 34 deletions

View File

@ -218,13 +218,13 @@ module RestModule {
}
addBody(bodyType: string, body: string | any, input: any, pagination: PaginationConfig | null, paginationValues: PaginationValues | null) {
if (bodyType === BodyTypes.NONE) {
return input
}
if (!input.headers) {
input.headers = {}
}
let error, object = {}, string = ""
if (bodyType === BodyTypes.NONE) {
return input
}
let error, object: any = {}, string = ""
try {
if (body) {
string = typeof body !== "string" ? JSON.stringify(body) : body
@ -278,19 +278,15 @@ module RestModule {
input.body = string
input.headers["Content-Type"] = "application/xml"
break
default:
case BodyTypes.JSON:
// if JSON error, throw it
if (error) {
throw "Invalid JSON for request body"
}
if (!body) {
body = {}
}
addPaginationToBody((key: string, value: any) => {
body[key] = value
object[key] = value
})
input.body = JSON.stringify(body)
input.body = JSON.stringify(object)
input.headers["Content-Type"] = "application/json"
break
}

View File

@ -4,19 +4,23 @@ jest.mock("node-fetch", () =>
raw: () => {
return { "content-type": ["application/json"] }
},
get: () => ["application/json"]
get: () => ["application/json"],
},
json: jest.fn(),
text: jest.fn()
json: jest.fn(() => ({
my_next_cursor: 123,
})),
text: jest.fn(),
}))
)
const fetch = require("node-fetch")
const RestIntegration = require("../rest")
const { AuthType } = require("../rest")
const FormData = require("form-data")
const { URLSearchParams } = require("url")
const HEADERS = {
"Accept": "application/json",
"Content-Type": "application/json"
Accept: "application/json",
"Content-Type": "application/json",
}
class TestConfiguration {
@ -165,17 +169,20 @@ describe("REST Integration", () => {
status: 200,
json: json ? async () => json : undefined,
text: text ? async () => text : undefined,
headers: { get: key => key === "content-length" ? 100 : header, raw: () => ({ "content-type": header }) }
headers: {
get: key => (key === "content-length" ? 100 : header),
raw: () => ({ "content-type": header }),
},
}
}
it("should be able to parse JSON response", async () => {
const input = buildInput({a: 1}, null, "application/json")
const input = buildInput({ a: 1 }, null, "application/json")
const output = await config.integration.parseResponse(input)
expect(output.data).toEqual({a: 1})
expect(output.data).toEqual({ a: 1 })
expect(output.info.code).toEqual(200)
expect(output.info.size).toEqual("100B")
expect(output.extra.raw).toEqual(JSON.stringify({a: 1}))
expect(output.extra.raw).toEqual(JSON.stringify({ a: 1 }))
expect(output.extra.headers["content-type"]).toEqual("application/json")
})
@ -192,7 +199,7 @@ describe("REST Integration", () => {
const text = "<root><a>1</a><b>2</b></root>"
const input = buildInput(null, text, "application/xml")
const output = await config.integration.parseResponse(input)
expect(output.data).toEqual({a: "1", b: "2"})
expect(output.data).toEqual({ a: "1", b: "2" })
expect(output.extra.raw).toEqual(text)
expect(output.extra.headers["content-type"]).toEqual("application/xml")
})
@ -202,53 +209,309 @@ describe("REST Integration", () => {
const basicAuth = {
_id: "c59c14bd1898a43baa08da68959b24686",
name: "basic-1",
type : AuthType.BASIC,
config : {
type: AuthType.BASIC,
config: {
username: "user",
password: "password"
}
password: "password",
},
}
const bearerAuth = {
_id: "0d91d732f34e4befabeff50b392a8ff3",
name: "bearer-1",
type : AuthType.BEARER,
config : {
"token": "mytoken"
}
type: AuthType.BEARER,
config: {
token: "mytoken",
},
}
beforeEach(() => {
config = new TestConfiguration({
url: BASE_URL,
authConfigs : [basicAuth, bearerAuth]
authConfigs: [basicAuth, bearerAuth],
})
})
it("adds basic auth", async () => {
const query = {
authConfigId: "c59c14bd1898a43baa08da68959b24686"
authConfigId: "c59c14bd1898a43baa08da68959b24686",
}
await config.integration.read(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
method: "GET",
headers: {
Authorization: "Basic dXNlcjpwYXNzd29yZA=="
Authorization: "Basic dXNlcjpwYXNzd29yZA==",
},
})
})
it("adds bearer auth", async () => {
const query = {
authConfigId: "0d91d732f34e4befabeff50b392a8ff3"
authConfigId: "0d91d732f34e4befabeff50b392a8ff3",
}
await config.integration.read(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
method: "GET",
headers: {
Authorization: "Bearer mytoken"
Authorization: "Bearer mytoken",
},
})
})
})
describe("page based pagination", () => {
it("can paginate using query params", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
path: "api",
pagination: {
type: "page",
location: "query",
pageParam,
sizeParam,
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
await config.integration.read(query)
expect(fetch).toHaveBeenCalledWith(
`${BASE_URL}/api?${pageParam}=${pageValue}&${sizeParam}=${sizeValue}&`,
{
headers: {},
method: "GET",
}
)
})
it("can paginate using JSON request body", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
bodyType: "json",
path: "api",
pagination: {
type: "page",
location: "body",
pageParam,
sizeParam,
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
await config.integration.create(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
body: JSON.stringify({
[pageParam]: pageValue,
[sizeParam]: sizeValue,
}),
headers: {
"Content-Type": "application/json",
},
method: "POST",
})
})
it("can paginate using form-data request body", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
bodyType: "form",
path: "api",
pagination: {
type: "page",
location: "body",
pageParam,
sizeParam,
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
await config.integration.create(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
body: expect.any(FormData),
headers: {},
method: "POST",
})
const sentData = JSON.stringify(fetch.mock.calls[0][1].body)
expect(sentData).toContain(pageParam)
expect(sentData).toContain(sizeParam)
})
it("can paginate using form-encoded request body", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
bodyType: "encoded",
path: "api",
pagination: {
type: "page",
location: "body",
pageParam,
sizeParam,
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
await config.integration.create(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
body: expect.any(URLSearchParams),
headers: {},
method: "POST",
})
const sentData = fetch.mock.calls[0][1].body
expect(sentData.has(pageParam))
expect(sentData.get(pageParam)).toEqual(pageValue.toString())
expect(sentData.has(sizeParam))
expect(sentData.get(sizeParam)).toEqual(sizeValue.toString())
})
})
describe("cursor based pagination", () => {
it("can paginate using query params", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
path: "api",
pagination: {
type: "cursor",
location: "query",
pageParam,
sizeParam,
responseParam: "my_next_cursor",
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
const res = await config.integration.read(query)
expect(fetch).toHaveBeenCalledWith(
`${BASE_URL}/api?${pageParam}=${pageValue}&${sizeParam}=${sizeValue}&`,
{
headers: {},
method: "GET",
}
)
expect(res.pagination.cursor).toEqual(123)
})
it("can paginate using JSON request body", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
bodyType: "json",
path: "api",
pagination: {
type: "page",
location: "body",
pageParam,
sizeParam,
responseParam: "my_next_cursor",
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
const res = await config.integration.create(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
body: JSON.stringify({
[pageParam]: pageValue,
[sizeParam]: sizeValue,
}),
headers: {
"Content-Type": "application/json",
},
method: "POST",
})
expect(res.pagination.cursor).toEqual(123)
})
it("can paginate using form-data request body", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
bodyType: "form",
path: "api",
pagination: {
type: "page",
location: "body",
pageParam,
sizeParam,
responseParam: "my_next_cursor",
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
const res = await config.integration.create(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
body: expect.any(FormData),
headers: {},
method: "POST",
})
const sentData = JSON.stringify(fetch.mock.calls[0][1].body)
expect(sentData).toContain(pageParam)
expect(sentData).toContain(sizeParam)
expect(res.pagination.cursor).toEqual(123)
})
it("can paginate using form-encoded request body", async () => {
const pageParam = "my_page_param"
const sizeParam = "my_size_param"
const pageValue = 3
const sizeValue = 10
const query = {
bodyType: "encoded",
path: "api",
pagination: {
type: "page",
location: "body",
pageParam,
sizeParam,
responseParam: "my_next_cursor",
},
paginationValues: {
page: pageValue,
limit: sizeValue,
},
}
const res = await config.integration.create(query)
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/api?`, {
body: expect.any(URLSearchParams),
headers: {},
method: "POST",
})
const sentData = fetch.mock.calls[0][1].body
expect(sentData.has(pageParam))
expect(sentData.get(pageParam)).toEqual(pageValue.toString())
expect(sentData.has(sizeParam))
expect(sentData.get(sizeParam)).toEqual(sizeValue.toString())
expect(res.pagination.cursor).toEqual(123)
})
})
})