Commit Graph

3 Commits

Author SHA1 Message Date
Knacky
8b1de6e258 test(m4): cover the new security guards + pin e2e to exact MITRE v19 counts
- 5 new pytest covering paths the code-reviewer flagged as un-asserted:
    * `test_seed_refuses_file_url` — `file://` scheme rejected before I/O
      (was the SSRF-to-local-FS vector).
    * `test_seed_refuses_disallowed_https_host` — non-allowlisted HTTPS
      host rejected with `MitreSourceForbidden`.
    * `test_seed_refuses_custom_url_without_sha` — end-to-end guard that
      `seed_mitre(source=<custom URL>, expected_sha256=None,
      allow_unverified=False)` raises `MitreSeedError`.
    * `test_dotted_id_fallback_resolves_orphan_subtechnique` — STIX bundle
      without `relationship[subtechnique-of]` still attaches T1059.001 to
      T1059 via the dotted-id convention.
    * `test_seed_clears_version_when_source_is_not_default` — seed from a
      local path leaves `settings.mitre_version` NULL (no stale pin).
- Existing `test_checksum_mismatch_aborts` reworked to monkey-patch
  `_ensure_host_allowed` so `file://` can drive the test past the allowlist
  gate (was relying on file:// being accepted before CR1).
- Removed unused `uuid` import.
- e2e: assertions on `tactics_upserted`/`techniques_upserted`/
  `subtechniques_upserted` switched from `>= 14/180/400` thresholds to
  `=== 15/222/475` exact counts pinned to MITRE Enterprise v19.0 + 0
  orphans. Catches parser regressions that would silently include revoked
  rows. Bump alongside MITRE_VERSION when re-pinning.
- e2e: `Math.random()` → `crypto.randomUUID().slice(0, 8)` for unique
  test-run emails (collision-safe across parallel CI workers).

DoD: 58 pytest pass (was 53), 34 Playwright pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 19:19:34 +02:00
Knacky
7dbe2dbc28 refactor(m4): flatten the MITRE picker into the attack.mitre.org matrix
The hierarchical 3-column drill-down was hard to scan and forced a stateful
walk per tag. Replaced with a flat, columns-as-tactics matrix that mirrors
attack.mitre.org/# — every cell is a one-click select target, with inline
sub-technique expand via a `+N` chevron.

- New endpoint GET /api/v1/mitre/matrix returns the full grid (tactics →
  techniques → sub-techniques nested) in a single ~55 KB response, so the
  SPA renders the whole matrix without firing 15 parallel queries. Two
  pytest tests added (nested structure + auth required).
- MitreTagPicker.tsx rewritten as a horizontal-scrolling matrix:
  - Click a tactic header → select the tactic (cyan filled).
  - Click a technique cell → select the technique (orange filled).
  - Click the `+N` chevron → expand sub-techniques inline within the column.
  - Click a sub-technique → select (purple filled).
  - Single Filter field matches on external_id or name across all kinds.
  - Selection chips at the top, clickable to remove.
  - `aria-pressed` on every clickable cell for screen readers and Playwright.
- e2e test updated to walk the new flow (click cell → assert aria-pressed,
  expand chevron, click sub, verify chip + JSON preview, filter to T1078).
- Spec §F2 + §F12 + todo.md M4 entry updated to make the matrix layout the
  canonical UI for MITRE tagging (so future spec-reviewer passes accept it).
- testing-m4.md walkthrough rewritten for the flat picker.

DoD post-refactor: make test-api → 53 passed (was 51), make e2e → 34 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:32:20 +02:00
Knacky
90036437cc test(m4): pytest parser + endpoints + e2e tag picker
- backend/tests/test_mitre.py: 12 integration tests using a hand-crafted
  minimal STIX bundle (no network in tests). Covers parser
  (revoked/deprecated skip, sub-technique parent linkage), seed idempotence,
  persisted settings, checksum mismatch path, all four read endpoints, perm
  enforcement on /mitre/sync, ILIKE search.
- e2e/tests/m4-mitre.spec.ts: 6 Playwright tests against the live stack.
  beforeAll calls POST /mitre/sync once (real bundle, ~50 MB, ~1.1 s) then
  the suite validates tactics ≥14, T1003 has ≥5 sub-techniques, the picker
  walks tactic→technique→subtechnique with chip multi-select, and non-admin
  sees /mitre but no Sync card.
- tasks/testing-m4.md: manual + automated checklist, air-gapped operator
  notes, volume-permission caveat for pre-existing root-owned volumes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 13:54:26 +02:00