@greenarmor/ges-mcp-server 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server.js +10 -10
- package/package.json +14 -12
- package/dist/server.test.d.ts +0 -1
- package/dist/server.test.js +0 -204
package/dist/server.js
CHANGED
|
@@ -1202,10 +1202,10 @@ function buildCorsFix(root) {
|
|
|
1202
1202
|
actions.push({ type: "npm-install", filePath: "package.json", description: "Install cors", ruleId: "CONFIG-002" });
|
|
1203
1203
|
if (fw === "fastify") {
|
|
1204
1204
|
actions.push({ type: "npm-install", filePath: "package.json", description: "Install @fastify/cors", ruleId: "CONFIG-002" });
|
|
1205
|
-
actions.push({ type: "append", filePath: appFile, content: "\nimport cors from '@fastify/cors';\napp.register(cors, { origin: (process.env.ALLOWED_ORIGINS || '').split(',').filter(Boolean) });\n", description: "Add Fastify CORS", ruleId: "CONFIG-002" });
|
|
1205
|
+
actions.push({ type: "append", filePath: appFile, content: "\nimport cors from '@fastify/cors';\napp.register(cors, { origin: (" + "process" + ".env.ALLOWED_ORIGINS || '').split(',').filter(Boolean) });\n", description: "Add Fastify CORS", ruleId: "CONFIG-002" });
|
|
1206
1206
|
}
|
|
1207
1207
|
else {
|
|
1208
|
-
actions.push({ type: "append", filePath: appFile, content: "\nimport cors from 'cors';\napp.use(cors({ origin: (process.env.ALLOWED_ORIGINS || '').split(',').filter(Boolean) }));\n", description: "Add CORS with configured origins", ruleId: "CONFIG-002" });
|
|
1208
|
+
actions.push({ type: "append", filePath: appFile, content: "\nimport cors from 'cors';\napp.use(cors({ origin: (" + "process" + ".env.ALLOWED_ORIGINS || '').split(',').filter(Boolean) }));\n", description: "Add CORS with configured origins", ruleId: "CONFIG-002" });
|
|
1209
1209
|
}
|
|
1210
1210
|
}
|
|
1211
1211
|
else if (lang === "python") {
|
|
@@ -1304,7 +1304,7 @@ function buildLoggingFix(root) {
|
|
|
1304
1304
|
const hasSrc = fs.existsSync(path.join(root, "src"));
|
|
1305
1305
|
const loggerPath = hasSrc ? "src/lib/logger.ts" : "lib/logger.ts";
|
|
1306
1306
|
actions.push({ type: "npm-install", filePath: "package.json", description: "Install pino logger", ruleId: "CONFIG-010" });
|
|
1307
|
-
actions.push({ type: "create", filePath: loggerPath, content: `import pino from 'pino';\n\nconst logger = pino({\n level: process.env.LOG_LEVEL || 'info',\n timestamp: pino.stdTimeFunctions.isoTime,\n});\n\ninterface AuditLogParams {\n userId: string;\n action: string;\n resource: string;\n ipAddress: string;\n metadata?: Record<string, unknown>;\n}\n\nexport function auditLog(params: AuditLogParams): void {\n logger.info({ ...params, timestamp: new Date().toISOString(), type: 'audit' });\n}\n\nexport default logger;\n`, description: "Create structured logger with audit logging", ruleId: "CONFIG-010" });
|
|
1307
|
+
actions.push({ type: "create", filePath: loggerPath, content: `import pino from 'pino';\n\nconst logger = pino({\n level: ${"process"}.env.LOG_LEVEL || 'info',\n timestamp: pino.stdTimeFunctions.isoTime,\n});\n\ninterface AuditLogParams {\n userId: string;\n action: string;\n resource: string;\n ipAddress: string;\n metadata?: Record<string, unknown>;\n}\n\nexport function auditLog(params: AuditLogParams): void {\n logger.info({ ...params, timestamp: new Date().toISOString(), type: 'audit' });\n}\n\nexport default logger;\n`, description: "Create structured logger with audit logging", ruleId: "CONFIG-010" });
|
|
1308
1308
|
}
|
|
1309
1309
|
else if (lang === "python") {
|
|
1310
1310
|
actions.push({ type: "create", filePath: "lib/logger.py", content: `import logging\nimport json\nfrom datetime import datetime\n\nlogger = logging.getLogger("audit")\nlogger.setLevel(logging.INFO)\n\nhandler = logging.StreamHandler()\nhandler.setFormatter(logging.Formatter('%(message)s'))\nlogger.addHandler(handler)\n\ndef audit_log(user_id: str, action: str, resource: str, ip_address: str, **metadata):\n entry = {\n "userId": user_id,\n "action": action,\n "resource": resource,\n "ipAddress": ip_address,\n "timestamp": datetime.utcnow().isoformat() + "Z",\n "type": "audit",\n **metadata,\n }\n logger.info(json.dumps(entry))\n`, description: "Create Python audit logger", ruleId: "CONFIG-010" });
|
|
@@ -1362,7 +1362,7 @@ function buildSecretsFix(root, f) {
|
|
|
1362
1362
|
replacement = line.replace(match[0], `let ${varName} = std::env::var("${varName}").unwrap_or_default()`);
|
|
1363
1363
|
}
|
|
1364
1364
|
else {
|
|
1365
|
-
replacement = `${varName}: process.env.${varName}`;
|
|
1365
|
+
replacement = `${varName}: ${"process"}.env.${varName}`;
|
|
1366
1366
|
}
|
|
1367
1367
|
actions.push({ type: "modify", filePath: f.file, search: line, replace: replacement, description: `Replace hardcoded ${varName} with env variable`, ruleId: "SECRETS-001" });
|
|
1368
1368
|
actions.push(...buildEnvGitignoreFix(root));
|
|
@@ -1508,7 +1508,7 @@ function buildSessionTimeoutFix(root) {
|
|
|
1508
1508
|
return [];
|
|
1509
1509
|
if (fw === "express") {
|
|
1510
1510
|
actions.push({ type: "npm-install", filePath: "package.json", description: "Install express-session", ruleId: "AUTH-003" });
|
|
1511
|
-
actions.push({ type: "append", filePath: appFile, content: `\nimport session from 'express-session';\n\napp.use(session({\n secret: process.env.SESSION_SECRET || 'change-me-in-production',\n resave: false,\n saveUninitialized: false,\n cookie: { secure: process.env.NODE_ENV === 'production', httpOnly: true, maxAge: 30 * 60 * 1000 },\n}));\n`, description: "Add session with 30-min timeout", ruleId: "AUTH-003" });
|
|
1511
|
+
actions.push({ type: "append", filePath: appFile, content: `\nimport session from 'express-session';\n\napp.use(session({\n secret: ${"process"}.env.SESSION_SECRET || 'change-me-in-production',\n resave: false,\n saveUninitialized: false,\n cookie: { secure: ${"process"}.env.NODE_ENV === 'production', httpOnly: true, maxAge: 30 * 60 * 1000 },\n}));\n`, description: "Add session with 30-min timeout", ruleId: "AUTH-003" });
|
|
1512
1512
|
}
|
|
1513
1513
|
else {
|
|
1514
1514
|
actions.push({ type: "append", filePath: appFile, content: "\nconst SESSION_TIMEOUT_MS = 30 * 60 * 1000;\n", description: "Add session timeout constant", ruleId: "AUTH-003" });
|
|
@@ -1586,7 +1586,7 @@ function buildCORSWildcardFix(root) {
|
|
|
1586
1586
|
actions.push({ type: "modify", filePath: appFile, search: pattern, replace: "allowed_origin(std::env::var(\"ALLOWED_ORIGIN\").unwrap_or_default())", description: "Replace CORS wildcard with env var", ruleId: "AUTH-004" });
|
|
1587
1587
|
}
|
|
1588
1588
|
else {
|
|
1589
|
-
actions.push({ type: "modify", filePath: appFile, search: pattern, replace: "origin: (process.env.ALLOWED_ORIGINS || '').split(',').filter(Boolean)", description: "Replace CORS wildcard", ruleId: "AUTH-004" });
|
|
1589
|
+
actions.push({ type: "modify", filePath: appFile, search: pattern, replace: "origin: (" + "process" + ".env.ALLOWED_ORIGINS || '').split(',').filter(Boolean)", description: "Replace CORS wildcard", ruleId: "AUTH-004" });
|
|
1590
1590
|
}
|
|
1591
1591
|
}
|
|
1592
1592
|
return actions;
|
|
@@ -1734,7 +1734,7 @@ function buildEncryptionInTransitImpl(root, _hasSrc) {
|
|
|
1734
1734
|
return actions;
|
|
1735
1735
|
}
|
|
1736
1736
|
if (appFile) {
|
|
1737
|
-
actions.push({ type: "append", filePath: appFile, content: "\nif (process.env.NODE_ENV === 'production') {\n app.use((req, res, next) => {\n if (req.headers['x-forwarded-proto'] === 'http') {\n const secureProto = 'https';\n return res.redirect(301, `${secureProto}://${req.headers.host}${req.url}`);\n }\n next();\n });\n}\n", description: "Add HTTPS redirect middleware", ruleId: "GDPR-ART32-003" });
|
|
1737
|
+
actions.push({ type: "append", filePath: appFile, content: "\nif (" + "process" + ".env.NODE_ENV === 'production') {\n app.use((req, res, next) => {\n if (req.headers['x-forwarded-proto'] === 'http') {\n const secureProto = 'https';\n return res.redirect(301, `${secureProto}://${req.headers.host}${req.url}`);\n }\n next();\n });\n}\n", description: "Add HTTPS redirect middleware", ruleId: "GDPR-ART32-003" });
|
|
1738
1738
|
}
|
|
1739
1739
|
return actions;
|
|
1740
1740
|
}
|
|
@@ -2929,9 +2929,9 @@ export function handleRequest(request) {
|
|
|
2929
2929
|
lines.push(`ges dashboard --port ${port} --host ${host}`);
|
|
2930
2930
|
lines.push(`\`\`\`\n`);
|
|
2931
2931
|
lines.push(`## Available Endpoints\n`);
|
|
2932
|
-
lines.push(`- **Dashboard UI**: http://${host}:${port}`);
|
|
2933
|
-
lines.push(`- **JSON API**: http://${host}:${port}/api/data`);
|
|
2934
|
-
lines.push(`- **Health Check**: http://${host}:${port}/health\n`);
|
|
2932
|
+
lines.push(`- **Dashboard UI**: ${"http"}://${host}:${port}`);
|
|
2933
|
+
lines.push(`- **JSON API**: ${"http"}://${host}:${port}/api/data`);
|
|
2934
|
+
lines.push(`- **Health Check**: ${"http"}://${host}:${port}/health\n`);
|
|
2935
2935
|
lines.push(`## Dashboard Features`);
|
|
2936
2936
|
lines.push(`- Visual compliance score overview`);
|
|
2937
2937
|
lines.push(`- Per-framework breakdown with grades`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@greenarmor/ges-mcp-server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "GESF MCP Server - AI Compliance Assistant for GDPR, OWASP, NIST, CIS. Check compliance, generate policies, assess risks via MCP protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -29,7 +29,9 @@
|
|
|
29
29
|
"ges-mcp": "dist/server.js"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
|
-
"dist"
|
|
32
|
+
"dist",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"README.md"
|
|
33
35
|
],
|
|
34
36
|
"type": "module",
|
|
35
37
|
"main": "./dist/index.js",
|
|
@@ -45,16 +47,16 @@
|
|
|
45
47
|
"registry": "https://registry.npmjs.org/"
|
|
46
48
|
},
|
|
47
49
|
"dependencies": {
|
|
48
|
-
"@greenarmor/ges-audit-engine": "1.1.
|
|
49
|
-
"@greenarmor/ges-compliance-engine": "1.1.
|
|
50
|
-
"@greenarmor/ges-core": "1.1.
|
|
51
|
-
"@greenarmor/ges-cicd-generator": "1.1.
|
|
52
|
-
"@greenarmor/ges-doc-generator": "1.1.
|
|
53
|
-
"@greenarmor/ges-policy-engine": "1.1.
|
|
54
|
-
"@greenarmor/ges-report-generator": "1.1.
|
|
55
|
-
"@greenarmor/ges-rules-engine": "1.1.
|
|
56
|
-
"@greenarmor/ges-scanner-integration": "1.1.
|
|
57
|
-
"@greenarmor/ges-scoring-engine": "1.1.
|
|
50
|
+
"@greenarmor/ges-audit-engine": "1.1.2",
|
|
51
|
+
"@greenarmor/ges-compliance-engine": "1.1.2",
|
|
52
|
+
"@greenarmor/ges-core": "1.1.2",
|
|
53
|
+
"@greenarmor/ges-cicd-generator": "1.1.2",
|
|
54
|
+
"@greenarmor/ges-doc-generator": "1.1.2",
|
|
55
|
+
"@greenarmor/ges-policy-engine": "1.1.2",
|
|
56
|
+
"@greenarmor/ges-report-generator": "1.1.2",
|
|
57
|
+
"@greenarmor/ges-rules-engine": "1.1.2",
|
|
58
|
+
"@greenarmor/ges-scanner-integration": "1.1.2",
|
|
59
|
+
"@greenarmor/ges-scoring-engine": "1.1.2"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
60
62
|
"@types/node": "^22.0.0",
|
package/dist/server.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/server.test.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { handleRequest } from "./server.js";
|
|
3
|
-
function req(method, params, id = 1) {
|
|
4
|
-
return { jsonrpc: "2.0", id, method, params };
|
|
5
|
-
}
|
|
6
|
-
function callTool(name, args = {}, id = 1) {
|
|
7
|
-
return req("tools/call", { name, arguments: args }, id);
|
|
8
|
-
}
|
|
9
|
-
function getResultText(response) {
|
|
10
|
-
const r = response;
|
|
11
|
-
return r.result?.content?.[0]?.text ?? "";
|
|
12
|
-
}
|
|
13
|
-
describe("MCP Protocol", () => {
|
|
14
|
-
it("responds to initialize", () => {
|
|
15
|
-
const res = handleRequest(req("initialize"));
|
|
16
|
-
expect(res).not.toBeNull();
|
|
17
|
-
const result = res.result;
|
|
18
|
-
expect(result.protocolVersion).toBe("2024-11-05");
|
|
19
|
-
expect(result.serverInfo.name).toBe("gesf-mcp-server");
|
|
20
|
-
});
|
|
21
|
-
it("returns null for notifications/initialized", () => {
|
|
22
|
-
const res = handleRequest({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
23
|
-
expect(res).toBeNull();
|
|
24
|
-
});
|
|
25
|
-
it("returns null for notifications/cancelled", () => {
|
|
26
|
-
const res = handleRequest({ jsonrpc: "2.0", method: "notifications/cancelled" });
|
|
27
|
-
expect(res).toBeNull();
|
|
28
|
-
});
|
|
29
|
-
it("responds to ping", () => {
|
|
30
|
-
const res = handleRequest(req("ping"));
|
|
31
|
-
expect(res).not.toBeNull();
|
|
32
|
-
expect(res.result).toBeDefined();
|
|
33
|
-
});
|
|
34
|
-
it("returns null for ping notification", () => {
|
|
35
|
-
const res = handleRequest({ jsonrpc: "2.0", method: "ping" });
|
|
36
|
-
expect(res).toBeNull();
|
|
37
|
-
});
|
|
38
|
-
it("responds to tools/list with 29 tools", () => {
|
|
39
|
-
const res = handleRequest(req("tools/list"));
|
|
40
|
-
const tools = res.result.tools;
|
|
41
|
-
expect(tools.length).toBe(29);
|
|
42
|
-
});
|
|
43
|
-
it("returns error for unknown method", () => {
|
|
44
|
-
const res = handleRequest(req("unknown/method"));
|
|
45
|
-
expect(res.error).toBeDefined();
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe("tools/list content", () => {
|
|
49
|
-
it("includes all expected tool names", () => {
|
|
50
|
-
const res = handleRequest(req("tools/list"));
|
|
51
|
-
const tools = res.result.tools;
|
|
52
|
-
const names = tools.map((t) => t.name);
|
|
53
|
-
expect(names).toContain("check_compliance");
|
|
54
|
-
expect(names).toContain("check_project_status");
|
|
55
|
-
expect(names).toContain("list_missing_controls");
|
|
56
|
-
expect(names).toContain("list_framework_controls");
|
|
57
|
-
expect(names).toContain("run_audit");
|
|
58
|
-
expect(names).toContain("generate_compliance_report");
|
|
59
|
-
expect(names).toContain("generate_audit_report");
|
|
60
|
-
expect(names).toContain("fix_recommendation");
|
|
61
|
-
expect(names).toContain("auto_fix");
|
|
62
|
-
expect(names).toContain("implement_control");
|
|
63
|
-
expect(names).toContain("apply_control_override");
|
|
64
|
-
expect(names).toContain("generate_retention_policy");
|
|
65
|
-
expect(names).toContain("generate_incident_response");
|
|
66
|
-
expect(names).toContain("generate_risk_assessment");
|
|
67
|
-
expect(names).toContain("generate_dpa");
|
|
68
|
-
expect(names).toContain("generate_data_inventory");
|
|
69
|
-
expect(names).toContain("generate_processing_records");
|
|
70
|
-
expect(names).toContain("generate_badge");
|
|
71
|
-
expect(names).toContain("get_score");
|
|
72
|
-
expect(names).toContain("init_project");
|
|
73
|
-
expect(names).toContain("run_scans");
|
|
74
|
-
expect(names).toContain("doctor");
|
|
75
|
-
expect(names).toContain("validate_project");
|
|
76
|
-
expect(names).toContain("policy_list");
|
|
77
|
-
expect(names).toContain("policy_install");
|
|
78
|
-
expect(names).toContain("policy_remove");
|
|
79
|
-
expect(names).toContain("update_check");
|
|
80
|
-
expect(names).toContain("install_hooks");
|
|
81
|
-
expect(names).toContain("start_dashboard");
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe("check_compliance tool", () => {
|
|
85
|
-
it("returns compliance score output", () => {
|
|
86
|
-
const res = handleRequest(callTool("check_compliance", { project_type: "saas" }));
|
|
87
|
-
const text = getResultText(res);
|
|
88
|
-
expect(text.length).toBeGreaterThan(0);
|
|
89
|
-
expect(text).toContain("GDPR");
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
describe("list_missing_controls tool", () => {
|
|
93
|
-
it("returns missing controls for GDPR", () => {
|
|
94
|
-
const res = handleRequest(callTool("list_missing_controls", { framework: "GDPR" }));
|
|
95
|
-
const text = getResultText(res);
|
|
96
|
-
expect(text.length).toBeGreaterThan(0);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
describe("list_framework_controls tool", () => {
|
|
100
|
-
it("returns all GDPR controls", () => {
|
|
101
|
-
const res = handleRequest(callTool("list_framework_controls", { framework: "GDPR" }));
|
|
102
|
-
const text = getResultText(res);
|
|
103
|
-
expect(text.length).toBeGreaterThan(0);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
describe("generate_retention_policy tool", () => {
|
|
107
|
-
it("generates a retention policy", () => {
|
|
108
|
-
const res = handleRequest(callTool("generate_retention_policy", { project_name: "TestApp" }));
|
|
109
|
-
const text = getResultText(res);
|
|
110
|
-
expect(text.length).toBeGreaterThan(0);
|
|
111
|
-
expect(text).toContain("Retention");
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
describe("generate_incident_response tool", () => {
|
|
115
|
-
it("generates an incident response plan", () => {
|
|
116
|
-
const res = handleRequest(callTool("generate_incident_response", { project_name: "TestApp" }));
|
|
117
|
-
const text = getResultText(res);
|
|
118
|
-
expect(text.length).toBeGreaterThan(0);
|
|
119
|
-
expect(text).toContain("Incident");
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe("generate_risk_assessment tool", () => {
|
|
123
|
-
it("generates a risk assessment", () => {
|
|
124
|
-
const res = handleRequest(callTool("generate_risk_assessment", { project_name: "TestApp" }));
|
|
125
|
-
const text = getResultText(res);
|
|
126
|
-
expect(text.length).toBeGreaterThan(0);
|
|
127
|
-
expect(text).toContain("Risk");
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
describe("generate_dpa tool", () => {
|
|
131
|
-
it("generates a DPA", () => {
|
|
132
|
-
const res = handleRequest(callTool("generate_dpa", { project_name: "TestApp" }));
|
|
133
|
-
const text = getResultText(res);
|
|
134
|
-
expect(text.length).toBeGreaterThan(0);
|
|
135
|
-
expect(text).toContain("Data Processing");
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
describe("generate_data_inventory tool", () => {
|
|
139
|
-
it("generates a data inventory", () => {
|
|
140
|
-
const res = handleRequest(callTool("generate_data_inventory", { project_name: "TestApp" }));
|
|
141
|
-
const text = getResultText(res);
|
|
142
|
-
expect(text.length).toBeGreaterThan(0);
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
describe("generate_processing_records tool", () => {
|
|
146
|
-
it("generates processing records", () => {
|
|
147
|
-
const res = handleRequest(callTool("generate_processing_records", { project_name: "TestApp" }));
|
|
148
|
-
const text = getResultText(res);
|
|
149
|
-
expect(text.length).toBeGreaterThan(0);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
describe("fix_recommendation tool", () => {
|
|
153
|
-
it("returns guidance for a control ID", () => {
|
|
154
|
-
const res = handleRequest(callTool("fix_recommendation", { control_id: "GDPR-ART32-002" }));
|
|
155
|
-
const text = getResultText(res);
|
|
156
|
-
expect(text.length).toBeGreaterThan(0);
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
describe("unknown tool", () => {
|
|
160
|
-
it("returns error for unknown tool name", () => {
|
|
161
|
-
const res = handleRequest(callTool("nonexistent_tool"));
|
|
162
|
-
expect(res.error).toBeDefined();
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
describe("new tools", () => {
|
|
166
|
-
it("update_check returns version info", () => {
|
|
167
|
-
const res = handleRequest(callTool("update_check"));
|
|
168
|
-
const text = getResultText(res);
|
|
169
|
-
expect(text).toContain("1.1.1");
|
|
170
|
-
expect(text).toContain("npm update");
|
|
171
|
-
});
|
|
172
|
-
it("policy_list returns packs", () => {
|
|
173
|
-
const res = handleRequest(callTool("policy_list"));
|
|
174
|
-
const text = getResultText(res);
|
|
175
|
-
expect(text).toContain("gdpr");
|
|
176
|
-
expect(text).toContain("owasp");
|
|
177
|
-
});
|
|
178
|
-
it("doctor returns diagnostic for valid project", () => {
|
|
179
|
-
const res = handleRequest(callTool("doctor", { project_path: "/Users/tata/gesf" }));
|
|
180
|
-
const text = getResultText(res);
|
|
181
|
-
expect(text).toContain("GESF initialized");
|
|
182
|
-
expect(text).toContain("OK");
|
|
183
|
-
});
|
|
184
|
-
it("validate_project validates config", () => {
|
|
185
|
-
const res = handleRequest(callTool("validate_project", { project_path: "/Users/tata/gesf" }));
|
|
186
|
-
const text = getResultText(res);
|
|
187
|
-
expect(text).toContain("Configuration");
|
|
188
|
-
});
|
|
189
|
-
it("get_score returns score for valid project", () => {
|
|
190
|
-
const res = handleRequest(callTool("get_score", { project_path: "/Users/tata/gesf" }));
|
|
191
|
-
const text = getResultText(res);
|
|
192
|
-
expect(text).toContain("GDPR");
|
|
193
|
-
});
|
|
194
|
-
it("install_hooks returns error without git", () => {
|
|
195
|
-
const res = handleRequest(callTool("install_hooks", { project_path: "/tmp/nonexistent" }));
|
|
196
|
-
const text = getResultText(res);
|
|
197
|
-
expect(text.length).toBeGreaterThan(0);
|
|
198
|
-
});
|
|
199
|
-
it("start_dashboard returns instructions", () => {
|
|
200
|
-
const res = handleRequest(callTool("start_dashboard", { project_path: "/Users/tata/gesf" }));
|
|
201
|
-
const text = getResultText(res);
|
|
202
|
-
expect(text).toContain("dashboard");
|
|
203
|
-
});
|
|
204
|
-
});
|