MAESTRO: fix linting and formatting

This commit is contained in:
Mariusz Banach
2026-02-18 04:55:03 +01:00
parent af339e784e
commit 930495cd00
13 changed files with 22 additions and 29 deletions

View File

@@ -20,7 +20,7 @@ This phase performs final integration, accessibility audit, responsive testing,
- [x] T046 Wire all components together in `frontend/src/app/page.tsx` — integrate HeaderInput, FileDropZone, AnalysisControls, AnalyseButton, ProgressIndicator, ReportContainer, CaptchaChallenge into the single-view application with correct data flow. Ensure: input feeds to analysis hook, progress hook drives progress indicator, result feeds to report container, 429 errors trigger CAPTCHA modal, cache hook restores state on mount. Notes: added AnalysisControls + CAPTCHA retry flow, extended analysis hook for bypass token handling, confirmed cache restore.
- [x] T047 Verify WCAG 2.1 AA compliance across all components (NFR-03) — ARIA labels, keyboard nav order, focus indicators, colour contrast ratios (dark theme). Fix violations. Test with screen reader simulation. Ensure all interactive elements have visible focus states. Notes: added keyboard-accessible file picker with ARIA descriptions, focus-visible outlines on drop zone/summary/search fields, boosted low-contrast text from 40% to 60%, linked CAPTCHA dialog description, added file picker tests; ran `npx vitest run src/__tests__/FileDropZone.test.tsx`.
- [x] T048 [P] Verify responsive layout 320px2560px (NFR-04) at breakpoints: 320px, 768px, 1024px, 1440px, 2560px. No horizontal scroll, no overlapping elements, readable text. Fix any layout issues discovered. Notes: stacked control cards on small screens, added min-w-0 + flex-wrap on report UI, and break-words handling for long header values, hop chain hostnames/IPs, and search pills to prevent overflow.
- [ ] T049 [P] Run full linting pass — `ruff check backend/` and `ruff format backend/` zero errors; `npx eslint src/` and `npx prettier --check src/` zero errors; no `any` types in TypeScript. Fix all violations
- [x] T049 [P] Run full linting pass — `ruff check backend/` and `ruff format backend/` zero errors; `npx eslint src/` and `npx prettier --check src/` zero errors; no `any` types in TypeScript. Fix all violations. Notes: ruff formatted backend files, removed unsupported `aria-invalid` on file drop button, ran prettier on CAPTCHA + analysis tests.
- [ ] T050 [P] Run full test suites and verify coverage — `pytest backend/tests/ --cov` ≥80% new modules (NFR-06); `npx vitest run --coverage` ≥80% new components (NFR-07). Add missing tests if coverage is below threshold
- [ ] T051 [P] Verify initial page load <3s on simulated 4G (constitution P7). Use Lighthouse with Slow 4G preset. Target score ≥90. Fix blocking resources or missing lazy-loading if score is below target
- [ ] T052 [P] Benchmark analysis performance — full analysis of `backend/tests/fixtures/sample_headers.txt` completes within 10s (NFR-01). Profile slow scanners. Document results. Optimise if any scanner exceeds acceptable threshold

View File

@@ -68,9 +68,7 @@ class Settings(BaseSettings):
parsed = json.loads(text)
if isinstance(parsed, list):
return [
str(item).strip()
for item in parsed
if str(item).strip()
str(item).strip() for item in parsed if str(item).strip()
]
except json.JSONDecodeError:
pass

View File

@@ -114,9 +114,7 @@ class Logger:
colored = colorizingFunc(c, txt)
if not colored:
raise ValueError(
f"Could not strip colors from phrase: ({patt})!"
)
raise ValueError(f"Could not strip colors from phrase: ({patt})!")
s = s.replace(patt, colored)
pos = 0

View File

@@ -1,2 +1 @@
"""Scanner implementations grouped by vendor or function."""

View File

