348 lines
12 KiB
JavaScript
348 lines
12 KiB
JavaScript
import cockpit from "cockpit";
|
|
import QUnit from "qunit-tests";
|
|
|
|
/* Set this to a regexp to ignore that warning once */
|
|
/*
|
|
function console_ignore_warning(exp) {
|
|
const console_warn = console.warn;
|
|
console.warn = function() {
|
|
if (!exp.exec(arguments[0]))
|
|
console_warn.apply(console, arguments);
|
|
console.warn = console_warn;
|
|
};
|
|
}
|
|
*/
|
|
|
|
QUnit.test("public api", assert => {
|
|
const client = cockpit.http("/test");
|
|
assert.equal(typeof client, "object", "http is an object");
|
|
assert.equal(typeof client.get, "function", "http.get() is a function");
|
|
assert.equal(typeof client.post, "function", "http.post() is a function");
|
|
});
|
|
|
|
const test_server = {
|
|
address: window.location.hostname,
|
|
port: parseInt(window.location.port, 10)
|
|
};
|
|
|
|
QUnit.test("simple request", assert => {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
cockpit.http(test_server).get("/pkg/playground/manifest.json")
|
|
.then(data => {
|
|
assert.deepEqual(JSON.parse(data), {
|
|
requires: {
|
|
cockpit: "122"
|
|
},
|
|
|
|
tools: {
|
|
index: {
|
|
label: "Development"
|
|
}
|
|
},
|
|
|
|
playground: {
|
|
"react-patterns": {
|
|
label: "React Patterns"
|
|
},
|
|
translate: {
|
|
label: "Translating"
|
|
},
|
|
exception: {
|
|
label: "Exceptions"
|
|
},
|
|
pkgs: {
|
|
label: "Packages"
|
|
},
|
|
preloaded: {
|
|
label: "Preloaded"
|
|
},
|
|
"notifications-receiver": {
|
|
label: "Notifications Receiver"
|
|
},
|
|
metrics: {
|
|
label: "Monitoring"
|
|
},
|
|
plot: {
|
|
label: "Plots"
|
|
},
|
|
service: {
|
|
label: "Generic Service Monitor"
|
|
},
|
|
speed: {
|
|
label: "Speed Tests"
|
|
},
|
|
journal: {
|
|
label: "Logs Box"
|
|
},
|
|
test: {
|
|
label: "Playground"
|
|
}
|
|
},
|
|
preload: ["preloaded"],
|
|
"content-security-policy": "img-src 'self' data:"
|
|
}, "returned right data");
|
|
})
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("with params", assert => {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
cockpit.http(test_server)
|
|
.get("/mock/qs", { key: "value", name: "Scruffy the Janitor" })
|
|
.then(resp => assert.equal(resp, "key=value&name=Scruffy+the+Janitor", "right query string"))
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("not found", assert => {
|
|
const done = assert.async();
|
|
assert.expect(5);
|
|
|
|
cockpit.http(test_server)
|
|
.get("/not/found")
|
|
.response(status => assert.equal(status, 404, "status code"))
|
|
.catch((ex, data) => {
|
|
assert.strictEqual(ex.problem, null, "mapped to cockpit code");
|
|
assert.strictEqual(ex.status, 404, "has status code");
|
|
assert.equal(ex.message, "Not Found", "has reason");
|
|
assert.true(data !== undefined && data.includes('<h1>Not Found</h1>'), "got body");
|
|
})
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("streaming", assert => {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
let num_chunks = 0;
|
|
let got = "";
|
|
cockpit.http(test_server)
|
|
.get("/mock/stream")
|
|
.stream(resp => {
|
|
got += resp;
|
|
num_chunks++;
|
|
})
|
|
.finally(() => {
|
|
assert.true(num_chunks > 1, "got at least two chunks");
|
|
assert.true(num_chunks <= 10, "got at most 10 chunks");
|
|
assert.equal(got, "0 1 2 3 4 5 6 7 8 9 ", "stream got right data");
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("close", assert => {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
let at = 0;
|
|
const http = cockpit.http(test_server);
|
|
|
|
http.get("/mock/stream")
|
|
.stream(resp => {
|
|
at += 1;
|
|
assert.equal(resp, "0 ", "first stream part");
|
|
http.close("bad-boy");
|
|
})
|
|
.catch(ex => assert.equal(ex.problem, "bad-boy", "right problem"))
|
|
.finally(() => {
|
|
assert.equal(at, 1, "stream got cancelled");
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("close all", assert => {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
const http = cockpit.http(test_server);
|
|
const req = http.get("/mock/stream");
|
|
|
|
let at = 0;
|
|
req
|
|
.stream(resp => {
|
|
at += 1;
|
|
assert.equal(resp, "0 ", "first stream part");
|
|
http.close("bad-boy");
|
|
})
|
|
.catch(ex => assert.equal(ex.problem, "bad-boy", "right problem"))
|
|
.finally(() => {
|
|
assert.equal(at, 1, "stream got cancelled");
|
|
http.close("closed"); // This should be a no-op now
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("headers", assert => {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
cockpit.http(test_server)
|
|
.get("/mock/headers", null, { Header1: "booo", Header2: "yay value" })
|
|
.response((status, headers) => {
|
|
assert.equal(status, 201, "status code");
|
|
assert.deepEqual(headers, {
|
|
Header1: "booo",
|
|
Header2: "yay value",
|
|
Header3: "three",
|
|
Header4: "marmalade",
|
|
"Referrer-Policy": "no-referrer",
|
|
"X-DNS-Prefetch-Control": "off",
|
|
"X-Content-Type-Options": "nosniff",
|
|
"X-Frame-Options": "sameorigin",
|
|
"Cross-Origin-Resource-Policy": "same-origin",
|
|
}, "got back headers");
|
|
})
|
|
.then(() => assert.ok(true, "split response succeeded"))
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("escape host header", assert => {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
cockpit.http(test_server)
|
|
.get("/mock/host", null, { })
|
|
.response((status, headers) => {
|
|
assert.equal(status, 201, "status code");
|
|
assert.deepEqual(headers.Host, window.location.host, "got back escaped headers");
|
|
})
|
|
.then(() => assert.ok(true, "split response succeeded"))
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("connection headers", assert => {
|
|
const done = assert.async();
|
|
assert.expect(2);
|
|
|
|
cockpit.http({ port: test_server.port, headers: { Header1: "booo", Header2: "not this" } })
|
|
.get("/mock/headers", null, { Header2: "yay value", Header0: "extra" })
|
|
.response((status, headers) => {
|
|
assert.equal(status, 201, "status code");
|
|
assert.deepEqual(headers, {
|
|
Header0: "extra",
|
|
Header1: "booo",
|
|
Header2: "yay value",
|
|
Header3: "three",
|
|
Header4: "marmalade",
|
|
"Referrer-Policy": "no-referrer",
|
|
"X-DNS-Prefetch-Control": "off",
|
|
"X-Content-Type-Options": "nosniff",
|
|
"X-Frame-Options": "sameorigin",
|
|
"Cross-Origin-Resource-Policy": "same-origin",
|
|
}, "got back combined headers");
|
|
})
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("http promise recursive", assert => {
|
|
assert.expect(7);
|
|
|
|
const promise = cockpit.http(test_server).get("/");
|
|
|
|
const target = { };
|
|
const promise2 = promise.promise(target);
|
|
assert.strictEqual(promise2, target, "used target");
|
|
assert.equal(typeof promise2.done, "function", "promise2.done()");
|
|
assert.equal(typeof promise2.promise, "function", "promise2.promise()");
|
|
assert.equal(typeof promise2.input, "function", "promise2.input()");
|
|
|
|
const promise3 = promise2.promise();
|
|
assert.equal(typeof promise3.done, "function", "promise3.done()");
|
|
assert.equal(typeof promise3.promise, "function", "promise3.promise()");
|
|
assert.equal(typeof promise3.input, "function", "promise3.input()");
|
|
});
|
|
|
|
QUnit.test("http keep alive", async assert => {
|
|
assert.expect(1);
|
|
|
|
/*
|
|
* The /mock/connection handler returns an identifier that changes if
|
|
* a different connection is used.
|
|
*/
|
|
const first = await cockpit.http({ port: test_server.port, connection: "marmalade" }).get("/mock/connection");
|
|
const second = await cockpit.http({ port: test_server.port, connection: "marmalade" }).get("/mock/connection");
|
|
assert.equal(first, second, "same connection");
|
|
});
|
|
|
|
QUnit.test("http connection different", async assert => {
|
|
assert.expect(1);
|
|
|
|
/*
|
|
* The /mock/connection handler returns an identifier that changes if
|
|
* a different connection is used.
|
|
*/
|
|
const first = await cockpit.http({ port: test_server.port, connection: "one" }).get("/mock/connection");
|
|
const second = await cockpit.http({ port: test_server.port, connection: "two" }).get("/mock/connection");
|
|
assert.notEqual(first, second, "different connection");
|
|
});
|
|
|
|
QUnit.test("http connection without address", async assert => {
|
|
assert.expect(1);
|
|
|
|
// Able to reuse connection client info and not specify address again.
|
|
const first = await cockpit.http({ port: test_server.port, connection: "one" }).get("/mock/connection");
|
|
const second = await cockpit.http({ connection: "one" }).get("/mock/connection");
|
|
assert.equal(first, second, "same connection");
|
|
});
|
|
|
|
QUnit.test("no dns address", assert => {
|
|
assert.expect(1);
|
|
|
|
assert.rejects(cockpit.http({ port: 8080, address: "the-other-host.example.com" }).get("/"),
|
|
/* Unfortunately we can see either of these errors when running unit tests */
|
|
ex => { return ex.problem === "timeout" || ex.problem === "not-found" });
|
|
});
|
|
|
|
QUnit.test("address with params", assert => {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
cockpit.http(test_server)
|
|
.get("/mock/qs", { key: "value", name: "Scruffy the Janitor" })
|
|
.then(resp => assert.equal(resp, "key=value&name=Scruffy+the+Janitor", "right query string"))
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("HEAD method", assert => {
|
|
const done = assert.async();
|
|
assert.expect(4);
|
|
|
|
assert.rejects(
|
|
cockpit.http(test_server).get("/mock/headonly"),
|
|
ex => ex.status == 400 && ex.reason == "Only HEAD allowed on this path",
|
|
"rejects GET request on /headonly path");
|
|
|
|
const InputData = "some chars";
|
|
|
|
cockpit.http(test_server).request({
|
|
path: "/mock/headonly",
|
|
method: "HEAD",
|
|
headers: { InputData },
|
|
body: "",
|
|
})
|
|
.response((status, headers) => {
|
|
assert.equal(status, 200);
|
|
assert.equal(headers.InputDataLength, InputData.length);
|
|
})
|
|
.then(data => assert.equal(data, ""))
|
|
.finally(done);
|
|
});
|
|
|
|
QUnit.test("wrong options", assert => {
|
|
assert.rejects(
|
|
cockpit.http({}).get("/"),
|
|
// unfortunately cockpit.js does not propagate the detailed error message
|
|
ex => ex.problem == "protocol-error" && ex.status == undefined,
|
|
"rejects request without port or unix option");
|
|
|
|
assert.rejects(
|
|
cockpit.http({ port: 1234, unix: "/nonexisting/socket" }).get("/"),
|
|
ex => ex.problem == "protocol-error" && ex.status == undefined,
|
|
"rejects request with both port and unix option");
|
|
});
|
|
|
|
QUnit.start();
|