cc-libs/packages/trapos-cloud/tests/cloud-program.lua

193 lines
6.0 KiB
Lua

local createLibTest = require('/apis/libtest');
local testlib = createLibTest({ ... });
local function containsLine(lines, expected)
for _, line in ipairs(lines) do
if line == expected then return true; end
end
return false;
end
local function containsText(lines, expected)
for _, line in ipairs(lines) do
if string.find(line, expected, 1, true) then return true; end
end
return false;
end
local function fakeSettings(values)
return {
values = values or {},
saveCount = 0,
get = function(self, key)
return self.values[key];
end,
set = function(self, key, value)
self.values[key] = value;
end,
save = function(self)
self.saveCount = self.saveCount + 1;
return true;
end,
};
end
local function runCloud(args, opts)
opts = opts or {};
local lines = {};
local writes = {};
local readMasks = {};
local cloudRequests = {};
local settingsLib = opts.settings or fakeSettings();
local readValues = opts.readValues or {};
local env = setmetatable({
print = function(line)
lines[#lines + 1] = line or '';
end,
write = function(text)
writes[#writes + 1] = text or '';
end,
read = function(mask)
readMasks[#readMasks + 1] = mask;
local value = readValues[#readMasks];
if value == nil then return ''; end
return value;
end,
settings = {
get = function(key) return settingsLib:get(key); end,
set = function(key, value) return settingsLib:set(key, value); end,
save = function() return settingsLib:save(); end,
},
require = function(path)
if path == '/apis/libcloud' then
return function()
return {
request = function(msgType, payload, requestOpts)
cloudRequests[#cloudRequests + 1] = {
msgType = msgType,
payload = payload,
opts = requestOpts,
};
return opts.requestOk ~= false, opts.requestResult or { serverOk = true, opencodeOk = true };
end,
};
end;
end
if path == '/apis/libversion' then
return function()
return { forSelf = function() return '0.0.0-test'; end };
end;
end
return require(path);
end,
}, { __index = _G });
local chunk, loadErr = loadfile('/programs/cloud.lua', 't', env);
if not chunk then error(loadErr, 0); end
local ok, err = pcall(chunk, table.unpack(args or {}));
if not ok then error(err, 0); end
return {
lines = lines,
writes = writes,
readMasks = readMasks,
cloudRequests = cloudRequests,
settings = settingsLib,
};
end
testlib.test('cloud help lists status and set-password without health', function()
local ctx = runCloud({ '--help' });
testlib.assertTrue(containsLine(ctx.lines, ' cloud status'));
testlib.assertTrue(containsLine(ctx.lines, ' cloud set-password [--force|-f]'));
testlib.assertTrue(not containsLine(ctx.lines, ' cloud health'));
end);
testlib.test('cloud health is not kept as an alias', function()
local ctx = runCloud({ 'health' }, {
settings = fakeSettings({ ['cloud.url'] = 'wss://example.test' }),
});
testlib.assertEquals(#ctx.cloudRequests, 0);
testlib.assertTrue(containsLine(ctx.lines, 'cloud usage:'));
end);
testlib.test('cloud status probes the server', function()
local ctx = runCloud({ 'status' }, {
settings = fakeSettings({ ['cloud.url'] = 'wss://example.test' }),
requestResult = { serverOk = true, opencodeOk = false, opencodeDetail = 'missing key' },
});
testlib.assertEquals(#ctx.cloudRequests, 1);
testlib.assertEquals(ctx.cloudRequests[1].msgType, 'probe_server');
testlib.assertTrue(containsLine(ctx.lines, 'serverOk: true'));
testlib.assertTrue(containsLine(ctx.lines, 'opencodeOk: false'));
testlib.assertTrue(containsLine(ctx.lines, 'opencode: missing key'));
end);
testlib.test('cloud set-password stores a missing password with masked input', function()
local settingsLib = fakeSettings();
local ctx = runCloud({ 'set-password' }, {
settings = settingsLib,
readValues = { 'hunter2' },
});
testlib.assertEquals(ctx.writes[1], 'Password: ');
testlib.assertEquals(ctx.readMasks[1], '*');
testlib.assertEquals(settingsLib.values['cloud.password'], 'hunter2');
testlib.assertEquals(settingsLib.saveCount, 1);
testlib.assertTrue(containsLine(ctx.lines, 'cloud.password set'));
end);
testlib.test('cloud set-password rejects replacing without force', function()
local settingsLib = fakeSettings({ ['cloud.password'] = 'old' });
local ctx = runCloud({ 'set-password' }, {
settings = settingsLib,
readValues = { 'new' },
});
testlib.assertEquals(#ctx.readMasks, 0);
testlib.assertEquals(settingsLib.values['cloud.password'], 'old');
testlib.assertEquals(settingsLib.saveCount, 0);
testlib.assertTrue(containsText(ctx.lines, 'use cloud set-password --force'));
end);
testlib.test('cloud set-password --force replaces an existing password', function()
local settingsLib = fakeSettings({ ['cloud.password'] = 'old' });
runCloud({ 'set-password', '--force' }, {
settings = settingsLib,
readValues = { 'new' },
});
testlib.assertEquals(settingsLib.values['cloud.password'], 'new');
testlib.assertEquals(settingsLib.saveCount, 1);
end);
testlib.test('cloud set-password -f replaces an existing password', function()
local settingsLib = fakeSettings({ ['cloud.password'] = 'old' });
runCloud({ 'set-password', '-f' }, {
settings = settingsLib,
readValues = { 'new' },
});
testlib.assertEquals(settingsLib.values['cloud.password'], 'new');
testlib.assertEquals(settingsLib.saveCount, 1);
end);
testlib.test('cloud set-password rejects an empty password', function()
local settingsLib = fakeSettings();
local ctx = runCloud({ 'set-password' }, {
settings = settingsLib,
readValues = { '' },
});
testlib.assertEquals(settingsLib.values['cloud.password'], nil);
testlib.assertEquals(settingsLib.saveCount, 0);
testlib.assertTrue(containsLine(ctx.lines, 'cloud.password not changed: password cannot be empty'));
end);
testlib.run();