845 lines
29 KiB
JavaScript
845 lines
29 KiB
JavaScript
import cockpit from "cockpit";
|
|
import QUnit from "qunit-tests";
|
|
|
|
/* Set this to a regexp to ignore that warning once */
|
|
function console_ignore_log(exp) {
|
|
const console_log = console.log;
|
|
console.log = function() {
|
|
if (!exp.exec(arguments[0]))
|
|
console_log.apply(console, arguments);
|
|
console.log = console_log;
|
|
};
|
|
}
|
|
|
|
/* The other end of the mock websocket */
|
|
function MockPeer() {
|
|
const self = this;
|
|
const echos = { };
|
|
const nulls = { };
|
|
const queue = [];
|
|
let pending = false;
|
|
|
|
cockpit.event_target(this);
|
|
|
|
/* These are events */
|
|
self.onopen = function(event) { };
|
|
self.onrecv = function(event, channel, payload) {
|
|
/* A rudimentary echo channel implementation */
|
|
if (channel) {
|
|
if (channel in echos || channel in nulls)
|
|
queue.push([channel, payload]);
|
|
} else {
|
|
const command = JSON.parse(payload);
|
|
if (command.command == "open") {
|
|
let reply;
|
|
if (command.payload == "echo") {
|
|
echos[command.channel] = true;
|
|
reply = {
|
|
command: "ready",
|
|
channel: command.channel
|
|
};
|
|
} else if (command.payload == "null") {
|
|
nulls[command.channel] = true;
|
|
reply = {
|
|
command: "ready",
|
|
channel: command.channel
|
|
};
|
|
} else {
|
|
reply = {
|
|
command: "close",
|
|
channel: command.channel,
|
|
problem: "not-supported",
|
|
};
|
|
}
|
|
queue.push([null, JSON.stringify(reply)]);
|
|
} else if (command.command == "close") {
|
|
delete echos[command.channel];
|
|
delete nulls[command.channel];
|
|
}
|
|
}
|
|
|
|
if (queue.length && !pending) {
|
|
pending = true;
|
|
window.setTimeout(function() {
|
|
while (queue.length) {
|
|
self.send.apply(self, queue.shift());
|
|
}
|
|
pending = false;
|
|
}, 0);
|
|
}
|
|
};
|
|
|
|
/* Methods filled in by MockWebSocket */
|
|
self.send = function(channel, payload) { throw Error("not reached") };
|
|
self.close = function(options) { throw Error("not reached") };
|
|
}
|
|
|
|
window.mock = { url: "ws://url" };
|
|
let force_default_host = null;
|
|
let mock_peer = new MockPeer();
|
|
|
|
QUnit.testDone(function() {
|
|
mock_peer = new MockPeer();
|
|
cockpit.transport.close();
|
|
});
|
|
|
|
/* Mock WebSocket */
|
|
function MockWebSocket(url, protocol) {
|
|
if (typeof url != "string")
|
|
throw Error("WebSocket(@url) is not a string: " + typeof url);
|
|
if (typeof protocol != "string")
|
|
throw Error("WebSocket(@protocol) is not a string: " + typeof protocol);
|
|
|
|
this.onopen = function(event) { };
|
|
this.onclose = function(event) { };
|
|
this.onmessage = function(event) { };
|
|
this.onerror = function(event) { };
|
|
this.readyState = 0;
|
|
this.url = url;
|
|
this.protocol = protocol;
|
|
this.extensions = "";
|
|
this.binaryType = null;
|
|
|
|
const ws = this;
|
|
const mock = mock_peer;
|
|
|
|
this.send = function(data) {
|
|
if (typeof data != "string")
|
|
throw Error("WebSocket.send(@data) is not a string: " + typeof data);
|
|
const pos = data.indexOf("\n");
|
|
if (pos == -1)
|
|
throw Error("Invalid frame sent to WebSocket: " + data);
|
|
const channel = data.substring(0, pos);
|
|
const payload = data.substring(pos + 1);
|
|
window.setTimeout(function() { mock.dispatchEvent("recv", channel, payload) }, 5);
|
|
};
|
|
|
|
this.close = function(code, reason) {
|
|
if (typeof code != "number" && typeof code != "undefined")
|
|
throw Error("WebSocket.close(@code) is not a number: " + typeof code);
|
|
if (typeof reason != "string" && typeof reason != "undefined")
|
|
throw Error("WebSocket.close(@reason) is not a number: " + typeof string);
|
|
if (this.readyState > 1)
|
|
throw Error("WebSocket.close() called on a closed WebSocket" + this.readyState + " " + code + reason);
|
|
this.readyState = 3;
|
|
this.onclose({ name: "close", code: code || 1000, reason: reason, wasClean: true });
|
|
};
|
|
|
|
/* Instantiate the global mock peer */
|
|
const sending = [];
|
|
mock.send = function(channel, payload) {
|
|
if (!channel)
|
|
channel = "";
|
|
const event = {
|
|
name: "message",
|
|
data: channel.toString() + "\n" + payload
|
|
};
|
|
sending.push(event);
|
|
window.setTimeout(function() {
|
|
if (ws.readyState == 1)
|
|
ws.onmessage(sending.shift());
|
|
}, 5);
|
|
};
|
|
|
|
mock.close = function(options) {
|
|
if (!options)
|
|
options = { };
|
|
window.setTimeout(function() {
|
|
ws.close(options.reason ? 1000 : 1011, options.reason || "");
|
|
}, 5);
|
|
};
|
|
|
|
/* Open shortly */
|
|
window.setTimeout(function() {
|
|
ws.readyState = 1;
|
|
mock.dispatchEvent("open");
|
|
ws.onopen({ name: "open" });
|
|
const init = {
|
|
command: "init",
|
|
version: 1,
|
|
"channel-seed": "test",
|
|
"csrf-token": "the-csrf-token",
|
|
user: {
|
|
user: "scruffy",
|
|
name: "Scruffy the Janitor"
|
|
},
|
|
system: {
|
|
version: "zero.point.zero",
|
|
build: "nasty stuff",
|
|
}
|
|
};
|
|
if (force_default_host)
|
|
init.host = force_default_host;
|
|
force_default_host = null;
|
|
ws.onmessage({ data: "\n" + JSON.stringify(init) });
|
|
}, 5);
|
|
}
|
|
|
|
WebSocket = MockWebSocket; // eslint-disable-line no-global-assign
|
|
|
|
function check_transport (assert, base_url, application, socket, url_root) {
|
|
const old_url = window.mock.url;
|
|
const arr = [base_url];
|
|
if (base_url.slice(-1) == '/')
|
|
arr.push(base_url + "other");
|
|
else
|
|
arr.push(base_url + '/', base_url + '/other');
|
|
|
|
window.mock.url = null;
|
|
window.mock.url_root = url_root;
|
|
for (let i = 0; i < arr.length; i++) {
|
|
window.mock.pathname = arr[i];
|
|
assert.equal(cockpit.transport.application(), application,
|
|
arr[i] + " transport.application is " + socket);
|
|
assert.equal(cockpit.transport.uri(), "ws://" + window.location.host + socket,
|
|
arr[i] + " transport.uri is " + socket);
|
|
}
|
|
|
|
window.mock.url = old_url;
|
|
window.mock.url_root = null;
|
|
window.mock.pathname = null;
|
|
}
|
|
|
|
QUnit.test("public api", function (assert) {
|
|
const channel = cockpit.channel({ host: "host.example.com" });
|
|
assert.equal(typeof channel, "object", "cockpit.channel() constructor");
|
|
assert.equal(channel.options.host, "host.example.com", "channel.options is dict");
|
|
assert.ok(channel.id !== undefined, "channel.id is a field");
|
|
assert.ok(channel.toString().indexOf("host.example.com") > 0, "channel.toString()");
|
|
assert.equal(typeof channel.send, "function", "channel.send() is a function");
|
|
assert.equal(typeof channel.close, "function", "channel.close() is a function");
|
|
assert.strictEqual(channel.valid, true, "channel.valid is set");
|
|
assert.equal(typeof cockpit.logout, "function", "cockpit.logout is a function");
|
|
assert.equal(typeof cockpit.transport, "object", "cockpit.transport is an object");
|
|
assert.equal(typeof cockpit.transport.close, "function", "cockpit.transport.close is a function");
|
|
assert.equal(typeof cockpit.transport.options, "object", "cockpit.transport.options is a object");
|
|
|
|
if (window.location.origin)
|
|
assert.equal(cockpit.transport.origin, window.location.origin, "cockpit.transport.origin is correct");
|
|
else
|
|
assert.equal(typeof cockpit.transport.origin, "string", "cockpit.transport.origin is present");
|
|
|
|
check_transport(assert, '/', 'cockpit', '/cockpit/socket');
|
|
check_transport(assert, '/cockpit', 'cockpit', '/cockpit/socket');
|
|
check_transport(assert, '/cockpitother/', 'cockpit', '/cockpit/socket');
|
|
check_transport(assert, '/cockpita+pplication/', 'cockpit', '/cockpit/socket');
|
|
check_transport(assert, '/cockpit+application', 'cockpit+application', '/cockpit+application/socket');
|
|
check_transport(assert, '/=machine', 'cockpit+=machine', '/cockpit+=machine/socket');
|
|
check_transport(assert, '/url-root', 'cockpit', '/url-root/cockpit/socket', 'url-root');
|
|
check_transport(assert, '/url-root/cockpit', 'cockpit', '/url-root/cockpit/socket', 'url-root');
|
|
check_transport(assert, '/url-root/cockpit+application', 'cockpit+application',
|
|
'/url-root/cockpit+application/socket', 'url-root');
|
|
check_transport(assert, '/url-root/=machine', 'cockpit+=machine', '/url-root/cockpit+=machine/socket', 'url-root');
|
|
});
|
|
|
|
QUnit.test("open channel", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(8);
|
|
|
|
const channel = cockpit.channel({ host: "scruffy" });
|
|
let is_inited = false;
|
|
mock_peer.addEventListener("open", function(event) {
|
|
assert.ok(true, "websocket connected");
|
|
});
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const command = JSON.parse(payload);
|
|
if (!is_inited) {
|
|
assert.equal(typeof command, "object", "valid json");
|
|
assert.strictEqual(chan, "", "sent with empty channel");
|
|
assert.equal(command.command, "init", "got init");
|
|
assert.equal(command.version, 1, "got init version");
|
|
is_inited = true;
|
|
} else {
|
|
assert.equal(command.command, "open", "right command");
|
|
assert.strictEqual(command.channel, channel.id, "contains right channel");
|
|
assert.equal(command.host, "scruffy", "host as expected");
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
QUnit.test("multiple", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
const channel = cockpit.channel({ host: "scruffy" });
|
|
const channelb = cockpit.channel({ host: "amy" });
|
|
|
|
const onrecv = event => {
|
|
mock_peer.removeEventListener("recv", onrecv);
|
|
assert.notStrictEqual(channel.id, channelb.id, "channels have different ids");
|
|
done();
|
|
};
|
|
mock_peer.addEventListener("recv", onrecv);
|
|
});
|
|
|
|
QUnit.test("open no host", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
const channel = cockpit.channel({ });
|
|
assert.ok(channel);
|
|
mock_peer.addEventListener("open", function(event) {
|
|
assert.ok(true, "websocket connected");
|
|
});
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const command = JSON.parse(payload);
|
|
if (command.command == "open") {
|
|
assert.strictEqual(command.host, undefined, "host not included");
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
QUnit.test("open auto host", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
force_default_host = "planetexpress";
|
|
const channel = cockpit.channel({ });
|
|
assert.ok(channel);
|
|
mock_peer.addEventListener("open", function(event) {
|
|
assert.ok(true, "websocket connected");
|
|
});
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const command = JSON.parse(payload);
|
|
if (command.command == "open") {
|
|
assert.strictEqual(command.host, "planetexpress", "host automatically chosen");
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
QUnit.test("send message", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(2);
|
|
|
|
const channel = cockpit.channel({ });
|
|
mock_peer.addEventListener("open", function(event) {
|
|
channel.send("Scruffy gonna die the way he lived");
|
|
});
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
/* Ignore the open and init messages */
|
|
if (!chan)
|
|
return;
|
|
assert.strictEqual(chan, channel.id, "sent with correct channel");
|
|
assert.equal(payload, "Scruffy gonna die the way he lived", "sent the right payload");
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("queue messages", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
const sentence = [];
|
|
const channel = cockpit.channel({ });
|
|
channel.send("Scruffy");
|
|
channel.send("knows");
|
|
channel.send("he");
|
|
channel.send("rules");
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
if (!chan)
|
|
return; /* ignore control messages */
|
|
sentence.push(payload);
|
|
if (sentence.length === 4) {
|
|
assert.equal(sentence.join(" "), "Scruffy knows he rules", "messages queued and sent correctly");
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
QUnit.test("receive message", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
const onrecv = (event, chan, payload) => {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "open") {
|
|
mock_peer.removeEventListener("recv", onrecv);
|
|
mock_peer.send(channel.id, "Oh, marrrrmalade!");
|
|
}
|
|
};
|
|
mock_peer.addEventListener("recv", onrecv);
|
|
|
|
const channel = cockpit.channel({ });
|
|
channel.addEventListener("message", function(event, message) {
|
|
assert.equal(message, "Oh, marrrrmalade!", "got right message in channel");
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("close channel", function (assert) {
|
|
const done = assert.async(2);
|
|
assert.expect(4);
|
|
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "init") {
|
|
return;
|
|
} else if (cmd.command == "open") {
|
|
channel.close();
|
|
return;
|
|
}
|
|
assert.equal(cmd.command, "close", "sent close command");
|
|
assert.strictEqual(cmd.channel, channel.id, "correct channel");
|
|
mock_peer.send("", payload);
|
|
done();
|
|
});
|
|
const channel = cockpit.channel({ });
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.ok(true, "triggered event");
|
|
assert.ok(!options.problem, "no problem");
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("close early", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
const channel = cockpit.channel({ });
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.ok(true, "triggered event");
|
|
assert.equal(options.problem, "yo", "got problem");
|
|
done();
|
|
});
|
|
channel.close("yo");
|
|
assert.strictEqual(channel.valid, false, "no longer valid");
|
|
});
|
|
|
|
QUnit.test("close problem", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(5);
|
|
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "init") {
|
|
return;
|
|
} else if (cmd.command == "open") {
|
|
channel.close({ problem: "problem" });
|
|
assert.strictEqual(channel.valid, false, "no longer valid");
|
|
return;
|
|
}
|
|
assert.equal(cmd.command, "close", "sent close command");
|
|
assert.equal(cmd.problem, "problem", "sent reason");
|
|
done();
|
|
});
|
|
const channel = cockpit.channel({ });
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.ok(true, "triggered event");
|
|
assert.equal(options.problem, "problem", "set");
|
|
});
|
|
});
|
|
|
|
QUnit.test("close problem string", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(5);
|
|
|
|
const channel = cockpit.channel({ });
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "init") {
|
|
return;
|
|
} else if (cmd.command == "open") {
|
|
channel.close("testo");
|
|
assert.strictEqual(channel.valid, false, "no longer valid");
|
|
return;
|
|
}
|
|
assert.equal(cmd.command, "close", "sent close command");
|
|
assert.equal(cmd.problem, "testo", "sent reason");
|
|
done();
|
|
});
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.ok(true, "triggered event");
|
|
assert.equal(options.problem, "testo", "set");
|
|
});
|
|
});
|
|
|
|
QUnit.test("close peer", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(5);
|
|
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const msg = JSON.parse(payload);
|
|
if (msg.command == "init")
|
|
return;
|
|
const cmd = {
|
|
command: "close",
|
|
channel: channel.id,
|
|
problem: "marmalade",
|
|
extra: 5
|
|
};
|
|
mock_peer.send("", JSON.stringify(cmd));
|
|
});
|
|
|
|
const channel = cockpit.channel({ });
|
|
const channelb = cockpit.channel({ });
|
|
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.ok(true, "triggered event");
|
|
assert.equal(options.problem, "marmalade", "received reason");
|
|
assert.equal(options.extra, 5, "received extra");
|
|
assert.strictEqual(channel.valid, false, "became invalid");
|
|
assert.strictEqual(channelb.valid, true, "correct channel");
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("close socket", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(4);
|
|
|
|
const channel = cockpit.channel({ });
|
|
const channelb = cockpit.channel({ });
|
|
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.equal(options.problem, "disconnected", "received reason");
|
|
assert.strictEqual(channel.valid, false, "channel is invalid");
|
|
if (!channel.valid && !channelb.valid)
|
|
done();
|
|
});
|
|
|
|
channelb.addEventListener("close", function(event, options) {
|
|
assert.equal(options.problem, "disconnected", "received reason");
|
|
assert.strictEqual(channelb.valid, false, "other channel invalid");
|
|
if (!channel.valid && !channelb.valid)
|
|
done();
|
|
});
|
|
|
|
mock_peer.close();
|
|
});
|
|
|
|
QUnit.test("wait ready", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(5);
|
|
|
|
const channel = cockpit.channel({ payload: "echo" });
|
|
channel.wait().then(function(options) {
|
|
assert.ok(true, "channel is ready");
|
|
assert.equal(typeof options, "object", "wait options");
|
|
assert.ok(!!options, "wait options not null");
|
|
assert.equal(options.command, "ready", "wait is ready");
|
|
assert.strictEqual(channel.valid, true, "when valid");
|
|
}, function() {
|
|
assert.ok(false, "should not fail");
|
|
})
|
|
.always(function() {
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("wait close", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(6);
|
|
|
|
const channel = cockpit.channel({ payload: "unsupported" });
|
|
channel.wait().then(function() {
|
|
assert.ok(false, "should not succeed");
|
|
}, function(options) {
|
|
assert.ok(true, "channel is closed");
|
|
assert.equal(typeof options, "object", "wait options");
|
|
assert.ok(!!options, "wait options not null");
|
|
assert.equal(options.command, "close", "wait is close");
|
|
assert.equal(options.problem, "not-supported", "wait options has fields");
|
|
assert.strictEqual(channel.valid, false, "channel not valid");
|
|
})
|
|
.always(function() {
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("wait callback", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(5);
|
|
|
|
const channel = cockpit.channel({ payload: "unsupported" });
|
|
channel.wait(function(options) {
|
|
assert.equal(typeof options, "object", "wait options");
|
|
assert.ok(!!options, "wait options not null");
|
|
assert.equal(options.command, "close", "wait is close");
|
|
assert.equal(options.problem, "not-supported", "wait options has fields");
|
|
assert.strictEqual(channel.valid, false, "channel not valid");
|
|
}).always(function() {
|
|
done();
|
|
});
|
|
});
|
|
|
|
QUnit.test("logout", function (assert) {
|
|
const done = assert.async();
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "logout") {
|
|
mock_peer.close("disconnected");
|
|
assert.strictEqual(cmd.disconnect, true, "disconnect set");
|
|
}
|
|
});
|
|
|
|
let channel = cockpit.channel({ payload: "echo" });
|
|
let channelb = cockpit.channel({ payload: "echo" });
|
|
|
|
channel.addEventListener("close", function(event, options) {
|
|
assert.equal(options.problem, "disconnected", "received reason");
|
|
assert.strictEqual(channel.valid, false, "channel is invalid");
|
|
channel = null;
|
|
if (channel === null && channelb === null)
|
|
done();
|
|
});
|
|
|
|
channelb.addEventListener("close", function(event, options) {
|
|
assert.equal(options.problem, "disconnected", "received reason");
|
|
assert.strictEqual(channelb.valid, false, "other channel invalid");
|
|
channelb = null;
|
|
if (channel === null && channelb === null)
|
|
done();
|
|
});
|
|
|
|
cockpit.logout(false);
|
|
});
|
|
|
|
QUnit.test("droppriv", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "logout") {
|
|
assert.strictEqual(cmd.disconnect, false, "disconnect not set");
|
|
done();
|
|
}
|
|
});
|
|
|
|
cockpit.drop_privileges();
|
|
});
|
|
|
|
QUnit.test("info", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(4);
|
|
|
|
let info_changed = false;
|
|
|
|
const onchanged = () => {
|
|
assert.strictEqual(cockpit.info.version, "zero.point.zero", "cockpit.info.version");
|
|
assert.strictEqual(cockpit.info.build, "nasty stuff", "cockpit.info.build");
|
|
info_changed = true;
|
|
};
|
|
cockpit.info.addEventListener("changed", onchanged);
|
|
|
|
const onrecv = (event, chan, payload) => {
|
|
const cmd = JSON.parse(payload);
|
|
if (cmd.command == "open") {
|
|
mock_peer.removeEventListener("recv", onrecv);
|
|
cockpit.info.removeEventListener("changed", onchanged);
|
|
assert.strictEqual(info_changed, true, "info changed event was called");
|
|
done();
|
|
}
|
|
};
|
|
mock_peer.addEventListener("recv", onrecv);
|
|
|
|
const channel = cockpit.channel({ host: "scruffy" });
|
|
assert.ok(channel);
|
|
});
|
|
|
|
QUnit.test("send after close", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
console_ignore_log(/sending message on closed.*/);
|
|
|
|
let received_message = false;
|
|
const channel = cockpit.channel({ });
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
if (chan)
|
|
received_message = true;
|
|
});
|
|
|
|
channel.close();
|
|
channel.send("Dern it.");
|
|
|
|
window.setTimeout(function() {
|
|
assert.ok(!received_message, "didn't send message");
|
|
done();
|
|
}, 50);
|
|
});
|
|
|
|
QUnit.test("ignore other commands", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(1);
|
|
|
|
const channel = cockpit.channel({ payload: "echo" });
|
|
|
|
console_ignore_log(/unhandled control message.*/);
|
|
|
|
mock_peer.send(0, JSON.stringify({ command: "ping" }));
|
|
mock_peer.send(0, JSON.stringify({ command: "unexpected" }));
|
|
|
|
window.setTimeout(function() {
|
|
assert.ok(channel.valid, "other messages didn't screw up channel");
|
|
done();
|
|
}, 50);
|
|
});
|
|
|
|
QUnit.test("filter message in", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(14);
|
|
|
|
let filtered = 0;
|
|
let filtering = true;
|
|
cockpit.transport.filter(function(message, channelid, control) {
|
|
if (!filtering)
|
|
return true;
|
|
if (message[0] == '\n') {
|
|
assert.strictEqual(channelid, "", "control message channel");
|
|
assert.equal(typeof control, "object", "control is a JSON object");
|
|
assert.equal(typeof control.command, "string", "control has a command");
|
|
return true;
|
|
} else {
|
|
assert.strictEqual(channelid, channel.id, "cockpit channel id");
|
|
assert.equal(control, undefined, "control is undefined");
|
|
filtered += 1;
|
|
return (filtered != 1);
|
|
}
|
|
});
|
|
|
|
let received = 0;
|
|
const channel = cockpit.channel({ payload: "echo" });
|
|
channel.addEventListener("message", function(data) {
|
|
received += 1;
|
|
|
|
if (received == 2) {
|
|
assert.equal(filtered, 3, "filtered right amount");
|
|
assert.equal(received, 2, "let through right amount");
|
|
channel.close();
|
|
filtering = false;
|
|
done();
|
|
}
|
|
});
|
|
|
|
channel.send("one");
|
|
channel.send("two");
|
|
channel.send("three");
|
|
});
|
|
|
|
QUnit.test("filter message out", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(10);
|
|
|
|
let filtered = 0;
|
|
let filtering = true;
|
|
cockpit.transport.filter(function(message, channelid, control) {
|
|
if (!filtering)
|
|
return true;
|
|
if (message[0] == '\n') {
|
|
assert.strictEqual(channelid, "", "control message channel");
|
|
assert.equal(typeof control, "object", "control is a JSON object");
|
|
assert.equal(typeof control.command, "string", "control has a command");
|
|
} else {
|
|
assert.strictEqual(channelid, channel.id, "cockpit channel id");
|
|
assert.equal(control, undefined, "control is undefined");
|
|
filtered += 1;
|
|
|
|
if (filtered != 1) {
|
|
channel.close();
|
|
filtering = false;
|
|
done();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}, true);
|
|
|
|
const channel = cockpit.channel({ payload: "null" });
|
|
channel.send("one");
|
|
channel.send("two");
|
|
channel.send("three");
|
|
});
|
|
|
|
QUnit.test("inject message out", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(4);
|
|
|
|
const ret = cockpit.transport.inject("bree\nyellow");
|
|
assert.equal(ret, false, "failure returns false");
|
|
|
|
let first = true;
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
if (first) {
|
|
const ret = cockpit.transport.inject("bree\nyellow");
|
|
assert.equal(ret, true, "returned true");
|
|
first = false;
|
|
return;
|
|
}
|
|
|
|
if (chan) {
|
|
assert.equal(chan, "bree", "right channel");
|
|
assert.equal(payload, "yellow", "right payload");
|
|
channel.close();
|
|
done();
|
|
}
|
|
});
|
|
|
|
const channel = cockpit.channel({ });
|
|
});
|
|
|
|
QUnit.test("inject message in", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
const channel = cockpit.channel({ payload: "null" });
|
|
channel.addEventListener("control", function(ev, control) {
|
|
if (control.command == "ready") {
|
|
const payload = JSON.stringify({ command: "blah", blah: "marmalade", channel: channel.id });
|
|
const ret = cockpit.transport.inject("\n" + payload, false);
|
|
assert.equal(ret, true, "returned true");
|
|
} else {
|
|
assert.equal(control.command, "blah", "got right control message");
|
|
assert.equal(control.blah, "marmalade", "got right control data");
|
|
channel.close();
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
QUnit.test("transport options", function (assert) {
|
|
const done = assert.async();
|
|
assert.expect(3);
|
|
|
|
mock_peer.addEventListener("recv", function(event, chan, payload) {
|
|
if (chan) {
|
|
assert.equal(typeof cockpit.transport.options, "object", "is an object");
|
|
assert.deepEqual(cockpit.transport.options, {
|
|
command: "init",
|
|
version: 1,
|
|
"channel-seed": "test",
|
|
"csrf-token": "the-csrf-token",
|
|
user: {
|
|
user: "scruffy",
|
|
name: "Scruffy the Janitor"
|
|
},
|
|
system: {
|
|
version: "zero.point.zero",
|
|
build: "nasty stuff",
|
|
}
|
|
}, "is correct");
|
|
assert.equal(cockpit.transport.csrf_token, "the-csrf-token", "got csrf token");
|
|
channel.close();
|
|
done();
|
|
}
|
|
});
|
|
|
|
const channel = cockpit.channel({ });
|
|
channel.send("blah");
|
|
});
|
|
|
|
QUnit.test("message", function (assert) {
|
|
assert.expect(4);
|
|
assert.strictEqual(cockpit.message("terminated"), "Your session has been terminated.", "problem code");
|
|
assert.strictEqual(cockpit.message({ problem: "timeout" }), "Connection has timed out.", "problem property");
|
|
assert.strictEqual(cockpit.message({ message: "The message", problem: "blah" }), "The message", "problem property");
|
|
assert.strictEqual(cockpit.message(55), "55", "invalid input");
|
|
});
|
|
|
|
window.location.hash = "";
|
|
QUnit.start();
|