Adopt buildConfig in dashboardapi adapter

This commit is contained in:
Rene De Ren
2026-03-12 16:43:29 +01:00
parent 89d2260351
commit c5272fcc24
2 changed files with 225 additions and 72 deletions

153
test/nodeClass.test.js Normal file
View File

@@ -0,0 +1,153 @@
const NodeClass = require('../src/nodeClass');
jest.mock('../src/specificClass', () => {
return jest.fn().mockImplementation(() => ({
logger: {
warn: jest.fn(),
},
generateDashB: jest.fn().mockResolvedValue({ dashboard: { title: 'ok' } }),
}));
});
const SpecificClass = require('../src/specificClass');
function createNodeHarness(flowNode = null) {
const handlers = {};
const node = {
id: 'dashboard-node-id',
on: jest.fn((event, handler) => {
handlers[event] = handler;
}),
status: jest.fn(),
error: jest.fn(),
_flow: {
getNode: jest.fn(() => flowNode),
},
};
return { node, handlers };
}
describe('dashboardAPI nodeClass', () => {
beforeEach(() => {
jest.clearAllMocks();
delete process.env.GRAFANA_TOKEN;
});
it('uses RED.nodes.getNode when it returns a runtime child', async () => {
const childNode = {
source: {
config: {
general: { name: 'child' },
functionality: { softwareType: 'measurement' },
},
},
};
const { node, handlers } = createNodeHarness();
const RED = {
nodes: {
getNode: jest.fn(() => childNode),
},
};
new NodeClass({ name: 'E2E-DashboardAPI', host: 'grafana', port: 3000 }, RED, node, 'dashboardapi');
expect(SpecificClass).toHaveBeenCalledWith(
expect.objectContaining({
general: expect.objectContaining({
name: 'E2E-DashboardAPI',
id: 'dashboard-node-id',
}),
functionality: expect.objectContaining({
softwareType: 'dashboardapi',
role: 'auto ui generator',
}),
grafanaConnector: expect.objectContaining({
host: 'grafana',
port: 3000,
}),
}),
);
const send = jest.fn();
const done = jest.fn();
await handlers.input({ topic: 'registerChild', payload: 'measurement-e2e-node' }, send, done);
expect(RED.nodes.getNode).toHaveBeenCalledWith('measurement-e2e-node');
expect(send).toHaveBeenCalledWith(
expect.objectContaining({
topic: 'create',
payload: { dashboard: { title: 'ok' } },
}),
);
expect(done).toHaveBeenCalledWith();
});
it('falls back to the active flow when RED.nodes.getNode lacks source state', async () => {
const flowChildNode = {
source: {
config: {
general: { name: 'child' },
functionality: { softwareType: 'measurement' },
},
},
};
const { node, handlers } = createNodeHarness(flowChildNode);
const RED = {
nodes: {
getNode: jest.fn(() => ({ id: 'measurement-e2e-node' })),
},
};
new NodeClass({ name: 'E2E-DashboardAPI', host: 'grafana', port: 3000 }, RED, node, 'dashboardapi');
const send = jest.fn();
const done = jest.fn();
await handlers.input({ topic: 'registerChild', payload: 'measurement-e2e-node' }, send, done);
expect(node._flow.getNode).toHaveBeenCalledWith('measurement-e2e-node');
expect(send).toHaveBeenCalledWith(
expect.objectContaining({
topic: 'create',
payload: { dashboard: { title: 'ok' } },
}),
);
expect(done).toHaveBeenCalledWith();
});
it('accepts a child config payload directly', async () => {
const { node, handlers } = createNodeHarness();
const RED = {
nodes: {
getNode: jest.fn(),
},
};
new NodeClass({ name: 'E2E-DashboardAPI', host: 'grafana', port: 3000 }, RED, node, 'dashboardapi');
const send = jest.fn();
const done = jest.fn();
await handlers.input(
{
topic: 'registerChild',
payload: {
config: {
general: { name: 'E2E-Level-Sensor' },
functionality: { softwareType: 'measurement' },
},
},
},
send,
done,
);
expect(RED.nodes.getNode).not.toHaveBeenCalled();
expect(send).toHaveBeenCalledWith(
expect.objectContaining({
topic: 'create',
payload: { dashboard: { title: 'ok' } },
}),
);
expect(done).toHaveBeenCalledWith();
});
});