fix(portal): hide technical terms in executive demo view

This commit is contained in:
igor04091968
2026-06-04 22:52:03 +03:00
parent 88dcd8ecaa
commit 2cb1afad4f
3 changed files with 53 additions and 3 deletions
+26 -1
View File
@@ -2549,6 +2549,19 @@ fn security_events_summary_text(summary: &SecurityEventsSummary) -> String {
) )
} }
fn security_events_executive_text(summary: &SecurityEventsSummary) -> String {
if summary.backend == "disabled" || summary.status == "disabled" {
return "Источник событий безопасности отключён.".to_string();
}
if summary.fallback_used {
return "События безопасности временно недоступны.".to_string();
}
format!(
"События безопасности доступны: событий за 24 часа {}.",
summary.events_24h
)
}
fn security_events_block(summary: &SecurityEventsSummary) -> SummaryBlock { fn security_events_block(summary: &SecurityEventsSummary) -> SummaryBlock {
SummaryBlock { SummaryBlock {
status: security_events_summary_status(summary), status: security_events_summary_status(summary),
@@ -2844,7 +2857,7 @@ fn build_reports(
)); ));
executive_points.push(format!( executive_points.push(format!(
"События безопасности за 24 часа: {}", "События безопасности за 24 часа: {}",
security_events_summary_text(&security_events_summary) security_events_executive_text(&security_events_summary)
)); ));
executive_points.extend([ executive_points.extend([
format!("Сбор данных: {}. {}", collection.status, collection.text), format!("Сбор данных: {}. {}", collection.status, collection.text),
@@ -10174,6 +10187,15 @@ mod tests {
error: None, error: None,
}; };
assert!(security_events_summary_text(&available).contains("События безопасности доступны")); assert!(security_events_summary_text(&available).contains("События безопасности доступны"));
assert_eq!(
security_events_executive_text(&disabled),
"Источник событий безопасности отключён."
);
assert_eq!(
security_events_executive_text(&fallback),
"События безопасности временно недоступны."
);
assert!(!security_events_executive_text(&disabled).contains("ClickHouse"));
} }
#[test] #[test]
@@ -10733,6 +10755,9 @@ mod tests {
.unwrap() .unwrap()
.contains("Статус связанной картины риска")) .contains("Статус связанной картины риска"))
); );
let executive_points_text = report["executive_points"].to_string();
assert!(!executive_points_text.contains("ClickHouse"));
assert!(!executive_points_text.contains("SECURITY_EVENTS_BACKEND"));
assert!( assert!(
report["markdown"] report["markdown"]
.as_str() .as_str()
@@ -2174,7 +2174,7 @@ function renderSecurityEventsSummary(summary, options = {}) {
: fallback : fallback
? "События безопасности временно недоступны" ? "События безопасности временно недоступны"
: "События безопасности доступны"; : "События безопасности доступны";
const localModeText = disabled ? "Используется локальный режим без ClickHouse" : ""; const localModeText = disabled ? "Локальный режим" : "";
const title = options.compact const title = options.compact
? "События безопасности" ? "События безопасности"
: "События безопасности за 24 часа"; : "События безопасности за 24 часа";
+26 -1
View File
@@ -61,6 +61,24 @@ function expectedSecurityEventsText(mode) {
return ""; return "";
} }
function forbiddenExecutiveTerms(text) {
const forbidden = [
"Trust KPI",
"Business Risk",
"Risk Narrative",
"Security Events",
"Incident Candidate",
"Coverage SLA",
"ERROR",
"EMPTY",
"STALE",
"SECURITY_EVENTS_BACKEND",
"CLICKHOUSE_*",
"ClickHouse",
];
return forbidden.filter((term) => containsText(text, term));
}
function assertStaticTabHandlers() { function assertStaticTabHandlers() {
const index = fs.readFileSync(path.join(root, "adk-rust/crates/detmir-portal/src/static/index.html"), "utf8"); const index = fs.readFileSync(path.join(root, "adk-rust/crates/detmir-portal/src/static/index.html"), "utf8");
const app = fs.readFileSync(path.join(root, "adk-rust/crates/detmir-portal/src/static/app.js"), "utf8"); const app = fs.readFileSync(path.join(root, "adk-rust/crates/detmir-portal/src/static/app.js"), "utf8");
@@ -203,6 +221,12 @@ async function main() {
ok: requiredExecutive.every((marker) => containsText(readyBodyText, marker)), ok: requiredExecutive.every((marker) => containsText(readyBodyText, marker)),
required: requiredExecutive, required: requiredExecutive,
}); });
const forbiddenExecutive = forbiddenExecutiveTerms(readyBodyText);
checks.push({
name: "executive_view_no_technical_terms",
ok: forbiddenExecutive.length === 0,
forbidden: forbiddenExecutive,
});
const cardHeadings = await page.$$eval("#content section.card h3, #content h3.section-title", (nodes) => const cardHeadings = await page.$$eval("#content section.card h3, #content h3.section-title", (nodes) =>
nodes.map((node) => node.textContent.trim()), nodes.map((node) => node.textContent.trim()),
); );
@@ -238,7 +262,8 @@ async function main() {
!expectedSecurityText !expectedSecurityText
|| (containsText(readyBodyText, expectedSecurityText) || (containsText(readyBodyText, expectedSecurityText)
&& !containsText(readyBodyText, "SECURITY_EVENTS_BACKEND") && !containsText(readyBodyText, "SECURITY_EVENTS_BACKEND")
&& !containsText(readyBodyText, "CLICKHOUSE_*")), && !containsText(readyBodyText, "CLICKHOUSE_*")
&& !containsText(readyBodyText, "ClickHouse")),
mode: securityMode, mode: securityMode,
expected_text: expectedSecurityText, expected_text: expectedSecurityText,
}); });