feat: add comprehensive tests and samples for host and user rights endpoints

- Added GraphQL sample queries and mutations for host and user rights endpoints in the 'docs' directory.

- Implemented unit tests for all remaining GraphQL endpoints, including hosts, devices, host groups, locations, and user permissions.

- Created dedicated integration tests for host and user rights workflows, utilizing the new sample files.

- Fixed a bug in 'HostImporter.getHostGroupHierarchyNames' to correctly process and sort nested host group hierarchies.

- Refined Zabbix API mocking in tests to improve reliability and support path-based routing.

- Verified all 38 tests across 11 suites pass successfully.
This commit is contained in:
Andreas Hilbig 2026-01-26 16:55:23 +01:00
parent a3ed4886a3
commit fdfd5f1e0e
14 changed files with 729 additions and 6 deletions

View file

@ -0,0 +1,21 @@
### Query
Use this query to list all devices (hosts with device type and state).
```graphql
query AllDevices($name_pattern: String, $with_items: Boolean) {
allDevices(name_pattern: $name_pattern, with_items: $with_items) {
hostid
host
name
deviceType
}
}
```
### Variables
```json
{
"name_pattern": "%",
"with_items": true
}
```

View file

@ -0,0 +1,18 @@
### Query
# Use this query to list all host groups.
```graphql
query AllHostGroups($search_name: String) {
allHostGroups(search_name: $search_name) {
groupid
name
}
}
```
### Variables
```json
{
"search_name": "Baustellen-Devices/*"
}
```

View file

@ -0,0 +1,25 @@
### Query
Use this query to list all hosts, filtered by name pattern and/or device type.
```graphql
query AllHosts($name_pattern: String, $tag_deviceType: [String]) {
allHosts(name_pattern: $name_pattern, tag_deviceType: $tag_deviceType) {
hostid
host
name
deviceType
hostgroups {
groupid
name
}
}
}
```
### Variables
```json
{
"name_pattern": "BT_%",
"tag_deviceType": ["bt_device_tracker_generic"]
}
```

View file

@ -0,0 +1,28 @@
### Query
Use this query to export all user rights (roles and groups).
```graphql
query ExportUserRights($name_pattern: String) {
exportUserRights(name_pattern: $name_pattern) {
userGroups {
usrgrpid
name
hostgroup_rights {
name
permission
}
}
userRoles {
roleid
name
}
}
}
```
### Variables
```json
{
"name_pattern": "Admin%"
}
```

View file

@ -0,0 +1,28 @@
### Mutation
Use this mutation to import host groups.
```graphql
mutation ImportHostGroups($hostGroups: [CreateHostGroup!]!) {
importHostGroups(hostGroups: $hostGroups) {
groupName
groupid
message
error {
message
code
data
}
}
}
```
### Variables
```json
{
"hostGroups": [
{
"groupName": "ConstructionSite/Test"
}
]
}
```

View file

@ -0,0 +1,36 @@
### Mutation
Use this mutation to import hosts and assign them to host groups.
```graphql
mutation ImportHosts($hosts: [CreateHost!]!) {
importHosts(hosts: $hosts) {
deviceKey
hostid
message
error {
message
code
data
}
}
}
```
### Variables
```json
{
"hosts": [
{
"deviceKey": "TEST_DEVICE_001",
"name": "Test Device 001",
"deviceType": "bt_device_tracker_generic",
"groupNames": ["ConstructionSite/Test"],
"location": {
"name": "Test Location",
"location_lat": "52.5200",
"location_lon": "13.4050"
}
}
]
}
```

View file

@ -0,0 +1,50 @@
### Mutation
Use this mutation to import user rights (roles and groups).
```graphql
mutation ImportUserRights($input: UserRightsInput!, $dryRun: Boolean) {
importUserRights(input: $input, dryRun: $dryRun) {
userRoles {
id
name
message
}
userGroups {
id
name
message
}
}
}
```
### Variables
```json
{
"input": {
"userRoles": [
{
"name": "Test Role",
"type": 1,
"rules": {
"api_access": 1,
"api": ["host.get", "item.get"]
}
}
],
"userGroups": [
{
"name": "Test Group",
"gui_access": 0,
"hostgroup_rights": [
{
"name": "ConstructionSite/Test",
"permission": "READ_WRITE"
}
]
}
]
},
"dryRun": false
}
```

View file

@ -13,16 +13,21 @@ import {ZABBIX_EDGE_DEVICE_BASE_GROUP, zabbixAPI} from "../datasources/zabbix-ap
export class HostImporter {
public static getHostGroupHierarchyNames(hostGroups: Array<CreateHostGroup>) {
let resultSet: Set<CreateHostGroup> = new Set<CreateHostGroup>(hostGroups)
let nameToGroup = new Map<string, CreateHostGroup>()
for (let group of hostGroups || []) {
let levelNames = group.groupName.split("/", hostGroups?.length - 1)
let levelNames = group.groupName.split("/")
let leafName = ""
for (let level of levelNames) {
leafName += (leafName ? "/" + level : level)
resultSet.add({groupName: leafName})
for (let i = 0; i < levelNames.length; i++) {
leafName += (leafName ? "/" + levelNames[i] : levelNames[i])
if (!nameToGroup.has(leafName)) {
// Use original group object if it matches the name (to keep UUID), else create new
let original = hostGroups.find(g => g.groupName === leafName)
nameToGroup.set(leafName, original ? original : {groupName: leafName})
}
}
return resultSet
}
// Sort alphabetically to process parents before children
return Array.from(nameToGroup.values()).sort((a, b) => a.groupName.localeCompare(b.groupName))
}
public static async importHostGroups(hostGroups: InputMaybe<Array<CreateHostGroup>> | undefined, zabbixAuthToken?: string, cookie?: string) {

View file

@ -0,0 +1,84 @@
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";
// Mocking ZabbixAPI
jest.mock("../datasources/zabbix-api.js", () => ({
zabbixAPI: {
executeRequest: jest.fn(),
post: jest.fn(),
requestByPath: jest.fn()
},
ZABBIX_EDGE_DEVICE_BASE_GROUP: "Baustellen-Devices"
}));
// Mock ZabbixRequestWithPermissions to skip permission checks
jest.mock("../datasources/zabbix-permissions.js", () => ({
ZabbixRequestWithPermissions: class {
constructor(public path: string) {}
async prepare() {
return undefined;
}
async executeRequestReturnError(api: any, args: any) {
// @ts-ignore
return api.post(this.path, { body: { method: this.path, params: args?.zabbix_params } });
}
async executeRequestThrowError(api: any, args: any) {
return this.executeRequestReturnError(api, args);
}
},
ZabbixPermissionsHelper: {
hasUserPermissions: jest.fn().mockResolvedValue(true)
}
}));
describe("HostImporter", () => {
beforeEach(() => {
jest.clearAllMocks();
});
test("importHostGroups - create new hierarchy", async () => {
const hostGroups = [{ groupName: "Parent/Child" }];
// Parent lookup (from importHostGroups loop)
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce([]); // findHostGroupIdsByName (Parent)
// Parent creation
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce({ groupids: ["101"] }); // hostgroup.create (Parent)
// Parent/Child lookup
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce([]); // findHostGroupIdsByName (Parent/Child)
// Parent/Child creation
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce({ groupids: ["102"] }); // hostgroup.create (Parent/Child)
const result = await HostImporter.importHostGroups(hostGroups, "token");
expect(result).toHaveLength(2);
expect(result!.find(r => r.groupName === "Parent")?.groupid).toBe(101);
expect(result!.find(r => r.groupName === "Parent/Child")?.groupid).toBe(102);
});
test("importHosts - basic host", async () => {
const hosts = [{
deviceKey: "Device1",
deviceType: "Type1",
groupNames: ["Group1"]
}];
// Mocking group lookup for Base group and Group1
// findHostGroupIdsByName for [Base, Group1]
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce([{ groupid: "201", name: ZABBIX_EDGE_DEVICE_BASE_GROUP }]); // Base
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce([{ groupid: "202", name: ZABBIX_EDGE_DEVICE_BASE_GROUP + "/Group1" }]); // Group1
// Mocking template lookup for deviceType
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce([{ templateid: "301" }]);
// Mocking host.create via requestByPath
(zabbixAPI.requestByPath as jest.Mock).mockResolvedValueOnce({ hostids: ["401"] });
const result = await HostImporter.importHosts(hosts, "token");
expect(result).toHaveLength(1);
expect(result![0].hostid).toBe("401");
});
});

View file

@ -0,0 +1,83 @@
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';
// Mocking ZabbixAPI.post
jest.mock("../datasources/zabbix-api.js", () => ({
zabbixAPI: {
post: jest.fn(),
executeRequest: jest.fn(),
baseURL: 'http://localhost/zabbix',
getLocations: jest.fn(),
requestByPath: jest.fn()
},
ZABBIX_EDGE_DEVICE_BASE_GROUP: "Baustellen-Devices"
}));
describe("Host Integration Tests", () => {
let server: ApolloServer;
beforeAll(async () => {
const schema = await schema_loader();
server = new ApolloServer({
schema,
});
});
test("Query allHosts using sample", async () => {
const sampleFile = readFileSync(join(process.cwd(), 'docs', 'sample_all_hosts_query.graphql'), 'utf-8').replace(/\r\n/g, '\n');
const mutationMatch = sampleFile.match(/```graphql\n([\s\S]*?)\n```/);
const variablesMatch = sampleFile.match(/```json\n([\s\S]*?)\n```/);
const query = mutationMatch![1];
const variables = JSON.parse(variablesMatch![1]);
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce([{ hostid: "1", host: "BT_DEVICE_1", name: "BT_DEVICE_1" }]);
const response = await server.executeOperation({
query: query,
variables: variables,
}, {
contextValue: { zabbixAuthToken: 'test-token', dataSources: { zabbixAPI: zabbixAPI } }
});
expect(response.body.kind).toBe('single');
// @ts-ignore
const result = response.body.singleResult;
expect(result.errors).toBeUndefined();
expect(result.data.allHosts).toHaveLength(1);
});
test("Import hosts using sample", async () => {
const sampleFile = readFileSync(join(process.cwd(), 'docs', 'sample_import_hosts_mutation.graphql'), 'utf-8').replace(/\r\n/g, '\n');
const mutationMatch = sampleFile.match(/```graphql\n([\s\S]*?)\n```/);
const variablesMatch = sampleFile.match(/```json\n([\s\S]*?)\n```/);
const mutation = mutationMatch![1];
const variables = JSON.parse(variablesMatch![1]);
// Mocking for importHosts
(zabbixAPI.post as jest.Mock)
.mockResolvedValueOnce([{ groupid: "201", name: ZABBIX_EDGE_DEVICE_BASE_GROUP }]) // Base group
.mockResolvedValueOnce([{ groupid: "202", name: ZABBIX_EDGE_DEVICE_BASE_GROUP + "/ConstructionSite/Test" }]) // Specific group
.mockResolvedValueOnce([{ templateid: "301" }]); // Template lookup
(zabbixAPI.requestByPath as jest.Mock).mockResolvedValueOnce({ hostids: ["401"] });
const response = await server.executeOperation({
query: mutation,
variables: variables,
}, {
contextValue: { zabbixAuthToken: 'test-token', dataSources: { zabbixAPI: zabbixAPI } }
});
expect(response.body.kind).toBe('single');
// @ts-ignore
const result = response.body.singleResult;
expect(result.errors).toBeUndefined();
expect(result.data.importHosts).toHaveLength(1);
expect(result.data.importHosts[0].hostid).toBe("401");
});
});

112
src/test/host_query.test.ts Normal file
View file

@ -0,0 +1,112 @@
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";
// Mocking ZabbixAPI
jest.mock("../datasources/zabbix-api.js", () => ({
zabbixAPI: {
executeRequest: jest.fn(),
post: jest.fn(),
baseURL: "http://mock-zabbix",
getLocations: jest.fn()
},
ZABBIX_EDGE_DEVICE_BASE_GROUP: "Baustellen-Devices"
}));
describe("Host and HostGroup Resolvers", () => {
let resolvers: any;
beforeEach(() => {
jest.clearAllMocks();
resolvers = createResolvers();
});
test("allHosts query", async () => {
const mockHosts = [{ hostid: "1", host: "Host 1" }];
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce(mockHosts);
const args: QueryAllHostsArgs = { name_pattern: "Test" };
const context = {
zabbixAuthToken: "test-token",
dataSources: { zabbixAPI: zabbixAPI }
};
const result = await resolvers.Query.allHosts(null, args, context);
expect(result).toEqual(mockHosts);
expect(zabbixAPI.post).toHaveBeenCalledWith("host.get.with_items", expect.objectContaining({
body: expect.objectContaining({
method: "host.get",
params: expect.objectContaining({
search: { name: "Test" },
tags: expect.arrayContaining([{
tag: "hostType",
operator: 1,
value: ZABBIX_EDGE_DEVICE_BASE_GROUP
}])
})
})
}));
});
test("allDevices query", async () => {
const mockDevices = [{ hostid: "2", host: "Device 1" }];
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce(mockDevices);
const args: QueryAllDevicesArgs = { hostids: 2 };
const context = {
zabbixAuthToken: "test-token",
dataSources: { zabbixAPI: zabbixAPI }
};
const result = await resolvers.Query.allDevices(null, args, context);
expect(result).toEqual(mockDevices);
expect(zabbixAPI.post).toHaveBeenCalledWith("host.get.with_items", expect.objectContaining({
body: expect.objectContaining({
method: "host.get",
params: expect.objectContaining({
hostids: 2
})
})
}));
});
test("allHostGroups query", async () => {
const mockGroups = [{ groupid: "10", name: ZABBIX_EDGE_DEVICE_BASE_GROUP + "/Group 1" }];
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce(mockGroups);
const args: QueryAllHostGroupsArgs = { search_name: "Group 1" };
const context = {
zabbixAuthToken: "test-token"
};
const result = await resolvers.Query.allHostGroups(null, args, context);
expect(result).toEqual(mockGroups);
expect(zabbixAPI.post).toHaveBeenCalledWith("hostgroup.get", expect.objectContaining({
body: expect.objectContaining({
params: expect.objectContaining({
search: { name: ["Group 1"] }
})
})
}));
});
test("locations query", async () => {
const mockLocations = [{ name: "Loc 1", latitude: 1.0, longitude: 2.0 }];
(zabbixAPI.getLocations as jest.Mock).mockResolvedValueOnce(mockLocations);
const args = { name_pattern: "Loc" };
const context = {
zabbixAuthToken: "test-token",
dataSources: { zabbixAPI: zabbixAPI }
};
const result = await resolvers.Query.locations(null, args, context);
expect(result).toEqual(mockLocations);
expect(zabbixAPI.getLocations).toHaveBeenCalled();
});
});

View file

@ -0,0 +1,49 @@
import {createResolvers} from "../api/resolvers.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
// Mocking ZabbixAPI
jest.mock("../datasources/zabbix-api.js", () => ({
zabbixAPI: {
executeRequest: jest.fn(),
post: jest.fn()
}
}));
describe("Miscellaneous Resolvers", () => {
let resolvers: any;
beforeEach(() => {
jest.clearAllMocks();
resolvers = createResolvers();
});
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());
});
test("login query", async () => {
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce("mock-token");
const result = await resolvers.Query.login(null, { username: "admin", password: "password" });
expect(result).toBe("mock-token");
expect(zabbixAPI.post).toHaveBeenCalledWith("user.login", expect.objectContaining({
body: expect.objectContaining({
params: { username: "admin", password: "password" }
})
}));
});
test("logout query", async () => {
(zabbixAPI.post as jest.Mock).mockResolvedValueOnce(true);
const result = await resolvers.Query.logout(null, null, { zabbixAuthToken: "token" });
expect(result).toBe(true);
expect(zabbixAPI.post).toHaveBeenCalledWith("user.logout", expect.anything());
});
});

View file

@ -0,0 +1,123 @@
import {createResolvers} from "../api/resolvers.js";
import {zabbixAPI} from "../datasources/zabbix-api.js";
// Mocking ZabbixAPI
jest.mock("../datasources/zabbix-api.js", () => ({
zabbixAPI: {
executeRequest: jest.fn(),
post: jest.fn(),
baseURL: "http://mock-zabbix"
}
}));
describe("User Rights and Permissions Resolvers", () => {
let resolvers: any;
beforeEach(() => {
jest.clearAllMocks();
resolvers = createResolvers();
});
test("exportUserRights query", async () => {
// Mocks for exportUserRights
(zabbixAPI.post as jest.Mock).mockImplementation((path: string) => {
if (path === "templategroup.get") return Promise.resolve([]);
if (path === "hostgroup.get") return Promise.resolve([]);
if (path === "usergroup.get.withuuids") return Promise.resolve([{ usrgrpid: "1", name: "UserGroup1", hostgroup_rights: [], templategroup_rights: [] }]);
if (path === "module.get") return Promise.resolve([{ moduleid: "10", id: "mod1" }]);
if (path === "role.get") return Promise.resolve([{ roleid: "2", name: "UserRole1" }]);
return Promise.resolve([]);
});
const args = { name_pattern: "User" };
const context = { zabbixAuthToken: "test-token" };
const result = await resolvers.Query.exportUserRights(null, args, context);
expect(result.userGroups).toBeDefined();
expect(result.userRoles).toBeDefined();
expect(zabbixAPI.post).toHaveBeenCalledWith("usergroup.get.withuuids", expect.anything());
expect(zabbixAPI.post).toHaveBeenCalledWith("module.get", expect.anything());
expect(zabbixAPI.post).toHaveBeenCalledWith("role.get", expect.anything());
});
test("userPermissions query", async () => {
// Mock for userPermissions
(zabbixAPI.post as jest.Mock).mockImplementation((path: string) => {
if (path === "usergroup.get.permissions") return Promise.resolve([
{
usrgrpid: "1",
name: "Group 1",
templategroup_rights: [{ id: "1001", permission: "3" }]
}
]);
if (path === "templategroup.get.permissions") return Promise.resolve([
{ groupid: "1001", name: "Permissions/Hostgroup/1001" }
]);
return Promise.resolve([]);
});
const args = { objectNames: ["Hostgroup/1001"] };
const context = { zabbixAuthToken: "test-token" };
const result = await resolvers.Query.userPermissions(null, args, context);
expect(result).toBeDefined();
expect(result).toHaveLength(1);
expect(result[0].objectName).toBe("Hostgroup/1001");
expect(result[0].permission).toBe("3"); // Zabbix value "3" (READ_WRITE)
});
test("hasPermissions query", async () => {
// Mock for hasPermissions
(zabbixAPI.post as jest.Mock).mockImplementation((path: string) => {
if (path === "usergroup.get.permissions") return Promise.resolve([
{
usrgrpid: "1",
templategroup_rights: [{ id: "1002", permission: "3" }]
}
]);
if (path === "templategroup.get.permissions") return Promise.resolve([
{ groupid: "1002", name: "Permissions/Hostgroup/1002" }
]);
return Promise.resolve([]);
});
const args = { permissions: [{ objectName: "Hostgroup/1002", permission: "READ" }] };
const context = { zabbixAuthToken: "test-token" };
const result = await resolvers.Query.hasPermissions(null, args, context);
expect(result).toBe(true);
});
test("importUserRights mutation", async () => {
// Mocks for importUserRights
(zabbixAPI.post as jest.Mock).mockImplementation((path: string) => {
if (path === "module.get") return Promise.resolve([{ moduleid: "10", id: "mod1" }]);
if (path === "role.get") return Promise.resolve([{ roleid: "2", name: "NewRole" }]);
if (path === "role.update") return Promise.resolve({ roleids: ["2"] });
if (path === "templategroup.get") return Promise.resolve([{ groupid: "101", name: "Group1", uuid: "uuid1" }]);
if (path === "hostgroup.get") return Promise.resolve([{ groupid: "201", name: "HostGroup1", uuid: "uuid2" }]);
if (path === "usergroup.get") return Promise.resolve([{ usrgrpid: "1", name: "NewGroup" }]);
if (path === "usergroup.update") return Promise.resolve({ usrgrpids: ["1"] });
if (path === "hostgroup.propagate") return Promise.resolve(true);
return Promise.resolve([]);
});
const args = {
input: {
userRoles: [{ name: "NewRole", type: 1 }],
userGroups: [{ name: "NewGroup" }]
},
dryRun: false
};
const context = { zabbixAuthToken: "test-token" };
const result = await resolvers.Mutation.importUserRights(null, args, context);
expect(result.userRoles).toHaveLength(1);
expect(result.userGroups).toHaveLength(1);
});
});

View file

@ -0,0 +1,61 @@
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", () => ({
zabbixAPI: {
post: jest.fn(),
executeRequest: jest.fn(),
baseURL: 'http://localhost/zabbix',
getLocations: jest.fn(),
requestByPath: jest.fn()
}
}));
describe("User Rights Integration Tests", () => {
let server: ApolloServer;
beforeAll(async () => {
const schema = await schema_loader();
server = new ApolloServer({
schema,
});
});
test("Import user rights using sample", async () => {
const sampleFile = readFileSync(join(process.cwd(), 'docs', 'sample_import_user_rights_mutation.graphql'), 'utf-8').replace(/\r\n/g, '\n');
const mutationMatch = sampleFile.match(/```graphql\n([\s\S]*?)\n```/);
const variablesMatch = sampleFile.match(/```json\n([\s\S]*?)\n```/);
const mutation = mutationMatch![1];
const variables = JSON.parse(variablesMatch![1]);
// Mocks for importUserRights
(zabbixAPI.post as jest.Mock)
.mockResolvedValueOnce([{ groupid: "101", name: "Group1", uuid: "uuid1" }]) // templategroup.get for roles (in prepare)
.mockResolvedValueOnce([{ groupid: "201", name: "ConstructionSite/Test", uuid: "uuid2" }]) // hostgroup.get for roles (in prepare)
.mockResolvedValueOnce([{ moduleid: "10", id: "mod1" }]) // module.get for roles
.mockResolvedValueOnce([{ roleid: "2", name: "Test Role" }]) // role.get
.mockResolvedValueOnce({ roleids: ["2"] }) // role.update
.mockResolvedValueOnce([{ groupid: "101", name: "Group1", uuid: "uuid1" }]) // templategroup.get for groups (in prepare)
.mockResolvedValueOnce([{ groupid: "201", name: "ConstructionSite/Test", uuid: "uuid2" }]) // hostgroup.get for groups (in prepare)
.mockResolvedValueOnce([{ usrgrpid: "1", name: "Test Group" }]) // usergroup.get
.mockResolvedValueOnce({ usrgrpids: ["1"] }); // usergroup.update
const response = await server.executeOperation({
query: mutation,
variables: variables,
}, {
contextValue: { zabbixAuthToken: 'test-token', dataSources: { zabbixAPI: zabbixAPI } }
});
expect(response.body.kind).toBe('single');
// @ts-ignore
const result = response.body.singleResult;
expect(result.errors).toBeUndefined();
expect(result.data.importUserRights.userRoles).toHaveLength(1);
});
});