'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const DashboardApi = require('../../src/specificClass.js'); const { registerChild } = require('../../src/commands/handlers.js'); function makeFetch(routes) { const calls = []; const fetchImpl = async (url, opts = {}) => { const method = opts.method || 'GET'; const { pathname } = new URL(url); calls.push({ method, pathname, body: opts.body }); const r = routes[`${method} ${pathname}`]; if (!r) return { ok: false, status: 404, json: async () => ({ message: 'not found' }) }; if (typeof r === 'function') return r(); return { ok: r.ok ?? true, status: r.status ?? 200, json: async () => r.body }; }; fetchImpl.calls = calls; return fetchImpl; } function api(grafanaConnector = {}) { return new DashboardApi({ grafanaConnector }); } test('resolveDatasourceUid returns the first influxdb datasource uid', async () => { const a = api(); const fetchImpl = makeFetch({ 'GET /api/datasources': { body: [ { type: 'prometheus', uid: 'p1' }, { type: 'influxdb', uid: 'dfmpjg9jjvym8b', name: 'influxdb' }, { type: 'influxdb', uid: 'second-one' }, ], }, }); const uid = await a.resolveDatasourceUid({ fetchImpl }); assert.equal(uid, 'dfmpjg9jjvym8b'); }); test('resolveDatasourceUid is cached → second call makes no further fetch', async () => { const a = api(); const fetchImpl = makeFetch({ 'GET /api/datasources': { body: [{ type: 'influxdb', uid: 'u1' }] }, }); await a.resolveDatasourceUid({ fetchImpl }); await a.resolveDatasourceUid({ fetchImpl }); assert.equal(fetchImpl.calls.length, 1); }); test('resolveDatasourceUid returns empty string when no influxdb datasource exists', async () => { const a = api(); const fetchImpl = makeFetch({ 'GET /api/datasources': { body: [{ type: 'prometheus', uid: 'p1' }] }, }); const uid = await a.resolveDatasourceUid({ fetchImpl }); assert.equal(uid, ''); }); test('resolveDatasourceUid: fetch throws → returns empty string (template uid preserved)', async () => { const a = api(); const fetchImpl = async () => { throw new Error('ECONNREFUSED'); }; const uid = await a.resolveDatasourceUid({ fetchImpl }); assert.equal(uid, ''); }); test('resolveDatasourceUid: no fetch available → returns empty string', async () => { const a = api(); const uid = await a.resolveDatasourceUid({ fetchImpl: null }); assert.equal(uid, ''); }); test('rewriteDatasourceUid: rewrites panel.datasource.uid for influxdb only', () => { const a = api(); const dashboard = { panels: [ { datasource: { type: 'influxdb', uid: 'OLD' } }, { datasource: { type: 'grafana', uid: '-- Grafana --' } }, ], }; a.rewriteDatasourceUid(dashboard, 'NEW'); assert.equal(dashboard.panels[0].datasource.uid, 'NEW'); assert.equal(dashboard.panels[1].datasource.uid, '-- Grafana --'); }); test('rewriteDatasourceUid: rewrites panel.targets[].datasource.uid', () => { const a = api(); const dashboard = { panels: [ { datasource: { type: 'influxdb', uid: 'OLD' }, targets: [ { datasource: { type: 'influxdb', uid: 'OLD' }, query: 'a' }, { datasource: { type: 'influxdb', uid: 'OLD' }, query: 'b' }, ], }, ], }; a.rewriteDatasourceUid(dashboard, 'NEW'); for (const t of dashboard.panels[0].targets) assert.equal(t.datasource.uid, 'NEW'); }); test('rewriteDatasourceUid: descends into nested row panels', () => { const a = api(); const dashboard = { panels: [ { type: 'row', panels: [ { datasource: { type: 'influxdb', uid: 'OLD' } }, ], }, ], }; a.rewriteDatasourceUid(dashboard, 'NEW'); assert.equal(dashboard.panels[0].panels[0].datasource.uid, 'NEW'); }); test('rewriteDatasourceUid: rewrites templating.list[] influxdb variables', () => { const a = api(); const dashboard = { panels: [], templating: { list: [ { type: 'query', datasource: { type: 'influxdb', uid: 'OLD' } }, { type: 'constant', datasource: { type: 'prometheus', uid: 'OLD' } }, ], }, }; a.rewriteDatasourceUid(dashboard, 'NEW'); assert.equal(dashboard.templating.list[0].datasource.uid, 'NEW'); assert.equal(dashboard.templating.list[1].datasource.uid, 'OLD'); }); test('rewriteDatasourceUid: leaves template-variable references alone (${datasource})', () => { const a = api(); const dashboard = { panels: [{ datasource: { type: 'influxdb', uid: '${datasource}' } }], }; a.rewriteDatasourceUid(dashboard, 'NEW'); assert.equal(dashboard.panels[0].datasource.uid, '${datasource}'); }); test('rewriteDatasourceUid: no-op when uid is falsy (preserves template)', () => { const a = api(); const dashboard = { panels: [{ datasource: { type: 'influxdb', uid: 'KEEP' } }] }; a.rewriteDatasourceUid(dashboard, ''); assert.equal(dashboard.panels[0].datasource.uid, 'KEEP'); }); test('emit path rewrites every upsert dashboard with the resolved datasource uid', async () => { const a = api({ folderTitle: 'EVOLV' }); a.resolveFolderUid = async () => 'fld'; a.resolveDatasourceUid = async () => 'resolved-ds-uid'; const childSource = { config: { general: { id: 'm1', name: 'Level' }, functionality: { softwareType: 'measurement' } }, }; const sent = []; const ctx = { node: { id: 'dapi' }, send: (m) => sent.push(m) }; await registerChild(a, { payload: childSource }, ctx); assert.ok(sent.length >= 1); for (const m of sent) { const panels = m.payload?.dashboard?.panels || []; for (const p of panels) { if (p?.datasource?.type === 'influxdb') { assert.equal(p.datasource.uid, 'resolved-ds-uid'); } } } });