refactor: extract shouldShowClearExitNode and isActiveExitNode to lib.js (TDD) — light progress on #43
- Two small pure UI predicates moved out of QML delegate - QML now calls TailscaleLib.* (thinner glue) - New tests + all existing tests pass - No new state, no architecture change Written by AI agent working for @jtmorris. Model: Grok build-0.1.
This commit is contained in:
parent
0b80f5cdc8
commit
01db16cfd9
3 changed files with 24 additions and 4 deletions
|
|
@ -202,7 +202,7 @@ PluginComponent {
|
|||
}
|
||||
|
||||
MouseArea {
|
||||
visible: root.currentExitNode !== ""
|
||||
visible: TailscaleLib.shouldShowClearExitNode(root.currentExitNode)
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
@ -292,7 +292,7 @@ PluginComponent {
|
|||
id: exitNodeButton
|
||||
text: "↗"
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: root.currentExitNode === modelData.hostname ? Theme.primary : Theme.surfaceVariantText
|
||||
color: TailscaleLib.isActiveExitNode(root.currentExitNode, modelData.hostname) ? Theme.primary : Theme.surfaceVariantText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,15 @@ function getStrings() {
|
|||
}
|
||||
}
|
||||
|
||||
// Light UI predicates extracted from QML (advances #43 — keeps view thin)
|
||||
function shouldShowClearExitNode(currentExitNode) {
|
||||
return currentExitNode !== ""
|
||||
}
|
||||
|
||||
function isActiveExitNode(currentExitNode, hostname) {
|
||||
return currentExitNode === hostname
|
||||
}
|
||||
|
||||
function parseStatusResult(jsonText) {
|
||||
try {
|
||||
const data = JSON.parse(jsonText)
|
||||
|
|
@ -108,5 +117,5 @@ function errorMessage(cmd) {
|
|||
|
||||
// CommonJS export for Node.js tests (ignored by QML)
|
||||
if (typeof module !== "undefined" && module.exports) {
|
||||
module.exports = { parsePeers, makeExitNodeCommand, findActiveExitNode, errorMessage, validateClipboardTool, buildCopyCommand, nextClipboardTool, allClipboardTools, buildToggleCommand, parseStatusResult, getStrings }
|
||||
module.exports = { parsePeers, makeExitNodeCommand, findActiveExitNode, errorMessage, validateClipboardTool, buildCopyCommand, nextClipboardTool, allClipboardTools, buildToggleCommand, parseStatusResult, getStrings, shouldShowClearExitNode, isActiveExitNode }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { test } from "node:test"
|
||||
import assert from "node:assert"
|
||||
import lib from "../tailscalectl/lib.js"
|
||||
const { parsePeers, makeExitNodeCommand, findActiveExitNode, errorMessage, validateClipboardTool, buildCopyCommand, nextClipboardTool, allClipboardTools, buildToggleCommand, parseStatusResult, getStrings } = lib
|
||||
const { parsePeers, makeExitNodeCommand, findActiveExitNode, errorMessage, validateClipboardTool, buildCopyCommand, nextClipboardTool, allClipboardTools, buildToggleCommand, parseStatusResult, getStrings, shouldShowClearExitNode, isActiveExitNode } = lib
|
||||
|
||||
test("parsePeers extracts exitNode from ExitNodeOption", () => {
|
||||
const peerMap = {
|
||||
|
|
@ -157,6 +157,17 @@ test("getStrings.copied interpolates the text", () => {
|
|||
assert.ok(msg.includes("100.64.0.5"))
|
||||
})
|
||||
|
||||
test("shouldShowClearExitNode returns true only when there is a current exit node", () => {
|
||||
assert.strictEqual(shouldShowClearExitNode("router"), true)
|
||||
assert.strictEqual(shouldShowClearExitNode(""), false)
|
||||
})
|
||||
|
||||
test("isActiveExitNode correctly identifies the active exit node button", () => {
|
||||
assert.strictEqual(isActiveExitNode("gluetun-sjc", "gluetun-sjc"), true)
|
||||
assert.strictEqual(isActiveExitNode("gluetun-sjc", "gluetun-den"), false)
|
||||
assert.strictEqual(isActiveExitNode("", "router"), false)
|
||||
})
|
||||
|
||||
// --- buildToggleCommand ---
|
||||
|
||||
test("buildToggleCommand returns down command when connected", () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue