|
|
|
@ -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) |
|
|
|
}) |
|
|
|
}) |
|
|
|
}) |
|
|
|
|