Add advanced Git and deployment workflows, secure backups and auditing, live Gitea integration, desktop notifications, connection validation, and the premium responsive UX refresh.
208 lines
6.8 KiB
JavaScript
208 lines
6.8 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
|
|
test("changed file list has an independently scrollable bounded layout", async () => {
|
|
const css = await readFile(
|
|
new URL("../src/renderer/styles.css", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(
|
|
css,
|
|
/\.main-canvas\.repository-canvas\s*\{[^}]*overflow:\s*hidden/,
|
|
);
|
|
assert.match(
|
|
css,
|
|
/\.file-panel\s*\{[^}]*min-height:\s*0[^}]*overflow:\s*hidden/,
|
|
);
|
|
assert.match(
|
|
css,
|
|
/\.file-list\s*\{[^}]*flex:\s*1 1 auto[^}]*overflow-y:\s*auto/,
|
|
);
|
|
});
|
|
|
|
test("commit workflow explains every disabled prerequisite", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(renderer, /Commit message <span class="required-mark">required/);
|
|
assert.match(renderer, /Enter a commit message to enable commit and push/);
|
|
assert.match(renderer, /ForgeFlow stages the selected files automatically/);
|
|
assert.match(renderer, /data-action="commit-push"/);
|
|
assert.match(renderer, /Commit staged hunks/);
|
|
});
|
|
|
|
test("ITWorx branding is integrated into titlebar and setup", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(renderer, /itworx-mark\.png/);
|
|
assert.match(renderer, /itworx-wordmark-(?:light|dark)\.png/);
|
|
});
|
|
|
|
test("all modal content stays inside the viewport with a persistent action footer", async () => {
|
|
const css = await readFile(
|
|
new URL("../src/renderer/styles.css", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(
|
|
css,
|
|
/\.modal\s*\{[^}]*max-height:\s*calc\(100dvh[^}]*display:\s*flex[^}]*flex-direction:\s*column/,
|
|
);
|
|
assert.match(
|
|
css,
|
|
/\.modal-body\s*\{[^}]*min-height:\s*0[^}]*overflow-y:\s*auto/,
|
|
);
|
|
assert.match(css, /\.modal-footer\s*\{[^}]*flex:\s*0 0 auto/);
|
|
});
|
|
|
|
test("settings provides one-click normalization for legacy Gitea origins", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(renderer, /data-action="normalize-origins"/);
|
|
assert.match(renderer, /Normalize all origins/);
|
|
});
|
|
|
|
test("Git mutations are serialized per repository and expose repair actions", async () => {
|
|
const ipc = await readFile(
|
|
new URL("../src/main/ipc.cjs", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(ipc, /repositoryMutations = new Map/);
|
|
assert.match(ipc, /withRepositoryMutation/);
|
|
assert.match(ipc, /GIT_LOCKS_RECENT/);
|
|
assert.match(ipc, /setTimeout\(resolve, 2_500\)/);
|
|
assert.match(renderer, /data-action="repair-git-locks"/);
|
|
assert.match(renderer, /Repository troubleshooting/);
|
|
assert.match(renderer, /data-action="repair-origin"/);
|
|
assert.match(renderer, /Open guided repository repair/);
|
|
});
|
|
|
|
test("SSH secrets are captured before the loading render clears password inputs", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const passwordCapture = renderer.search(
|
|
/const password = document\.querySelector\(["']#server-password["']\)/,
|
|
);
|
|
const loading = renderer.search(
|
|
/setLoading\(true, ["']Saving encrypted SSH configuration/,
|
|
);
|
|
assert.ok(passwordCapture >= 0 && loading > passwordCapture);
|
|
});
|
|
|
|
test("SSH deployments are polled in the background and Portfolio casing is preserved", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(renderer, /function startOperationPolling\(\)/);
|
|
assert.match(renderer, /startOperationPolling\(\);/);
|
|
assert.match(renderer, /Visible container name/);
|
|
assert.match(renderer, /Compose service \(internal\)/);
|
|
});
|
|
|
|
test("deployment profiles expose built-in/uploaded DockerMan icons and automatic metadata repair", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(renderer, /Built-in high-contrast ITWorx mark/);
|
|
assert.match(renderer, /profile-icon-mode/);
|
|
assert.match(renderer, /Repair DockerMan integration/);
|
|
assert.match(renderer, /reconcile-deployment/);
|
|
});
|
|
|
|
test("repository troubleshooting offers personalized synchronization repair actions", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const ipc = await readFile(
|
|
new URL("../src/main/ipc.cjs", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(renderer, /repair-repository-sync/);
|
|
assert.match(renderer, /safety branch/);
|
|
assert.match(ipc, /repository:repair-sync/);
|
|
});
|
|
|
|
test("advanced Git, desktop, backup, policy and audit workflows are exposed in the renderer", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const preload = await readFile(
|
|
new URL("../preload.cjs", import.meta.url),
|
|
"utf8",
|
|
);
|
|
for (const phrase of [
|
|
"Stage hunks",
|
|
"Conflict guide",
|
|
"Create pull request",
|
|
"Open pull requests",
|
|
"load-pull-requests",
|
|
"Check branch protection",
|
|
"Encrypted configuration backup",
|
|
"Deployment policy",
|
|
"Operational audit log",
|
|
])
|
|
assert.match(renderer, new RegExp(phrase, "i"));
|
|
for (const method of [
|
|
"stageHunks",
|
|
"resolveConflict",
|
|
"createPullRequest",
|
|
"branchProtection",
|
|
"openEditor",
|
|
"openTerminal",
|
|
"exportConfigurationBackup",
|
|
"listAuditEvents",
|
|
])
|
|
assert.match(preload, new RegExp(`${method}:`));
|
|
});
|
|
|
|
test("one-click troubleshooting excludes destructive or publishing Git actions", async () => {
|
|
const renderer = await readFile(
|
|
new URL("../src/renderer/app.js", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const ipc = await readFile(
|
|
new URL("../src/main/ipc.cjs", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(ipc, /action: 'abort-operation', safe: false/);
|
|
assert.match(ipc, /action: 'push', safe: false/);
|
|
assert.match(ipc, /const stale = lock\.ageMs >= 10_000/);
|
|
assert.match(ipc, /\['fast-forward', 'fetch'\]\.includes\(issue\.action\)/);
|
|
assert.doesNotMatch(
|
|
ipc,
|
|
/\['fast-forward', 'push', 'fetch'\]\.includes\(issue\.action\)/,
|
|
);
|
|
assert.match(
|
|
renderer,
|
|
/trouble\?\.issues\?\.some\(\(item\) => item\.repairable && item\.safe\)/,
|
|
);
|
|
});
|
|
|
|
test("premium repository workspace reserves separate rows for actions and release status", async () => {
|
|
const styles = await readFile(
|
|
new URL("../src/renderer/styles.css", import.meta.url),
|
|
"utf8",
|
|
);
|
|
assert.match(
|
|
styles,
|
|
/\.repo-workspace\s*\{[^}]*grid-template-rows:\s*auto auto auto 39px minmax\(0, 1fr\)/s,
|
|
);
|
|
assert.match(styles, /prefers-reduced-motion/);
|
|
assert.match(styles, /ForgeFlow 0\.8 premium visual system/);
|
|
});
|