Add tests for REST pagination
This commit is contained in:
parent
422c0a3033
commit
bf22c5130f
|
@ -218,13 +218,13 @@ module RestModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
addBody(bodyType: string, body: string | any, input: any, pagination: PaginationConfig | null, paginationValues: PaginationValues | null) {
|
addBody(bodyType: string, body: string | any, input: any, pagination: PaginationConfig | null, paginationValues: PaginationValues | null) {
|
||||||
if (bodyType === BodyTypes.NONE) {
|
|
||||||
return input
|
|
||||||
}
|
|
||||||
if (!input.headers) {
|
if (!input.headers) {
|
||||||
input.headers = {}
|
input.headers = {}
|
||||||
}
|
}
|
||||||
let error, object = {}, string = ""
|
if (bodyType === BodyTypes.NONE) {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
let error, object: any = {}, string = ""
|
||||||
try {
|
try {
|
||||||
if (body) {
|
if (body) {
|
||||||
string = typeof body !== "string" ? JSON.stringify(body) : body
|
string = typeof body !== "string" ? JSON.stringify(body) : body
|
||||||
|
@ -278,19 +278,15 @@ module RestModule {
|
||||||
input.body = string
|
input.body = string
|
||||||
input.headers["Content-Type"] = "application/xml"
|
input.headers["Content-Type"] = "application/xml"
|
||||||
break
|
break
|
||||||
default:
|
|
||||||
case BodyTypes.JSON:
|
case BodyTypes.JSON:
|
||||||
// if JSON error, throw it
|
// if JSON error, throw it
|
||||||
if (error) {
|
if (error) {
|
||||||
throw "Invalid JSON for request body"
|
throw "Invalid JSON for request body"
|
||||||
}
|
}
|
||||||
if (!body) {
|
|
||||||
body = {}
|
|
||||||
}
|
|
||||||
addPaginationToBody((key: string, value: any) => {
|
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"
|
input.headers["Content-Type"] = "application/json"
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,23 @@ jest.mock("node-fetch", () =>
|
||||||
raw: () => {
|
raw: () => {
|
||||||
return { "content-type": ["application/json"] }
|
return { "content-type": ["application/json"] }
|
||||||
},
|
},
|
||||||
get: () => ["application/json"]
|
get: () => ["application/json"],
|
||||||
},
|
},
|
||||||
json: jest.fn(),
|
json: jest.fn(() => ({
|
||||||
text: jest.fn()
|
my_next_cursor: 123,
|
||||||
|
})),
|
||||||
|
text: jest.fn(),
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
const RestIntegration = require("../rest")
|
const RestIntegration = require("../rest")
|
||||||
const { AuthType } = require("../rest")
|
const { AuthType } = require("../rest")
|
||||||
|
const FormData = require("form-data")
|
||||||
|
const { URLSearchParams } = require("url")
|
||||||
|
|
||||||
const HEADERS = {
|
const HEADERS = {
|
||||||
"Accept": "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json",
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestConfiguration {
|
class TestConfiguration {
|
||||||
|
@ -165,17 +169,20 @@ describe("REST Integration", () => {
|
||||||
status: 200,
|
status: 200,
|
||||||
json: json ? async () => json : undefined,
|
json: json ? async () => json : undefined,
|
||||||
text: text ? async () => text : 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 () => {
|
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)
|
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.code).toEqual(200)
|
||||||
expect(output.info.size).toEqual("100B")
|
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")
|
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 text = "<root><a>1</a><b>2</b></root>"
|
||||||
const input = buildInput(null, text, "application/xml")
|
const input = buildInput(null, text, "application/xml")
|
||||||
const output = await config.integration.parseResponse(input)
|
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.raw).toEqual(text)
|
||||||
expect(output.extra.headers["content-type"]).toEqual("application/xml")
|
expect(output.extra.headers["content-type"]).toEqual("application/xml")
|
||||||
})
|
})
|
||||||
|
@ -202,53 +209,309 @@ describe("REST Integration", () => {
|
||||||
const basicAuth = {
|
const basicAuth = {
|
||||||
_id: "c59c14bd1898a43baa08da68959b24686",
|
_id: "c59c14bd1898a43baa08da68959b24686",
|
||||||
name: "basic-1",
|
name: "basic-1",
|
||||||
type : AuthType.BASIC,
|
type: AuthType.BASIC,
|
||||||
config : {
|
config: {
|
||||||
username: "user",
|
username: "user",
|
||||||
password: "password"
|
password: "password",
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const bearerAuth = {
|
const bearerAuth = {
|
||||||
_id: "0d91d732f34e4befabeff50b392a8ff3",
|
_id: "0d91d732f34e4befabeff50b392a8ff3",
|
||||||
name: "bearer-1",
|
name: "bearer-1",
|
||||||
type : AuthType.BEARER,
|
type: AuthType.BEARER,
|
||||||
config : {
|
config: {
|
||||||
"token": "mytoken"
|
token: "mytoken",
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
config = new TestConfiguration({
|
config = new TestConfiguration({
|
||||||
url: BASE_URL,
|
url: BASE_URL,
|
||||||
authConfigs : [basicAuth, bearerAuth]
|
authConfigs: [basicAuth, bearerAuth],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("adds basic auth", async () => {
|
it("adds basic auth", async () => {
|
||||||
const query = {
|
const query = {
|
||||||
authConfigId: "c59c14bd1898a43baa08da68959b24686"
|
authConfigId: "c59c14bd1898a43baa08da68959b24686",
|
||||||
}
|
}
|
||||||
await config.integration.read(query)
|
await config.integration.read(query)
|
||||||
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
|
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Basic dXNlcjpwYXNzd29yZA=="
|
Authorization: "Basic dXNlcjpwYXNzd29yZA==",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("adds bearer auth", async () => {
|
it("adds bearer auth", async () => {
|
||||||
const query = {
|
const query = {
|
||||||
authConfigId: "0d91d732f34e4befabeff50b392a8ff3"
|
authConfigId: "0d91d732f34e4befabeff50b392a8ff3",
|
||||||
}
|
}
|
||||||
await config.integration.read(query)
|
await config.integration.read(query)
|
||||||
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
|
expect(fetch).toHaveBeenCalledWith(`${BASE_URL}/?`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue