package.loaded["gettext"] = function(text) return text end package.loaded["ffi/util"] = { template = function(text, ...) local values = { ... } return (text:gsub("%%(%d+)", function(index) return tostring(values[tonumber(index)]) end)) end, } package.loaded["device"] = { model = "test-device" } package.loaded["ui/widget/infomessage"] = { new = function(_, opts) return opts end } package.loaded["ui/widget/inputdialog"] = {} package.loaded["ui/widget/multiinputdialog"] = {} package.loaded["ui/network/manager"] = {} package.loaded["ui/widget/notification"] = {} package.loaded["ui/uimanager"] = {} package.loaded["ffi/sha2"] = { md5 = function(value) return value end } package.loaded["util"] = { trim = function(value) return tostring(value or ""):match("^%s*(.-)%s*$") end, } package.loaded["bookorbit_api"] = {} package.loaded["bookorbit_sweep"] = { syncStatus = function() return { lastSweepAt = 0, matched = 0, unmatched = 0 } end, } package.path = "koreader-plugin/bookorbit.koplugin/?.lua;" .. package.path local MainMenu = require("bookorbit_main_menu") local function assertEqual(actual, expected, label) if actual ~= expected then error(string.format("%s: expected %s, got %s", label, tostring(expected), tostring(actual))) end end local function hasRow(rows, key) for _, row in ipairs(rows) do if type(row) == "table" and row[1] == key then return true end end return false end local function newPlugin(logged_in) local plugin = { SYNC_STRATEGY = { PROMPT = 1, SILENT = 2, DISABLE = 3 }, settings = { auto_sync = true, annotation_sync = true, }, PLUGIN_VERSION = "test", device_id = "123456789", isLoggedIn = function() return logged_in end, getSyncCoordinatorStatus = function() return { pending_count = 0 } end, } MainMenu.install(plugin) return plugin end local plugin = newPlugin(false) local rows = plugin:diagnosticsRows() assertEqual(hasRow(rows, "Server"), true, "logged-out diagnostics shows setup rows") assertEqual(hasRow(rows, "Open highlights"), false, "logged-out diagnostics hides sync state") assertEqual(hasRow(rows, "Last highlight sync"), false, "logged-out diagnostics hides highlight summary") assertEqual(hasRow(rows, "Retry highlight sync"), false, "logged-out diagnostics hides highlight retry") assertEqual(hasRow(rows, "Retry open-book match"), false, "logged-out diagnostics hides match retry") assertEqual(hasRow(rows, "Test connection"), false, "logged-out diagnostics hides connection action without credentials") assertEqual(hasRow(rows, "Recheck all book matches"), false, "logged-out diagnostics hides the match recheck") plugin.settings.server_url = "https://bookorbit.example.com" plugin.settings.username = "reader" plugin.settings.userkey = "secret" rows = plugin:diagnosticsRows() assertEqual(hasRow(rows, "Test connection"), true, "logged-out diagnostics shows connection action with credentials") plugin = newPlugin(true) rows = plugin:diagnosticsRows() assertEqual(hasRow(rows, "Retry highlight sync"), false, "file manager diagnostics hides highlight retry") assertEqual(hasRow(rows, "Retry open-book match"), false, "file manager diagnostics hides match retry") assertEqual(hasRow(rows, "Test connection"), true, "file manager diagnostics keeps connection action") assertEqual(hasRow(rows, "Open highlights"), true, "logged-in diagnostics shows sync state") assertEqual(hasRow(rows, "Last highlight sync"), true, "logged-in diagnostics shows highlight summary") -- "Sync all books" is incremental now, so the full rematch lives here as its -- own explicit maintenance action. assertEqual(hasRow(rows, "Recheck all book matches"), true, "logged-in diagnostics offers the match recheck") plugin.ui = { document = {} } plugin.getDocumentDigest = function() return "digest" end plugin.isOpenBookMatched = function() return true end rows = plugin:diagnosticsRows() assertEqual(hasRow(rows, "Retry highlight sync"), true, "reader diagnostics shows highlight retry") assertEqual(hasRow(rows, "Retry open-book match"), true, "reader diagnostics shows match retry") plugin.settings.annotation_sync = false rows = plugin:diagnosticsRows() assertEqual(hasRow(rows, "Retry highlight sync"), false, "two-way-off diagnostics hides highlight retry") assertEqual(hasRow(rows, "Retry open-book match"), true, "two-way-off diagnostics keeps match retry") -- The Technical details page draws the same facts as titled sections, with -- the actions apart from them. local d = plugin:diagnosticsSections() local titles = {} for _, section in ipairs(d.sections) do table.insert(titles, section.title) end assertEqual(table.concat(titles, ","), "This device,Account,Last results,Library,Sync,Highlights", "logged-in sections in reading order") local kinds = {} for _, action in ipairs(d.actions) do table.insert(kinds, action.kind) end assertEqual(table.concat(kinds, ","), "retry-match,recheck,test,check-update", "reader actions without two-way sync") package.loaded["device"].model = "Kobo_monza" d = plugin:diagnosticsSections() assertEqual(d.sections[1].rows[1][2], "Kobo Libra Colour (Kobo_monza)", "the device is named as sold, with the model id kept for bug reports") plugin = newPlugin(false) d = plugin:diagnosticsSections() assertEqual(#d.sections, 2, "signed out, only the device and the account") assertEqual(#d.actions, 0, "and nothing to run without credentials") print("bookorbit_diagnostics_rows_test.lua: ok")