Files
ProxyWarden/src/app/App.view.test.ts
T

153 lines
4.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type {
ApplyConfigurationResult,
PingServerResponse,
} from "../api/tauriCommands";
import type { ComponentStatus } from "../domain/types";
import {
connectionCheckView,
noticeFromConfigurationApply,
pingSummary,
routeChainSegments,
} from "./viewModel";
const runningProxiFyre: ComponentStatus = {
id: "proxyfier",
name: "ProxiFyre",
state: "running",
installed: true,
running: true,
path: "C:\\Tools\\ProxiFyre\\ProxiFyre.exe",
problems: [],
actions: [],
};
describe("App view helpers", () => {
it("describes the external SOCKS5 route without Local sing-box", () => {
const segments = routeChainSegments({
routeMode: "external",
proxyInput: "proxy.example.test:1080",
proxyfier: runningProxiFyre,
singbox: undefined,
singBoxStatus: null,
selectedServer: null,
appCount: 2,
isDetectingComponents: false,
});
expect(segments.map((segment) => segment.id)).toEqual([
"apps",
"proxifyre",
"endpoint",
"exit",
]);
expect(segments[2]).toMatchObject({
value: "proxy.example.test:1080",
tone: "ok",
});
expect(segments[3].details).toContain(
"Local sing-box не нужен для этого маршрута.",
);
});
it("summarizes the fastest successful ping", () => {
const results = [
{ tag: "slow", ok: true, latency: 90 },
{ tag: "failed", ok: false },
{ tag: "fast", ok: true, latency: 20 },
] as PingServerResponse[];
expect(pingSummary(results)).toBe("Ответили 2/3; быстрее fast: 20 ms.");
});
it("builds an expandable route-check result from every backend probe", () => {
const view = connectionCheckView({
routeMode: "external",
proxyInput: "192.168.50.111:8080",
proxyCheck: {
tag: "external",
server: "192.168.50.111",
serverPort: 8080,
ok: true,
latency: 14,
probes: [
{
id: "cloudflare-trace",
name: "Cloudflare Trace",
url: "https://cloudflare.com/cdn-cgi/trace",
ok: true,
status: 200,
latency: 21,
ip: "203.0.113.10",
},
{
id: "ipify",
name: "ipify",
url: "https://api.ipify.org",
ok: false,
error: "timeout",
},
],
},
singbox: undefined,
singBoxStatus: null,
selectedServer: null,
isDetectingComponents: false,
isProxyChecking: false,
});
expect(view).toMatchObject({
checked: true,
endpoint: "192.168.50.111:8080",
tone: "warning",
});
expect(view.probes.map((probe) => probe.id)).toEqual([
"tcp",
"cloudflare-trace",
"ipify",
]);
expect(view.details).toContainEqual({
label: "Cloudflare Trace",
value: "IP 203.0.113.10 · HTTP 200 · 21 ms",
});
expect(view.probes[1]).toMatchObject({
ip: "203.0.113.10",
latency: "21 ms",
status: "Доступна",
});
});
it("shows the result surface while the route check is running", () => {
const view = connectionCheckView({
routeMode: "external",
proxyInput: "192.168.50.111:8080",
proxyCheck: null,
singbox: undefined,
singBoxStatus: null,
selectedServer: null,
isDetectingComponents: false,
isProxyChecking: true,
});
expect(view).toMatchObject({ checked: false, loading: true });
});
it("distinguishes rolled-back and partial apply failures", () => {
const base: ApplyConfigurationResult = {
success: false,
changed: false,
partialState: false,
message: "Helper failed; previous files restored.",
generatedConfigPath:
"C:\\ProgramData\\ProxyWarden\\generated\\proxifyre-app-config.json",
restartRequired: [],
phases: [],
};
expect(noticeFromConfigurationApply(base).title).toBe("Изменения отменены");
expect(
noticeFromConfigurationApply({ ...base, partialState: true }).title,
).toBe("Проверь состояние файлов");
});
});