import './setup.mjs'; import test from 'node:test'; import assert from 'node:assert/strict'; import { load } from './setup.mjs'; const { computeDrift } = await load('../services/intuneDriftService.js'); const { canPublish, canApprove } = await load('../services/graphRbac.js'); // --- drift ---------------------------------------------------------------- test('computeDrift reports in-sync when plan matches tenant', () => { const app = { displayName: 'Edge', publisher: 'Microsoft', installCommandLine: 'a', uninstallCommandLine: 'b', applicableArchitectures: 'x64' }; const assignment = { intent: 'required', target: { '@odata.type': '#microsoft.graph.groupAssignmentTarget', groupId: 'g1' } }; const rel = { '@odata.type': '#microsoft.graph.mobileAppSupersedence', targetId: 'old' }; const drift = computeDrift({ expectedApp: app, liveApp: { ...app }, expectedAssignments: [assignment], liveAssignments: [assignment], expectedRelationships: [rel], liveRelationships: [rel] }); assert.equal(drift.inSync, true); }); test('computeDrift detects field, assignment, and relationship differences', () => { const drift = computeDrift({ expectedApp: { displayName: 'Edge', installCommandLine: 'new' }, liveApp: { displayName: 'Edge', installCommandLine: 'old' }, expectedAssignments: [{ intent: 'required', target: { '@odata.type': '#microsoft.graph.groupAssignmentTarget', groupId: 'g1' } }], liveAssignments: [{ intent: 'available', target: { '@odata.type': '#microsoft.graph.groupAssignmentTarget', groupId: 'g1' } }], expectedRelationships: [{ '@odata.type': '#microsoft.graph.mobileAppSupersedence', targetId: 'old' }], liveRelationships: [] }); assert.equal(drift.inSync, false); assert.ok(drift.appDrift.some((d) => d.field === 'installCommandLine')); assert.equal(drift.assignmentDrift.missing.length, 1); // required|...|g1 missing in tenant assert.equal(drift.assignmentDrift.extra.length, 1); // available|...|g1 extra in tenant assert.equal(drift.relationshipDrift.missing.length, 1); }); // --- per-connection RBAC -------------------------------------------------- const admin = { id: 'u-admin', role: 'admin' }; const alice = { id: 'u-alice', role: 'user' }; const bob = { id: 'u-bob', role: 'user' }; test('canPublish: admins always; empty list allows all; otherwise listed only', () => { assert.equal(canPublish({ publisherIds: [] }, admin), true); assert.equal(canPublish({ publisherIds: [] }, alice), true); assert.equal(canPublish({ publisherIds: ['u-alice'] }, alice), true); assert.equal(canPublish({ publisherIds: ['u-alice'] }, bob), false); }); test('canApprove: admins always; otherwise only named approvers (empty = none)', () => { assert.equal(canApprove({ approverIds: [] }, admin), true); assert.equal(canApprove({ approverIds: [] }, alice), false); assert.equal(canApprove({ approverIds: ['u-alice'] }, alice), true); assert.equal(canApprove({ approverIds: ['u-alice'] }, bob), false); }); test('RBAC helpers tolerate JSON-string list columns', () => { assert.equal(canPublish({ publisher_ids: '["u-alice"]' }, alice), true); assert.equal(canApprove({ approver_ids: '["u-bob"]' }, bob), true); });