132 lines
5.7 KiB
TypeScript
132 lines
5.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
const readSource = () => readFileSync(resolve(__dirname, "./PermissionAccessLogs.vue"), "utf8");
|
|
|
|
describe("PermissionAccessLogs", () => {
|
|
it("prefers province, city and ISP for IP location display", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("formatIpLocation(row)");
|
|
expect(source).toContain("row.ip_province");
|
|
expect(source).toContain("row.ip_city");
|
|
expect(source).toContain("row.ip_isp");
|
|
expect(source).toContain('parts.join(" / ")');
|
|
});
|
|
|
|
it("renders user behavior audit instead of endpoint table or region detail", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("IP访问排行");
|
|
expect(source).toContain("接口访问审计日志");
|
|
expect(source).toContain("terminal-lines");
|
|
expect(source).toContain("keyword");
|
|
expect(source).not.toContain("终端式访问流水");
|
|
expect(source).not.toContain("每行保留接口访问情况,便于快速扫日志");
|
|
expect(source).not.toContain("来源地域明细");
|
|
expect(source).not.toContain('prop="endpoint_key" label="接口"');
|
|
expect(source).not.toContain("fetchIpLocations");
|
|
});
|
|
|
|
it("exposes QA and CTA in role filter presets", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain('const ROLE_FILTER_KEYS = ["ADMIN", "PM", "CRA", "PV", "QA", "CTA"];');
|
|
});
|
|
|
|
it("uses permission template names for role filters and log lines", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("useRoleTemplateMeta");
|
|
expect(source).toContain("const { roleLabel, roleOptionsFor, loadRoleTemplates } = useRoleTemplateMeta();");
|
|
expect(source).toContain("const roleFilterOptions = computed(() => roleOptionsFor(ROLE_FILTER_KEYS));");
|
|
expect(source).toContain('v-for="role in roleFilterOptions"');
|
|
expect(source).toContain("role=${roleLabel(row.role)}");
|
|
expect(source).not.toContain("const ROLE_LABELS");
|
|
expect(source).not.toContain('label="医学审核" value="QA"');
|
|
});
|
|
|
|
it("uses narrow metric cards without helper subtitles", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("min-height: 64px");
|
|
expect(source).toContain("padding: 10px 16px");
|
|
expect(source).not.toContain("<small>{{ card.hint }}</small>");
|
|
expect(source).not.toContain("hint:");
|
|
expect(source).not.toContain("筛选范围内行为总量");
|
|
});
|
|
|
|
it("removes the duplicated audit hero copy", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("audit-filters");
|
|
expect(source).not.toContain("audit-hero");
|
|
expect(source).not.toContain("权限监控 / 访问日志");
|
|
expect(source).not.toContain("用户行为审计");
|
|
expect(source).not.toContain("按用户行为聚合访问记录,接口访问细节保留在终端式流水中");
|
|
});
|
|
|
|
it("streams terminal logs from top to bottom and refreshes in realtime", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("terminalLogRows");
|
|
expect(source).toContain("new Date(a.created_at).getTime() - new Date(b.created_at).getTime()");
|
|
expect(source).toContain("REALTIME_POLL_INTERVAL_MS");
|
|
expect(source).toContain("startRealtimePolling");
|
|
expect(source).toContain("onBeforeUnmount(stopRealtimePolling)");
|
|
expect(source).toContain('ref="terminalWindowRef"');
|
|
expect(source).toContain("scrollTerminalToBottom");
|
|
expect(source).toContain("terminal.scrollTop = terminal.scrollHeight");
|
|
});
|
|
|
|
it("surfaces source IPs in terminal logs and user ranking for network monitoring", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("ip=${ip}");
|
|
expect(source).toContain("user.sample_ip_address || \"未知 IP\"");
|
|
expect(source).toContain("IP访问排行");
|
|
expect(source).toContain("账号");
|
|
expect(source).toContain("rank-location");
|
|
expect(source).not.toContain("rank-ip-line");
|
|
expect(source).not.toContain("来源IP");
|
|
expect(source).not.toContain("去重IP");
|
|
});
|
|
|
|
it("renders low-level security access logs for anonymous and invalid requests", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("showSecurityLog");
|
|
expect(source).toContain('v-if="showSecurityLog"');
|
|
expect(source).toContain("fetchSecurityAccessLogs");
|
|
expect(source).toContain("安全事件审计日志");
|
|
expect(source).toContain("securityTerminalLines");
|
|
expect(source).toContain("auth_status");
|
|
expect(source).toContain("account_label");
|
|
expect(source).toContain("client_ip");
|
|
expect(source).toContain("status_code");
|
|
expect(source).toContain("ANONYMOUS");
|
|
expect(source).toContain("INVALID_TOKEN");
|
|
expect(source).not.toContain("安全访问日志");
|
|
expect(source).not.toContain("记录匿名、无效令牌、拒绝和异常状态请求,用于排查未知 IP 攻击");
|
|
});
|
|
|
|
it("opens both audit logs in realtime downloadable dialogs", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("interfaceLogDialogVisible");
|
|
expect(source).toContain("securityLogDialogVisible");
|
|
expect(source).toContain("openInterfaceLogDialog");
|
|
expect(source).toContain("openSecurityLogDialog");
|
|
expect(source).toContain("if (!showSecurityLog.value) return");
|
|
expect(source).toContain("downloadInterfaceLog");
|
|
expect(source).toContain("downloadSecurityLog");
|
|
expect(source).toContain("downloadLogFile");
|
|
expect(source).toContain("<el-dialog v-model=\"interfaceLogDialogVisible\"");
|
|
expect(source).toContain("<el-dialog v-model=\"securityLogDialogVisible\"");
|
|
expect(source).toContain("下载日志");
|
|
expect(source).toContain("securityTerminalWindowRef");
|
|
expect(source).toContain("scrollSecurityTerminalToBottom");
|
|
});
|
|
});
|