diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index ad6f159..0d3cb38 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,12 +4,30 @@
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -36,12 +54,12 @@
-
+
@@ -58,44 +76,44 @@
- {
+ "keyToString": {
+ "NIXITCH_NIXPKGS_CONFIG": "",
+ "NIXITCH_NIX_CONF_DIR": "",
+ "NIXITCH_NIX_OTHER_STORES": "",
+ "NIXITCH_NIX_PATH": "",
+ "NIXITCH_NIX_PROFILES": "",
+ "NIXITCH_NIX_REMOTE": "",
+ "NIXITCH_NIX_USER_PROFILE_DIR": "",
+ "Node.js.index.ts.executor": "Run",
+ "RunOnceActivity.MCP Project settings loaded": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
+ "RunOnceActivity.git.unshallow": "true",
+ "RunOnceActivity.typescript.service.memoryLimit.init": "true",
+ "com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
+ "git-widget-placeholder": "main",
+ "go.import.settings.migrated": "true",
+ "javascript.preferred.runtime.type.id": "node",
+ "junie.onboarding.icon.badge.shown": "true",
+ "last_opened_file_path": "//wsl.localhost/Ubuntu/home/ahilbig/git/vcr/zabbix-graphql-api/src",
+ "node.js.detected.package.eslint": "true",
+ "node.js.detected.package.tslint": "true",
+ "node.js.selected.package.eslint": "(autodetect)",
+ "node.js.selected.package.tslint": "(autodetect)",
+ "nodejs_interpreter_path": "wsl://Ubuntu@/home/ahilbig/.nvm/versions/node/v24.12.0/bin/node",
+ "nodejs_package_manager_path": "npm",
+ "npm.codegen.executor": "Run",
+ "npm.compile.executor": "Run",
+ "npm.copy-schema.executor": "Run",
+ "npm.prod.executor": "Run",
+ "npm.test.executor": "Run",
+ "settings.editor.selected.configurable": "settings.javascript.runtime",
+ "to.speed.mode.migration.done": "true",
+ "ts.external.directory.path": "\\\\wsl.localhost\\Ubuntu\\home\\ahilbig\\git\\vcr\\zabbix-graphql-api\\node_modules\\typescript\\lib",
+ "vue.rearranger.settings.migration": "true"
}
-}]]>
+}
@@ -115,7 +133,7 @@
-
+
@@ -356,7 +374,15 @@
1769531308340
-
+
+
+ 1769535965694
+
+
+
+ 1769535965695
+
+
@@ -374,8 +400,6 @@
-
-
@@ -397,7 +421,12 @@
-
+
+
+
+
+
+
diff --git a/.junie/guidelines.md b/.junie/guidelines.md
new file mode 100644
index 0000000..c72f30e
--- /dev/null
+++ b/.junie/guidelines.md
@@ -0,0 +1,4 @@
+# Junie Guidelines
+
+- Always include "Optimize imports" as a step in the plan before executing any commits or finishing a task (via `submit`).
+- This ensures consistency with the project's IntelliJ IDEA settings (`OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT` is enabled).
diff --git a/src/common_utils.ts b/src/common_utils.ts
index 937350c..4fcb46d 100644
--- a/src/common_utils.ts
+++ b/src/common_utils.ts
@@ -1,4 +1,5 @@
import {configDotenv} from "dotenv";
+
configDotenv();
export class Config {
diff --git a/src/datasources/zabbix-hosts.ts b/src/datasources/zabbix-hosts.ts
index b583e48..f0874d0 100644
--- a/src/datasources/zabbix-hosts.ts
+++ b/src/datasources/zabbix-hosts.ts
@@ -9,7 +9,6 @@ import {
ZabbixResult
} from "./zabbix-request.js";
import {ZabbixHistoryGetParams, ZabbixQueryHistoryRequest} from "./zabbix-history.js";
-import {isArray} from "node:util";
export class ZabbixQueryHostsGenericRequest extends ZabbixRequest {
diff --git a/src/datasources/zabbix-templates.ts b/src/datasources/zabbix-templates.ts
index 9352010..826158a 100644
--- a/src/datasources/zabbix-templates.ts
+++ b/src/datasources/zabbix-templates.ts
@@ -1,8 +1,4 @@
-
-import {isZabbixErrorResult, ParsedArgs, ZabbixRequest} from "./zabbix-request.js";
-import {ZabbixAPI} from "./zabbix-api.js";
-import {logger} from "../logging/logger.js";
-
+import {ZabbixRequest} from "./zabbix-request.js";
export interface ZabbixQueryTemplateResponse {
diff --git a/src/datasources/zabbix-usergroups.ts b/src/datasources/zabbix-usergroups.ts
index d728298..5c61a52 100644
--- a/src/datasources/zabbix-usergroups.ts
+++ b/src/datasources/zabbix-usergroups.ts
@@ -10,7 +10,7 @@ import {
} from "./zabbix-request.js";
import {
ApiError,
- ImportUserRightResult, Permission,
+ ImportUserRightResult,
UserGroup,
UserGroupInput,
ZabbixGroupRight,
diff --git a/src/execution/host_exporter.ts b/src/execution/host_exporter.ts
index 084c060..3606d02 100644
--- a/src/execution/host_exporter.ts
+++ b/src/execution/host_exporter.ts
@@ -1,7 +1,9 @@
import {
ApiError,
- GenericResponse, QueryExportHostValueHistoryArgs,
- StorageItemType, ZabbixItem
+ GenericResponse,
+ QueryExportHostValueHistoryArgs,
+ StorageItemType,
+ ZabbixItem
} from "../schema/generated/graphql.js";
import {ApiErrorCode, ApiErrorMessage} from "../model/model_enum_values.js";
diff --git a/src/execution/template_deleter.ts b/src/execution/template_deleter.ts
index 2eac02e..2d35112 100644
--- a/src/execution/template_deleter.ts
+++ b/src/execution/template_deleter.ts
@@ -1,4 +1,3 @@
-
import {DeleteResponse} from "../schema/generated/graphql.js";
import {
ZabbixDeleteTemplateGroupsRequest,
diff --git a/src/execution/template_importer.ts b/src/execution/template_importer.ts
index 5910ac1..4600f8d 100644
--- a/src/execution/template_importer.ts
+++ b/src/execution/template_importer.ts
@@ -1,4 +1,3 @@
-
import {
CreateTemplate,
CreateTemplateGroup,
@@ -11,7 +10,6 @@ import {
ZabbixCreateItemRequest,
ZabbixCreateTemplateGroupRequest,
ZabbixCreateTemplateRequest,
- ZabbixQueryItemRequest,
ZabbixQueryTemplateGroupRequest,
ZabbixQueryTemplatesRequest
} from "../datasources/zabbix-templates.js";
diff --git a/src/schema/generated/graphql.ts b/src/schema/generated/graphql.ts
index 4c48b89..f198540 100644
--- a/src/schema/generated/graphql.ts
+++ b/src/schema/generated/graphql.ts
@@ -1,8 +1,6 @@
-import { DeviceCommunicationType } from '../../model/model_enum_values.js';
-import { StorageItemType } from '../../model/model_enum_values.js';
-import { DeviceStatus } from '../../model/model_enum_values.js';
-import { Permission } from '../../model/model_enum_values.js';
-import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql';
+import {DeviceCommunicationType, DeviceStatus, Permission, StorageItemType} from '../../model/model_enum_values.js';
+import {GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig} from 'graphql';
+
export type Maybe = T | null;
export type InputMaybe = Maybe;
export type Exact = { [K in keyof T]: T[K] };
diff --git a/src/test/host_importer.test.ts b/src/test/host_importer.test.ts
index c221090..b31bba0 100644
--- a/src/test/host_importer.test.ts
+++ b/src/test/host_importer.test.ts
@@ -1,7 +1,5 @@
-
import {HostImporter} from "../execution/host_importer.js";
-import {zabbixAPI, ZABBIX_EDGE_DEVICE_BASE_GROUP} from "../datasources/zabbix-api.js";
-import {ZabbixRequestWithPermissions} from "../datasources/zabbix-permissions.js";
+import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI} from "../datasources/zabbix-api.js";
// Mocking ZabbixAPI
jest.mock("../datasources/zabbix-api.js", () => ({
diff --git a/src/test/host_integration.test.ts b/src/test/host_integration.test.ts
index 17ffcd5..963df37 100644
--- a/src/test/host_integration.test.ts
+++ b/src/test/host_integration.test.ts
@@ -1,8 +1,8 @@
-import { ApolloServer } from '@apollo/server';
-import { schema_loader } from '../api/schema.js';
-import { readFileSync } from 'fs';
-import { join } from 'path';
-import { zabbixAPI, ZABBIX_EDGE_DEVICE_BASE_GROUP } from '../datasources/zabbix-api.js';
+import {ApolloServer} from '@apollo/server';
+import {schema_loader} from '../api/schema.js';
+import {readFileSync} from 'fs';
+import {join} from 'path';
+import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI} from '../datasources/zabbix-api.js';
// Mocking ZabbixAPI.post
jest.mock("../datasources/zabbix-api.js", () => ({
diff --git a/src/test/host_query.test.ts b/src/test/host_query.test.ts
index 9b256d7..6fd9545 100644
--- a/src/test/host_query.test.ts
+++ b/src/test/host_query.test.ts
@@ -1,8 +1,6 @@
-
import {createResolvers} from "../api/resolvers.js";
-import {zabbixAPI, ZABBIX_EDGE_DEVICE_BASE_GROUP} from "../datasources/zabbix-api.js";
-import {QueryAllHostsArgs, QueryAllDevicesArgs, QueryAllHostGroupsArgs} from "../schema/generated/graphql.js";
-import {Config} from "../common_utils.js";
+import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI} from "../datasources/zabbix-api.js";
+import {QueryAllDevicesArgs, QueryAllHostGroupsArgs, QueryAllHostsArgs} from "../schema/generated/graphql.js";
// Mocking ZabbixAPI
jest.mock("../datasources/zabbix-api.js", () => ({
diff --git a/src/test/logger_config.test.ts b/src/test/logger_config.test.ts
new file mode 100644
index 0000000..e199105
--- /dev/null
+++ b/src/test/logger_config.test.ts
@@ -0,0 +1,18 @@
+// Import after mocking Config
+import {logger, Loglevel} from "../logging/logger.js";
+
+// Mocking Config
+jest.mock("../common_utils.js", () => ({
+ Config: {
+ LOG_LEVELS: "ERROR,INFO"
+ }
+}));
+
+describe("Logger Config Mocking", () => {
+ test("logger levels are initialized from Config", () => {
+ expect(logger.levels).toBeDefined();
+ expect(logger.levels?.has(Loglevel.ERROR)).toBe(true);
+ expect(logger.levels?.has(Loglevel.INFO)).toBe(true);
+ expect(logger.levels?.has(Loglevel.DEBUG)).toBe(false);
+ });
+});
diff --git a/src/test/misc_resolvers.test.ts b/src/test/misc_resolvers.test.ts
index 7879090..4c6f588 100644
--- a/src/test/misc_resolvers.test.ts
+++ b/src/test/misc_resolvers.test.ts
@@ -1,4 +1,3 @@
-
import {createResolvers} from "../api/resolvers.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
@@ -10,6 +9,13 @@ jest.mock("../datasources/zabbix-api.js", () => ({
}
}));
+// Mocking Config
+jest.mock("../common_utils.js", () => ({
+ Config: {
+ API_VERSION: "1.2.3"
+ }
+}));
+
describe("Miscellaneous Resolvers", () => {
let resolvers: any;
@@ -20,13 +26,7 @@ describe("Miscellaneous Resolvers", () => {
test("apiVersion query", async () => {
const result = await resolvers.Query.apiVersion();
- expect(typeof result).toBe("string");
- });
-
- test("zabbixVersion query", async () => {
- (zabbixAPI.post as jest.Mock).mockResolvedValueOnce({ result: "7.0.0" });
- const result = await resolvers.Query.zabbixVersion();
- expect(zabbixAPI.post).toHaveBeenCalledWith("apiinfo.version", expect.anything());
+ expect(result).toBe("1.2.3");
});
test("login query", async () => {
diff --git a/src/test/schema_config.test.ts b/src/test/schema_config.test.ts
new file mode 100644
index 0000000..0e4cf5f
--- /dev/null
+++ b/src/test/schema_config.test.ts
@@ -0,0 +1,41 @@
+import {schema_loader} from "../api/schema.js";
+import * as fs from "fs";
+import * as nodeFs from "node:fs";
+
+// Mocking Config
+jest.mock("../common_utils.js", () => ({
+ Config: {
+ SCHEMA_PATH: "./test_schema/",
+ ADDITIONAL_SCHEMAS: "./test_schema/extra.graphql",
+ ADDITIONAL_RESOLVERS: "ExtraDevice"
+ }
+}));
+
+// Mocking resolvers to avoid schema validation errors
+jest.mock("../api/resolvers.js", () => ({
+ createResolvers: jest.fn().mockReturnValue({
+ Query: {
+ test: () => "ok"
+ }
+ })
+}));
+
+// Mocking fs
+jest.mock("fs", () => ({
+ readFileSync: jest.fn().mockReturnValue("type Query { test: String } type Device { id: ID tags: [String] } type GenericDevice { id: ID tags: [String] } type DeviceConfig { id: ID } type ExtraDevice { id: ID tags: [String] }")
+}));
+
+jest.mock("node:fs", () => ({
+ readdirSync: jest.fn().mockReturnValue(["base.graphql"])
+}));
+
+describe("Schema Config Mocking", () => {
+ test("schema_loader uses Config variables", async () => {
+ const schema = await schema_loader();
+
+ expect(nodeFs.readdirSync).toHaveBeenCalledWith("./test_schema/");
+ expect(fs.readFileSync).toHaveBeenCalledWith("./test_schema/base.graphql", expect.anything());
+ expect(fs.readFileSync).toHaveBeenCalledWith("./test_schema/extra.graphql", expect.anything());
+ expect(schema).toBeDefined();
+ });
+});
diff --git a/src/test/template_deleter.test.ts b/src/test/template_deleter.test.ts
index 3e0f1c5..83f6548 100644
--- a/src/test/template_deleter.test.ts
+++ b/src/test/template_deleter.test.ts
@@ -1,4 +1,3 @@
-
import {TemplateDeleter} from "../execution/template_deleter.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
diff --git a/src/test/template_importer.test.ts b/src/test/template_importer.test.ts
index 9457bbd..8bfa18e 100644
--- a/src/test/template_importer.test.ts
+++ b/src/test/template_importer.test.ts
@@ -1,15 +1,5 @@
-
import {TemplateImporter} from "../execution/template_importer.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
-import {
- ZabbixCreateItemRequest,
- ZabbixCreateTemplateGroupRequest,
- ZabbixCreateTemplateRequest,
- ZabbixQueryItemRequest,
- ZabbixQueryTemplateGroupRequest,
- ZabbixQueryTemplatesRequest
-} from "../datasources/zabbix-templates.js";
-import {ZabbixErrorResult} from "../datasources/zabbix-request.js";
// Mocking ZabbixAPI.executeRequest
jest.mock("../datasources/zabbix-api.js", () => ({
diff --git a/src/test/template_integration.test.ts b/src/test/template_integration.test.ts
index f67b925..58b2571 100644
--- a/src/test/template_integration.test.ts
+++ b/src/test/template_integration.test.ts
@@ -1,8 +1,8 @@
-import { ApolloServer } from '@apollo/server';
-import { schema_loader } from '../api/schema.js';
-import { readFileSync } from 'fs';
-import { join } from 'path';
-import { zabbixAPI } from '../datasources/zabbix-api.js';
+import {ApolloServer} from '@apollo/server';
+import {schema_loader} from '../api/schema.js';
+import {readFileSync} from 'fs';
+import {join} from 'path';
+import {zabbixAPI} from '../datasources/zabbix-api.js';
// Mocking ZabbixAPI.post
jest.mock("../datasources/zabbix-api.js", () => ({
diff --git a/src/test/template_query.test.ts b/src/test/template_query.test.ts
index 028544a..f431766 100644
--- a/src/test/template_query.test.ts
+++ b/src/test/template_query.test.ts
@@ -1,4 +1,3 @@
-
import {createResolvers} from "../api/resolvers.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
import {QueryTemplatesArgs} from "../schema/generated/graphql.js";
diff --git a/src/test/user_rights.test.ts b/src/test/user_rights.test.ts
index 230749a..0ac3732 100644
--- a/src/test/user_rights.test.ts
+++ b/src/test/user_rights.test.ts
@@ -1,4 +1,3 @@
-
import {createResolvers} from "../api/resolvers.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
@@ -11,6 +10,13 @@ jest.mock("../datasources/zabbix-api.js", () => ({
}
}));
+// Mocking Config
+jest.mock("../common_utils.js", () => ({
+ Config: {
+ ZABBIX_PERMISSION_TEMPLATE_GROUP_NAME_PREFIX: "CustomPerms"
+ }
+}));
+
describe("User Rights and Permissions Resolvers", () => {
let resolvers: any;
@@ -53,7 +59,7 @@ describe("User Rights and Permissions Resolvers", () => {
}
]);
if (path === "templategroup.get.permissions") return Promise.resolve([
- { groupid: "1001", name: "Permissions/Hostgroup/1001" }
+ { groupid: "1001", name: "CustomPerms/Hostgroup/1001" }
]);
return Promise.resolve([]);
});
@@ -79,7 +85,7 @@ describe("User Rights and Permissions Resolvers", () => {
}
]);
if (path === "templategroup.get.permissions") return Promise.resolve([
- { groupid: "1002", name: "Permissions/Hostgroup/1002" }
+ { groupid: "1002", name: "CustomPerms/Hostgroup/1002" }
]);
return Promise.resolve([]);
});
diff --git a/src/test/user_rights_integration.test.ts b/src/test/user_rights_integration.test.ts
index 8568d47..afb9663 100644
--- a/src/test/user_rights_integration.test.ts
+++ b/src/test/user_rights_integration.test.ts
@@ -1,8 +1,8 @@
-import { ApolloServer } from '@apollo/server';
-import { schema_loader } from '../api/schema.js';
-import { readFileSync } from 'fs';
-import { join } from 'path';
-import { zabbixAPI } from '../datasources/zabbix-api.js';
+import {ApolloServer} from '@apollo/server';
+import {schema_loader} from '../api/schema.js';
+import {readFileSync} from 'fs';
+import {join} from 'path';
+import {zabbixAPI} from '../datasources/zabbix-api.js';
// Mocking ZabbixAPI.post
jest.mock("../datasources/zabbix-api.js", () => ({
diff --git a/src/test/zabbix_api_config.test.ts b/src/test/zabbix_api_config.test.ts
new file mode 100644
index 0000000..d0b564d
--- /dev/null
+++ b/src/test/zabbix_api_config.test.ts
@@ -0,0 +1,19 @@
+// Import after mocking Config
+import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI, zabbixSuperAuthToken} from "../datasources/zabbix-api.js";
+
+// Mocking Config
+jest.mock("../common_utils.js", () => ({
+ Config: {
+ ZABBIX_EDGE_DEVICE_BASE_GROUP: "CustomEdgeGroup",
+ ZABBIX_AUTH_TOKEN: "super-secret-token",
+ ZABBIX_BASE_URL: "http://custom-zabbix"
+ }
+}));
+
+describe("Zabbix API Config Mocking", () => {
+ test("constants are derived from Config", () => {
+ expect(ZABBIX_EDGE_DEVICE_BASE_GROUP).toBe("CustomEdgeGroup");
+ expect(zabbixSuperAuthToken).toBe("super-secret-token");
+ expect(zabbixAPI.baseURL).toBe("http://custom-zabbix");
+ });
+});