Files
OmniRoute/tests/unit/quota-edit-opens-wizard.test.ts
Diego Rodrigues de Sa e Souza b7a0c54139 chore(lint): batch 5 of #12146 — combos, endpoint, provider-stats, api-manager and costs react-hooks violations resolved (#12174)
* chore(lint): batch 5 of #12146 — resolve the react-hooks compiler violations in combos, endpoint, provider-stats, api-manager and costs

40 violations across 14 files, all real refactors (no eslint-disable, no new
suppressions; the areas' react-hooks entries are deleted from the freeze):

- set-state-in-effect (30): fetch-on-mount effects moved behind an async
  continuation (usePools, usePoolUsage, useApiKeyUsageLimits, Notion/Obsidian
  source cards, A2A/MCP dashboards, ComboControlCenterClient, provider-stats,
  combos modal loaders, ApiManager initial load); prop/state sync converted to
  state adjustment during render with prev tracking (ApiKeyUsageLimitCard,
  PoolWizard dimensions/reset/group snap, combos sortMethod, builder reset,
  builder stage guard, single-provider default, stale intelligent selection);
  localStorage reads became lazy useState initializers (combos usage guide).
- immutability / TDZ (8): effects that scheduled fetchers declared below them
  moved after the declarations (EndpointPageClient, ApiManagerPageClient,
  combos mount load); fetchData relocated below the per-key fetchers it calls.
- static-components (7): provider-stats SortIcon hoisted to module level.
- preserve-manual-memoization (2): ApiManager blockedModels dep destructured to
  a local; provider-scope derivation memoized so downstream memos see a stable
  dependency.

Validation: eslint (CI command with suppressions, --max-warnings 0) clean on the
14 files; dashboard typecheck within baseline; mutation gate no drift; area
tests 208/208 (node) + 29/29 (vitest).

Refs #12146

* chore(lint): batch 5 follow-up — hoist the render-adjustment predicates so the new-code complexity gates stay flat

The render adjustments added one cyclomatic branch to combos/page.tsx and one
cognitive point to PoolWizard (caught by the new-code gate on the committed
work); the compound conditions now live in pure module-level predicates.

* chore(lint): batch 5 follow-up 2 — PoolWizard render adjustments live in two small hooks

One consolidated hook tripped max-lines-per-function (>80) and the cognitive
budget; the dimensions and open/close adjustments now live in two focused hooks
with a shared WizardSetters type, and the group snap stays inline (one branch).
complexityNewCode=0, cognitiveComplexityNewCode=0.

* test(quota): repoint the two PoolWizard structural pins at the render-adjustment hook

quota-edit-opens-wizard anchored the pre-fill block on the old '} else if (editPool)'
effect literal and quota-pool-wizard-edit expected a bare 'if (editPool)' that only
existed there; both now anchor on the batch-5 structure (submit still branches via
if (!editPool)).
2026-08-31 03:10:49 -03:00

138 lines
4.7 KiB
TypeScript

/**
* tests/unit/quota-edit-opens-wizard.test.ts
*
* Task 6 — source-scan assertions for:
* 1. QuotaSharePageClient no longer imports or renders EditAllocationsModal.
* 2. The `editing` pool is wired to a <PoolWizard via editPool prop.
* 3. editPoolExclusive is computed from apiKeys.allowedQuotas and passed through.
* 4. PoolWizard pre-fill uses editPoolExclusive (not a hard-coded false).
*
* Node native test runner — pure source analysis, no DOM needed.
*/
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
const PAGE_CLIENT_PATH = path.join(
ROOT,
"src",
"app",
"(dashboard)",
"dashboard",
"costs",
"quota-share",
"QuotaSharePageClient.tsx"
);
const WIZARD_PATH = path.join(
ROOT,
"src",
"app",
"(dashboard)",
"dashboard",
"costs",
"quota-share",
"components",
"PoolWizard.tsx"
);
const pageSrc = fs.readFileSync(PAGE_CLIENT_PATH, "utf-8");
const wizardSrc = fs.readFileSync(WIZARD_PATH, "utf-8");
// ── QuotaSharePageClient: EditAllocationsModal must be gone ───────────────────
test("QuotaSharePageClient: does NOT import EditAllocationsModal", () => {
assert.ok(
!pageSrc.includes("EditAllocationsModal"),
"EditAllocationsModal must not appear in QuotaSharePageClient (retired Task 6)"
);
});
// ── QuotaSharePageClient: editing pool wired to PoolWizard ────────────────────
test("QuotaSharePageClient: passes editing pool as editPool= to PoolWizard", () => {
assert.ok(
pageSrc.includes("editPool={editing"),
"Expected editPool={editing...} prop on the edit PoolWizard instance"
);
});
test("QuotaSharePageClient: opens edit wizard when editing is set (open={!!editing})", () => {
assert.ok(
pageSrc.includes("open={!!editing}"),
"Expected open={!!editing} on the edit PoolWizard instance"
);
});
// ── QuotaSharePageClient: editingExclusive computed and passed ────────────────
test("QuotaSharePageClient: computes editingExclusive from allowedQuotas", () => {
assert.ok(
pageSrc.includes("editingExclusive"),
"Expected editingExclusive to be defined in QuotaSharePageClient"
);
assert.ok(
pageSrc.includes("allowedQuotas"),
"Expected allowedQuotas referenced in editingExclusive computation"
);
});
test("QuotaSharePageClient: passes editPoolExclusive={editingExclusive} to edit PoolWizard", () => {
assert.ok(
pageSrc.includes("editPoolExclusive={editingExclusive}"),
"Expected editPoolExclusive={editingExclusive} on the edit PoolWizard instance"
);
});
test("QuotaSharePageClient: editingExclusive requires >=1 allocation", () => {
// The guard `editing.allocations.length > 0` must be present
assert.ok(
pageSrc.includes("allocations.length > 0"),
"Expected allocations.length > 0 guard in editingExclusive"
);
});
test("QuotaSharePageClient: editingExclusive checks every allocated key has pool id in allowedQuotas", () => {
assert.ok(
pageSrc.includes("aq.includes(editing.id)"),
"Expected aq.includes(editing.id) check in editingExclusive"
);
});
// ── PoolWizard: editPoolExclusive prop declared and used ─────────────────────
test("PoolWizard.tsx: declares editPoolExclusive prop in PoolWizardProps", () => {
assert.ok(
wizardSrc.includes("editPoolExclusive?"),
"Expected editPoolExclusive? field in PoolWizardProps"
);
});
test("PoolWizard.tsx: pre-fill uses editPoolExclusive ?? false (not setExclusive(false))", () => {
// The old hard-coded false must be replaced by the prop
assert.ok(
wizardSrc.includes("editPoolExclusive ?? false"),
"Expected setExclusive(editPoolExclusive ?? false) in PoolWizard pre-fill"
);
// The literal `setExclusive(false)` must NOT appear in the edit-mode pre-fill block
// (it may still appear in the close-reset block, which is correct)
// #12146 batch 5: the pre-fill moved from the reset effect ("} else if (editPool)")
// into useWizardOpenCloseAdjustment's render adjustment.
const editFillIdx = wizardSrc.indexOf("if (changed && open && editPool)");
assert.ok(editFillIdx >= 0, "Expected the editPool pre-fill adjustment block in PoolWizard");
const closingBrace = wizardSrc.indexOf("\n }", editFillIdx);
const editFillBlock = wizardSrc.slice(
editFillIdx,
closingBrace > 0 ? closingBrace + 4 : editFillIdx + 1200
);
assert.ok(
!editFillBlock.includes("setExclusive(false)"),
"setExclusive(false) must not appear in the editPool pre-fill block — must use editPoolExclusive"
);
});