mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-09-21 17:04:00 +00:00
Manual changes following smoke test
This commit is contained in:
@@ -20,6 +20,12 @@ lib.Link.register(messages.AssignmentUpdateRequest);
|
||||
|
||||
const logger = { child: () => logger, info: () => {}, warn: () => {}, error: () => {}, verbose: () => {} };
|
||||
|
||||
// Silence the singleton logger to avoid polluting the test output
|
||||
lib.logger.silent = true;
|
||||
t.after(() => {
|
||||
lib.logger.silent = false;
|
||||
});
|
||||
|
||||
/** Build a plugin around a real controller, which is side effect free while not started. */
|
||||
async function startPlugin(t2, { roles = [] } = {}) {
|
||||
const controllerConfig = new lib.ControllerConfig("controller", {
|
||||
@@ -173,6 +179,18 @@ t.test("class ControllerPlugin", t2 => {
|
||||
t3.strictSame(applied.length, 1, "other player events do not");
|
||||
});
|
||||
|
||||
t2.test(".handleRoleListRequest() returns the current roles", async t3 => {
|
||||
const { plugin } = await startPlugin(t3, {
|
||||
roles: [role(1, "Player"), role(5, "Moderator")],
|
||||
});
|
||||
plugin.roleMeta.set(new messages.RoleMetaRecord(5, 2, 0, "Mod"));
|
||||
|
||||
const response = await plugin.handleRoleListRequest(new messages.RoleListRequest());
|
||||
t3.strictSame(response.length, 2, "the current roles are returned");
|
||||
t3.ok(response.some(record => record.name === "Moderator"));
|
||||
t3.ok(response.some(record => record.name === "Player"));
|
||||
});
|
||||
|
||||
t2.test(".handleRoleMetaUpdateRequest() validates the role", async t3 => {
|
||||
const { plugin } = await startPlugin(t3, { roles: [role(1, "Player"), role(5, "Moderator")] });
|
||||
|
||||
@@ -187,6 +205,19 @@ t.test("class ControllerPlugin", t2 => {
|
||||
t3.strictSame(plugin.roleMeta.get(5).shortHand, "Mod", "the properties are stored");
|
||||
});
|
||||
|
||||
t2.test(".handleAssignmentListRequest() returns the current assignments", async t3 => {
|
||||
const { plugin, controller } = await startPlugin(t3, {
|
||||
roles: [role(1, "Player"), role(5, "Moderator")],
|
||||
});
|
||||
controller.users.createUser("alice").set("roleIds", new Set([5]));
|
||||
controller.users.createUser("bob");
|
||||
|
||||
const response = await plugin.handleAssignmentListRequest(new messages.AssignmentListRequest());
|
||||
t3.strictSame(response.length, 1, "the current assignments are returned");
|
||||
t3.strictSame(response[0].name, "alice");
|
||||
t3.strictSame(response[0].roleIds, new Set([5]), "the default role is not listed");
|
||||
});
|
||||
|
||||
t2.test(".handleAssignmentSubscription() replays only newer records", async t3 => {
|
||||
const { plugin, controller } = await startPlugin(t3, { roles: [role(1, "Player"), role(5, "Moderator")] });
|
||||
controller.users.createUser("alice").set("roleIds", new Set([5]));
|
||||
|
||||
@@ -7,18 +7,18 @@ const fullMeta = new messages.RoleMetaRecord(
|
||||
7, 3, 1, "Mod", "[Mod]", new messages.RoleColor(1, 2, 3), 3600000, true, 12345, false,
|
||||
);
|
||||
|
||||
t.test("class RoleColor", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.RoleColor, testMatrix(
|
||||
t.test("class RoleColor", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.RoleColor, testMatrix(
|
||||
[0, 255], // r
|
||||
[0, 128], // g
|
||||
[0, 1], // b
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("class RoleMetaRecord", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.RoleMetaRecord, testMatrix(
|
||||
t.test("class RoleMetaRecord", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.RoleMetaRecord, testMatrix(
|
||||
[7], // id
|
||||
[3], // order
|
||||
[0, 1], // priority
|
||||
@@ -30,12 +30,12 @@ t.test("class RoleMetaRecord", subtest => {
|
||||
[0, 12345], // updatedAtMs
|
||||
[false, true], // isDeleted
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("class RoleRecord", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.RoleRecord, testMatrix(
|
||||
t.test("class RoleRecord", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.RoleRecord, testMatrix(
|
||||
[7], // id
|
||||
["Moderator"], // name
|
||||
[[], ["a.b", "c.d"]], // permissions
|
||||
@@ -44,67 +44,73 @@ t.test("class RoleRecord", subtest => {
|
||||
[0, 12345], // updatedAtMs
|
||||
[false, true], // isDeleted
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("class AssignmentRecord", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.AssignmentRecord, testMatrix(
|
||||
t.test("class AssignmentRecord", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.AssignmentRecord, testMatrix(
|
||||
["alice"], // name
|
||||
[new Set(), new Set([5, 6])], // roleIds
|
||||
[0, 12345], // updatedAtMs
|
||||
[false, true], // isDeleted
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.test("get id()", t3 => {
|
||||
const record = new messages.AssignmentRecord("alice", new Set([5]), 12345);
|
||||
t3.equal(record.id, "alice");
|
||||
t3.end();
|
||||
});
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
const sampleRecord = new messages.RoleRecord(7, "Moderator", ["a.b"], fullMeta, true, 12345);
|
||||
const sampleAssignment = new messages.AssignmentRecord("alice", new Set([5]), 12345);
|
||||
|
||||
t.test("class RoleUpdatedEvent", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.RoleUpdatedEvent, testMatrix(
|
||||
t.test("class RoleUpdatedEvent", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.RoleUpdatedEvent, testMatrix(
|
||||
[[], [sampleRecord]], // updates
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("class AssignmentUpdatedEvent", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.AssignmentUpdatedEvent, testMatrix(
|
||||
t.test("class AssignmentUpdatedEvent", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.AssignmentUpdatedEvent, testMatrix(
|
||||
[[], [sampleAssignment]], // updates
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("class RoleMetaUpdateRequest", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.RoleMetaUpdateRequest, testMatrix(
|
||||
t.test("class RoleMetaUpdateRequest", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.RoleMetaUpdateRequest, testMatrix(
|
||||
[new messages.RoleMetaRecord(7, 3), fullMeta], // meta
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("class AssignmentUpdateRequest", subtest => {
|
||||
testRoundTripJsonSerialisable(messages.AssignmentUpdateRequest, testMatrix(
|
||||
t.test("class AssignmentUpdateRequest", t2 => {
|
||||
testRoundTripJsonSerialisable(t2, messages.AssignmentUpdateRequest, testMatrix(
|
||||
["alice"], // name
|
||||
[[], [5]], // assign
|
||||
[[], [6]], // unassign
|
||||
));
|
||||
subtest.pass("round trips");
|
||||
subtest.end();
|
||||
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("encodeRolesForLua() sends each permission name once", subtest => {
|
||||
t.test("encodeRolesForLua() sends each permission name once", t2 => {
|
||||
const meta = id => new messages.RoleMetaRecord(id, id);
|
||||
const encoded = messages.encodeRolesForLua([
|
||||
new messages.RoleRecord(1, "A", ["p.one", "p.two"], meta(1)),
|
||||
new messages.RoleRecord(2, "B", ["p.two", "p.three"], meta(2)),
|
||||
]);
|
||||
|
||||
subtest.strictSame(encoded.permission_names, ["p.one", "p.two", "p.three"], "names are deduplicated");
|
||||
subtest.strictSame(encoded.roles[0].permissions, [0, 1], "indexes are zero based");
|
||||
subtest.strictSame(encoded.roles[1].permissions, [1, 2], "shared names reuse their index");
|
||||
subtest.end();
|
||||
t2.strictSame(encoded.permission_names, ["p.one", "p.two", "p.three"], "names are deduplicated");
|
||||
t2.strictSame(encoded.roles[0].permissions, [0, 1], "indexes are zero based");
|
||||
t2.strictSame(encoded.roles[1].permissions, [1, 2], "shared names reuse their index");
|
||||
t2.end();
|
||||
});
|
||||
|
||||
@@ -3,12 +3,12 @@ const path = require("node:path");
|
||||
const t = require("tap");
|
||||
const { reportLuaTests } = require("../../test/lua/runner");
|
||||
|
||||
const envFile = path.join(__dirname, "lua", "env.lua");
|
||||
const envFile = path.join(__dirname, "module", "env.lua");
|
||||
|
||||
// Each file runs in its own lua state, and each test in a fresh environment
|
||||
t.test("module/control.lua", t2 => {
|
||||
t.test("control.lua", t2 => {
|
||||
for (const file of ["lookup.lua", "players.lua", "assignment.lua", "sync.lua", "holders.lua"]) {
|
||||
t2.test(`lua/${file}`, subtest => reportLuaTests(subtest, envFile, path.join(__dirname, "lua", file)));
|
||||
t2.test(file, t3 => reportLuaTests(t3, envFile, path.join(__dirname, "module", file)));
|
||||
}
|
||||
t2.end();
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
--- Tests for the assignment methods of module/control.lua
|
||||
local Suite = ... --- The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local Suite = ... --- @type Suite The suite this file adds its tests to, see env.lua
|
||||
local test, check, eq, empty = Suite.test, Suite.check, Suite.eq, Suite.empty
|
||||
|
||||
--- alice is a moderator and bob a regular, with changes sent to the controller
|
||||
@@ -8,10 +8,10 @@ returned here becomes `...` in each test file.
|
||||
]]
|
||||
|
||||
local shared_root = ... --- @type string
|
||||
local source = assert(debug.getinfo(1, "S")).source
|
||||
local plugin_root = assert(source:match("^@(.*)/test/lua/env%.lua$"))
|
||||
local source = assert(debug.getinfo(1, "S")).source:gsub("\\", "/")
|
||||
local plugin_root = assert(source:match("^@(.*)/test/module/env%.lua$"))
|
||||
|
||||
local Framework = assert(loadfile(shared_root .. "/framework.lua"))()
|
||||
local Framework = assert(loadfile(shared_root .. "/framework.lua"))() --- @type Framework
|
||||
|
||||
--- Standard fixture: permission names sent once and referenced by zero based index
|
||||
local permission_names = {
|
||||
@@ -48,7 +48,7 @@ for _, record in ipairs(role_records()) do
|
||||
end
|
||||
|
||||
return Framework.suite(function(env)
|
||||
env.Roles = assert(loadfile(plugin_root .. "/module/control.lua"))()
|
||||
env.Roles = assert(loadfile(plugin_root .. "/module/control.lua"))() --- @type ExpRoles
|
||||
env.Roles.on_server_startup()
|
||||
|
||||
--- Get a fixture role by name, failing the test when it does not exist
|
||||
@@ -1,5 +1,5 @@
|
||||
--- Tests for listing and printing to the players who hold a role
|
||||
local Suite = ... --- The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local Suite = ... --- @type Suite The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local test, check, eq = Suite.test, Suite.check, Suite.eq
|
||||
|
||||
--- alice and dave are moderators with dave offline, zed has never joined
|
||||
@@ -1,5 +1,5 @@
|
||||
--- Tests for the role lookup functions of module/control.lua
|
||||
local Suite = ... --- The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local Suite = ... --- @type Suite The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local test, check, eq = Suite.test, Suite.check, Suite.eq
|
||||
|
||||
test("get_role() returns the role with the given clusterio id", function(env)
|
||||
@@ -1,5 +1,5 @@
|
||||
--- Tests for the player checks of module/control.lua
|
||||
local Suite = ... --- The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local Suite = ... --- @type Suite The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local test, check, eq = Suite.test, Suite.check, Suite.eq
|
||||
|
||||
--- alice is a moderator, bob is a regular, and carol has only the default role
|
||||
@@ -1,5 +1,5 @@
|
||||
--- Tests for the sync entry points of module/control.lua
|
||||
local Suite = ... --- The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local Suite = ... --- @type Suite The suite this file adds its tests to, see test/lua/framework.lua
|
||||
local test, check, eq, empty = Suite.test, Suite.check, Suite.eq, Suite.empty
|
||||
|
||||
--- alice is a moderator and carol has only the default role, both connected
|
||||
+37
-15
@@ -6,35 +6,57 @@ const { seedRoles, flattenSeedPermissions } = require("../dist/node/seed");
|
||||
// Importing this defines the exp_scenario permissions the seed grants
|
||||
require("@expcluster/scenario/dist/node/permissions");
|
||||
|
||||
t.test("seedRoles grant only defined permissions", subtest => {
|
||||
t.test("seedRoles[] grant only defined permissions", t2 => {
|
||||
for (const role of seedRoles) {
|
||||
for (const permission of flattenSeedPermissions(role)) {
|
||||
subtest.ok(lib.permissions.has(permission), `${role.name} grants defined permission ${permission}`);
|
||||
for (const permission of role.permissions) {
|
||||
t2.ok(lib.permissions.has(permission), `${role.name} grants defined permission ${permission}`);
|
||||
}
|
||||
}
|
||||
subtest.end();
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("flattenSeedPermissions() carries parents into their children", subtest => {
|
||||
t.test("seedRoles[] are unique with one default and one admin", t2 => {
|
||||
const names = seedRoles.map(role => role.name);
|
||||
t2.strictSame(names.length, new Set(names).size, "names are unique");
|
||||
t2.strictSame(seedRoles.filter(role => role.isDefault).length, 1, "one default role");
|
||||
t2.strictSame(seedRoles.filter(role => role.isAdmin).length, 1, "one admin role");
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("flattenSeedPermissions() inherits permissions from parent roles", t2 => {
|
||||
const byName = new Map(seedRoles.map(role => [role.name, role]));
|
||||
for (const role of seedRoles) {
|
||||
if (role.parent === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const parent = byName.get(role.parent);
|
||||
subtest.ok(parent, `${role.name} has parent ${role.parent}`);
|
||||
t2.ok(parent, `${role.name} has parent ${role.parent}`);
|
||||
|
||||
const flattened = flattenSeedPermissions(role);
|
||||
for (const permission of flattenSeedPermissions(parent)) {
|
||||
subtest.ok(flattened.has(permission), `${role.name} inherits ${permission}`);
|
||||
t2.ok(flattened.has(permission), `${role.name} inherits ${permission}`);
|
||||
}
|
||||
}
|
||||
subtest.end();
|
||||
t2.end();
|
||||
});
|
||||
|
||||
t.test("seedRoles are unique with one default and one admin", subtest => {
|
||||
const names = seedRoles.map(role => role.name);
|
||||
subtest.strictSame(names.length, new Set(names).size, "names are unique");
|
||||
subtest.strictSame(seedRoles.filter(role => role.isDefault).length, 1, "one default role");
|
||||
subtest.strictSame(seedRoles.filter(role => role.isAdmin).length, 1, "one admin role");
|
||||
subtest.end();
|
||||
});
|
||||
t.test("flattenSeedPermissions() does not inherit permissions when parent is undefined", t2 => {
|
||||
for (const role of seedRoles) {
|
||||
if (role.parent !== undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const flattened = flattenSeedPermissions(role);
|
||||
for (const permission of role.permissions) {
|
||||
t2.ok(flattened.has(permission), `${role.name} contains ${permission}`);
|
||||
}
|
||||
|
||||
t2.equal(
|
||||
flattened.size,
|
||||
role.permissions.length,
|
||||
`${role.name} has no inherited permissions`,
|
||||
);
|
||||
}
|
||||
t2.end();
|
||||
});
|
||||
Reference in New Issue
Block a user