@@ -189,7 +189,7 @@ def _normalize_payload(payload: object) -> tuple[str, str, str, str] | None:
def _combine_payloads(
payloads: list[tuple[str, str, str, str]]
payloads: list[tuple[str, str, str, str]],
) -> tuple[str, str, str, str]:
headers: list[str] = []
values: list[str] = []

View File

@@ -79,9 +79,7 @@ async def analyse(request: Request) -> StreamingResponse:
)
if len(headers) > MAX_HEADERS_LENGTH:
return JSONResponse(
status_code=413, content={"error": "Headers exceed 1 MB"}
)
return JSONResponse(status_code=413, content={"error": "Headers exceed 1 MB"})
headers = _sanitize_headers(headers)
if not headers.strip():
@@ -120,9 +118,7 @@ async def analyse(request: Request) -> StreamingResponse:
elapsed_ms = (perf_counter() - start) * 1000
percentage = 0.0
if total_tests > 0:
percentage = min(
100.0, (current_index + 1) / total_tests * 100.0
)
percentage = min(100.0, (current_index + 1) / total_tests * 100.0)
payload = AnalysisProgress(
current_index=current_index,
total_tests=total_tests,
@@ -168,9 +164,7 @@ async def analyse(request: Request) -> StreamingResponse:
),
)
await send_stream.send(
("result", final_result.model_dump(by_alias=True))
)
await send_stream.send(("result", final_result.model_dump(by_alias=True)))
await send_stream.send(("done", {}))
async def event_stream() -> Any:

View File

@@ -245,9 +245,7 @@ def _b64decode(data: str) -> bytes:
def _prune_challenges_locked() -> None:
now = time.time()
expired = [
token
for token, record in _CHALLENGES.items()
if record.expires_at <= now
token for token, record in _CHALLENGES.items() if record.expires_at <= now
]
for token in expired:
_CHALLENGES.pop(token, None)

View File

@@ -42,4 +42,4 @@ def test_analyzer_runs_selected_tests_and_reports_progress() -> None:
assert progress_events
assert all(total == 2 for _, total, _ in progress_events)
assert progress_events[0][0] == 0
assert progress_events[-1][0] == 1
assert progress_events[-1][0] == 1

View File

@@ -48,4 +48,4 @@ def test_parser_preserves_content_type_boundary(sample_headers: str) -> None:
headers = parser.parse(sample_headers)
content_type = next(header for header in headers if header.name == "Content-Type")
assert "boundary=\"boundary-123\"" in content_type.value
assert 'boundary="boundary-123"' in content_type.value

View File

@@ -29,4 +29,4 @@ def test_registry_filters_by_ids_and_lists_tests() -> None:
assert lookup[1].category
assert lookup[12].category
assert lookup[66].category
assert lookup[66].category

View File

@@ -105,8 +105,16 @@ const timeoutReport: AnalysisReport = {
};
const AnalysisHarness = ({ request, onStatusChange }: HarnessProps) => {
const { status, progress, result, error, submit, cancel, captchaChallenge, clearCaptchaChallenge } =
useAnalysis();
const {
status,
progress,
result,
error,
submit,
cancel,
captchaChallenge,
clearCaptchaChallenge,
} = useAnalysis();
useEffect(() => {
onStatusChange?.(status);

View File

@@ -105,8 +105,7 @@ export default function CaptchaChallenge({
),
).filter(
(element) =>
!element.hasAttribute("disabled") &&
element.getAttribute("aria-hidden") !== "true",
!element.hasAttribute("disabled") && element.getAttribute("aria-hidden") !== "true",
);
if (focusableElements.length === 0) {

View File

@@ -167,7 +167,6 @@ export default function FileDropZone({ onFileContent }: FileDropZoneProps) {
role="button"
aria-label="Drop or select an EML or TXT file"
aria-describedby={describedBy}
aria-invalid={error ? "true" : undefined}
>
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full border border-info/30 bg-background/40">
<FontAwesomeIcon icon={faArrowUpFromBracket} className="text-sm text-info" />