/**
 * Unit tests for check-audit.mjs filter logic.
 *
 * Tests the four behavioral cases without spawning pnpm:
 *  1. Unwaived High advisory → blocking (filter returns it)
 *  2. Waived High advisory (GHSA in allowlist) → not blocking
 *  3. Only moderate/low advisories → not blocking (advisory-only)
 *  4. No advisories → not blocking
 */

import assert from 'node:assert/strict';
import { test } from 'node:test';
import { selectBlocking, partitionAdvisories } from '../check-audit.mjs';

// Fixture: a High advisory not in the allowlist
const highUnwaived = {
  '1': {
    severity: 'high',
    github_advisory_id: 'GHSA-test-unwaived-high',
    module_name: 'some-package',
    title: 'Some high vulnerability',
  },
};

// Fixture: a High advisory that IS in the allowlist
const highWaived = {
  '2': {
    severity: 'high',
    github_advisory_id: 'GHSA-gv7w-rqvm-qjhr',
    module_name: 'esbuild',
    title: 'esbuild integrity-check advisory',
  },
};

// Fixture: only moderate/low advisories
const moderateLow = {
  '3': {
    severity: 'moderate',
    github_advisory_id: 'GHSA-mod-erate-test',
    module_name: 'another-package',
    title: 'Moderate vulnerability',
  },
  '4': {
    severity: 'low',
    github_advisory_id: 'GHSA-low-test-only',
    module_name: 'yet-another',
    title: 'Low vulnerability',
  },
};

// Fixture: allowlist with the esbuild waiver
const allowlist = {
  'GHSA-gv7w-rqvm-qjhr': {
    reason: 'esbuild dev transitive — not in production runtime',
    reviewer: 'luc',
    expires: '2026-09-01',
  },
};

const emptyAllowlist = {};

test('unwaived High advisory is blocking', () => {
  const blocking = selectBlocking(highUnwaived, emptyAllowlist);
  assert.equal(blocking.length, 1);
  assert.equal(blocking[0].github_advisory_id, 'GHSA-test-unwaived-high');
});

test('waived High advisory is NOT blocking', () => {
  const blocking = selectBlocking(highWaived, allowlist);
  assert.equal(blocking.length, 0);
});

test('only moderate/low advisories → not blocking', () => {
  const blocking = selectBlocking(moderateLow, emptyAllowlist);
  assert.equal(blocking.length, 0);
});

test('no advisories → not blocking', () => {
  const blocking = selectBlocking({}, emptyAllowlist);
  assert.equal(blocking.length, 0);
});

test('partitionAdvisories splits blocking and advisory correctly', () => {
  const mixed = { ...highUnwaived, ...moderateLow };
  const { blocking, advisory } = partitionAdvisories(mixed, emptyAllowlist);
  assert.equal(blocking.length, 1);
  assert.equal(advisory.length, 2);
});
