Replace dual message-channel + RPC setup with a single registerPluginProtocol path, unified sdk.channels (register/request/event/broadcast), RPC keepalive (__p2ns.ping/pong), and core request lifecycle on RPC open. Update global.profile and example.plugin, admin Plugin RPC stats, docs, and test:plugin-rpc. Breaking: upgrade all peers together; no legacy adapters.
87 lines
2.9 KiB
JavaScript
87 lines
2.9 KiB
JavaScript
/**
|
|
* Plugin protomux-rpc contract and channel-rpc unit tests.
|
|
*/
|
|
const assert = require('assert');
|
|
const contract = require('../includes/plugins/plugin-rpc-contract');
|
|
const channelRpc = require('../includes/plugins/channel-rpc');
|
|
|
|
function testReservedMethodDetection() {
|
|
assert.strictEqual(contract.isReservedMethod('__p2ns.ping'), true);
|
|
assert.strictEqual(contract.isReservedMethod('profile.update'), false);
|
|
assert.throws(
|
|
() => contract.assertPluginMethodName('__p2ns.evil'),
|
|
/reserved prefix/
|
|
);
|
|
}
|
|
|
|
function testRegisterRejectsReservedMethods() {
|
|
channelRpc.unregisterRpcMethods('test.plugin', 'demo');
|
|
assert.throws(
|
|
() => channelRpc.registerRpcMethods('test.plugin', 'demo', {
|
|
'__p2ns.ping': async () => null
|
|
}),
|
|
/reserved prefix/
|
|
);
|
|
}
|
|
|
|
function testRegisterAndListMethods() {
|
|
const domain = 'test.plugin';
|
|
const protocol = 'unit';
|
|
channelRpc.unregisterRpcMethods(domain, protocol);
|
|
channelRpc.registerRpcMethods(domain, protocol, {
|
|
'demo.echo': async (value) => ({ echo: value })
|
|
});
|
|
const methods = channelRpc.listRegisteredMethods(domain, protocol);
|
|
assert.ok(methods.includes('demo.echo'));
|
|
channelRpc.unregisterRpcMethods(domain, protocol);
|
|
assert.deepStrictEqual(channelRpc.listRegisteredMethods(domain, protocol), []);
|
|
}
|
|
|
|
function testInstallReservedHandlers() {
|
|
const responded = [];
|
|
const rpc = {
|
|
opened: false,
|
|
closed: false,
|
|
respond(method, _enc, handler) {
|
|
responded.push(method);
|
|
this._handlers = this._handlers || {};
|
|
this._handlers[method] = handler;
|
|
}
|
|
};
|
|
channelRpc.installReservedRpcHandlers(rpc, 'test.plugin', 'keepalive', 'peer1');
|
|
assert.ok(responded.includes(contract.RESERVED.PING));
|
|
assert.ok(responded.includes(contract.RESERVED.PONG));
|
|
channelRpc.installReservedRpcHandlers(rpc, 'test.plugin', 'keepalive', 'peer1');
|
|
assert.strictEqual(responded.filter((m) => m === contract.RESERVED.PING).length, 1);
|
|
}
|
|
|
|
function testWaitForRpcOpenAlreadyOpen() {
|
|
const rpc = { opened: true, closed: false };
|
|
return channelRpc.waitForRpcOpen(rpc, 100).then((ok) => {
|
|
assert.strictEqual(ok, true);
|
|
});
|
|
}
|
|
|
|
function testNoLegacyCoreRequestChannel() {
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const src = fs.readFileSync(path.join(__dirname, '../p2ns.js'), 'utf8');
|
|
assert.ok(!src.includes('registerPluginChannel'), 'p2ns.js must use registerPluginProtocol');
|
|
assert.ok(src.includes('registerPluginProtocol(CORE_DOMAIN, \'request\''), 'core request lifecycle uses registerPluginProtocol');
|
|
}
|
|
|
|
async function main() {
|
|
testReservedMethodDetection();
|
|
testRegisterRejectsReservedMethods();
|
|
testRegisterAndListMethods();
|
|
testInstallReservedHandlers();
|
|
await testWaitForRpcOpenAlreadyOpen();
|
|
testNoLegacyCoreRequestChannel();
|
|
console.log('plugin-channel-rpc.test.js: all tests passed');
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|