174 lines
4.6 KiB
Plaintext
174 lines
4.6 KiB
Plaintext
component extends="testbox.system.BaseSpec" {
|
|
|
|
function beforeAll() {
|
|
// Build base URL from the server running these tests
|
|
var port = cgi.server_port;
|
|
var host = cgi.server_name;
|
|
if (!len(host) || host == "") host = "localhost";
|
|
variables.baseURL = "http://#host#:#port#/tests/testapi/index.cfm";
|
|
}
|
|
|
|
/**
|
|
* Helper: make an HTTP request to the test API
|
|
*/
|
|
private struct function apiRequest(
|
|
required string uri,
|
|
string method = "GET",
|
|
string body = "",
|
|
struct headers = {}
|
|
) {
|
|
var result = {};
|
|
var fullURL = variables.baseURL & "?endpoint=" & arguments.uri;
|
|
|
|
cfhttp(url=fullURL, method=arguments.method, result="result", timeout=10, charset="utf-8") {
|
|
cfhttpparam(type="header", name="Content-Type", value="application/json");
|
|
cfhttpparam(type="header", name="Accept", value="application/json");
|
|
for (var h in arguments.headers) {
|
|
cfhttpparam(type="header", name=h, value=arguments.headers[h]);
|
|
}
|
|
if (len(arguments.body)) {
|
|
cfhttpparam(type="body", value=arguments.body);
|
|
}
|
|
}
|
|
|
|
result.data = {};
|
|
if (structKeyExists(result, "fileContent")) {
|
|
var body = result.fileContent;
|
|
if (!isSimpleValue(body)) {
|
|
body = toString(body);
|
|
}
|
|
body = trim(body);
|
|
if (len(body) && isJSON(body)) {
|
|
result.data = deserializeJSON(body);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function run() {
|
|
|
|
describe("End-to-End HTTP Tests", function() {
|
|
|
|
describe("GET requests", function() {
|
|
|
|
it("should return 200 for a valid GET request", function() {
|
|
var res = apiRequest("/echo");
|
|
expect(res.status_code).toBe(200);
|
|
expect(res.data.method).toBe("GET");
|
|
expect(res.data.message).toBe("echo");
|
|
});
|
|
|
|
it("should extract URI token from path", function() {
|
|
var res = apiRequest("/echo/42");
|
|
expect(res.status_code).toBe(200);
|
|
expect(res.data.id).toBe("42");
|
|
expect(res.data.method).toBe("GET");
|
|
});
|
|
|
|
it("should extract multiple URI tokens", function() {
|
|
var res = apiRequest("/echo/10/child/20");
|
|
expect(res.status_code).toBe(200);
|
|
expect(res.data.parentId).toBe("10");
|
|
expect(res.data.childId).toBe("20");
|
|
});
|
|
|
|
it("should return JSON content type", function() {
|
|
var res = apiRequest("/echo");
|
|
expect(res.responseheader["Content-Type"]).toInclude("application/json");
|
|
});
|
|
|
|
});
|
|
|
|
describe("POST requests", function() {
|
|
|
|
it("should return 201 Created", function() {
|
|
var res = apiRequest(
|
|
uri = "/echo",
|
|
method = "POST",
|
|
body = '{"name":"test","value":"123"}'
|
|
);
|
|
expect(res.status_code).toBe(201);
|
|
expect(res.data.method).toBe("POST");
|
|
});
|
|
|
|
it("should deserialize JSON request body", function() {
|
|
var res = apiRequest(
|
|
uri = "/echo",
|
|
method = "POST",
|
|
body = '{"name":"widget","value":"abc"}'
|
|
);
|
|
expect(res.data.name).toBe("widget");
|
|
expect(res.data.value).toBe("abc");
|
|
});
|
|
|
|
});
|
|
|
|
describe("PUT requests", function() {
|
|
|
|
it("should handle PUT with URI token and body", function() {
|
|
var res = apiRequest(
|
|
uri = "/echo/55",
|
|
method = "PUT",
|
|
body = '{"name":"updated"}'
|
|
);
|
|
expect(res.status_code).toBe(200);
|
|
expect(res.data.method).toBe("PUT");
|
|
expect(res.data.id).toBe("55");
|
|
expect(res.data.name).toBe("updated");
|
|
});
|
|
|
|
});
|
|
|
|
describe("DELETE requests", function() {
|
|
|
|
it("should handle DELETE with URI token", function() {
|
|
var res = apiRequest(uri="/echo/99", method="DELETE");
|
|
expect(res.status_code).toBe(200);
|
|
expect(res.data.method).toBe("DELETE");
|
|
expect(res.data.id).toBe("99");
|
|
});
|
|
|
|
it("should return custom response headers", function() {
|
|
var res = apiRequest(uri="/echo/99", method="DELETE");
|
|
expect(res.responseheader["X-Deleted-Id"]).toBe("99");
|
|
});
|
|
|
|
});
|
|
|
|
describe("Error responses", function() {
|
|
|
|
it("should return 404 for unknown URI", function() {
|
|
var res = apiRequest("/nonexistent/path");
|
|
expect(res.status_code).toBe(404);
|
|
});
|
|
|
|
it("should return 405 for unsupported HTTP method", function() {
|
|
// /echo/{parentId}/child/{childId} only supports GET
|
|
var res = apiRequest(uri="/echo/1/child/2", method="DELETE");
|
|
expect(res.status_code).toBe(405);
|
|
});
|
|
|
|
});
|
|
|
|
describe("X-HTTP-Method-Override", function() {
|
|
|
|
it("should support method tunneling via header", function() {
|
|
var res = apiRequest(
|
|
uri = "/echo/77",
|
|
method = "POST",
|
|
headers = { "X-HTTP-Method-Override": "PUT" },
|
|
body = '{"name":"tunneled"}'
|
|
);
|
|
expect(res.data.method).toBe("PUT");
|
|
expect(res.data.id).toBe("77");
|
|
expect(res.data.name).toBe("tunneled");
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|