mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-30 19:02:16 +00:00
- Rewrite .github/workflows/desktop.yml: 2-job pipeline (validate + build-and-release) with rolling desktop-latest pre-release on push to main and stable desktop-v* releases - Add UpdateChecker component: checks for updates on startup + every 30 min, background download with progress bar, one-click relaunch - Configure Tauri updater: endpoints pointing to desktop-latest release, pubkey placeholder - Add tauri-plugin-process for relaunch support (Cargo.toml, lib.rs, package.json) - Add macOS Entitlements.plist for notarization (network + file access, no sandbox) - Add scripts/bump-desktop-version.sh for atomic version bumps across 3 config files - Add desktop/README.md with dev setup, auto-update architecture, signing docs - Update .gitignore for desktop/node_modules, dist, target - Configure macOS minimumSystemVersion, Windows timestampUrl - Include all Phase 14-21 work: agent hardening, RBAC, taint tracking, workflows, skills, knowledge graph, sessions, A2A, MCP templates, WASM sandbox, TUI dashboard, production tools, CLI expansion, API expansion, learning productionization, Tauri desktop app, and 10 new channels Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
102 lines
3.0 KiB
Python
102 lines
3.0 KiB
Python
"""Tests for the Learning Dashboard API endpoints."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import FastAPI
|
|
from starlette.testclient import TestClient
|
|
|
|
from openjarvis.server.api_routes import learning_router
|
|
|
|
|
|
def _make_app() -> FastAPI:
|
|
"""Create a minimal FastAPI app with the learning router included."""
|
|
app = FastAPI()
|
|
app.include_router(learning_router)
|
|
return app
|
|
|
|
|
|
def _client() -> TestClient:
|
|
return TestClient(_make_app())
|
|
|
|
|
|
# ---- /v1/learning/stats tests ----
|
|
|
|
|
|
def test_learning_stats_returns_200():
|
|
"""GET /v1/learning/stats should return 200."""
|
|
client = _client()
|
|
resp = client.get("/v1/learning/stats")
|
|
assert resp.status_code == 200
|
|
|
|
|
|
def test_learning_stats_has_all_sections():
|
|
"""Response must contain grpo, bandit, icl, and skill_discovery sections."""
|
|
client = _client()
|
|
data = client.get("/v1/learning/stats").json()
|
|
for section in ("grpo", "bandit", "icl", "skill_discovery"):
|
|
assert section in data, f"Missing section: {section}"
|
|
assert "available" in data[section], (
|
|
f"Section '{section}' missing 'available' key"
|
|
)
|
|
|
|
|
|
def test_learning_stats_grpo_fields():
|
|
"""When GRPO is available, verify expected stat fields are present."""
|
|
client = _client()
|
|
data = client.get("/v1/learning/stats").json()
|
|
grpo = data["grpo"]
|
|
if grpo["available"]:
|
|
assert "total_updates" in grpo
|
|
assert "sample_counts" in grpo
|
|
assert "weight_count" in grpo
|
|
|
|
|
|
def test_learning_stats_icl_fields():
|
|
"""When ICL is available, verify expected stat fields are present."""
|
|
client = _client()
|
|
data = client.get("/v1/learning/stats").json()
|
|
icl = data["icl"]
|
|
if icl["available"]:
|
|
assert "example_count" in icl
|
|
assert "example_db_count" in icl
|
|
assert "version" in icl
|
|
|
|
|
|
# ---- /v1/learning/policy tests ----
|
|
|
|
|
|
def test_learning_policy_returns_200():
|
|
"""GET /v1/learning/policy should return 200."""
|
|
client = _client()
|
|
resp = client.get("/v1/learning/policy")
|
|
assert resp.status_code == 200
|
|
|
|
|
|
def test_learning_policy_has_expected_keys():
|
|
"""Response must include enabled, routing, intelligence, agent, metrics."""
|
|
client = _client()
|
|
data = client.get("/v1/learning/policy").json()
|
|
assert "enabled" in data
|
|
assert "routing" in data
|
|
assert "intelligence" in data
|
|
assert "agent" in data
|
|
assert "metrics" in data
|
|
|
|
|
|
def test_learning_policy_routing_structure():
|
|
"""The routing section should contain policy name and min_samples."""
|
|
client = _client()
|
|
data = client.get("/v1/learning/policy").json()
|
|
routing = data["routing"]
|
|
assert "policy" in routing
|
|
assert "min_samples" in routing
|
|
assert isinstance(routing["policy"], str)
|
|
assert isinstance(routing["min_samples"], int)
|
|
|
|
|
|
def test_learning_policy_enabled_is_bool():
|
|
"""The enabled field should be a boolean."""
|
|
client = _client()
|
|
data = client.get("/v1/learning/policy").json()
|
|
assert isinstance(data["enabled"], bool)
|