feat: #78 Excalidraw finitions + #67 push + #68 health-detailed + #77 desktop jumplist
CI / lint (push) Successful in 52s
CI / security (push) Successful in 36s
CI / test (push) Successful in 1m6s
CI / build (push) Successful in 1m15s
CI / e2e (push) Failing after 12m40s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
CI / lint (push) Successful in 52s
CI / security (push) Successful in 36s
CI / test (push) Successful in 1m6s
CI / build (push) Successful in 1m15s
CI / e2e (push) Failing after 12m40s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
#78 Excalidraw — finitions B5/C8/F2/F3 - backend/indexer.py: port Python pur de lz-string decompressFromBase64 (bitsPerChar=6, resetValue=32) validé contre 4 fixtures JS truth (texte accentué, edge cases) — remplace le stub base64 non-fonctionnel - B5 indexation: .excalidraw.md (format plugin Obsidian) maintenant décompressé côté Python → texte indexé pour recherche TF-IDF - 7 nouveaux tests B5 dans tests/test_excalidraw.py (13/13 total) - F2: excalidraw-viewer.test.mjs enregistré dans CI (lint job) - F3: tests/e2e/excalidraw.spec.js (9 specs — ouverture .excalidraw/.excalidraw.md, création via modale/menu contextuel, toolbar, thème, pop-out, recherche) - Fixtures test_vault/diagram.excalidraw + diagram.excalidraw.md #67 Push notifications (Web Push API + VAPID) - backend/push.py: router + VAPID keys + send_push_notification (pywebpush>=2.3.0) - frontend/js/push.js: subscription UI + service worker integration - tests/test_push.py: 10 tests (subscribe/list/unsubscribe/vapid key) - requirements.txt + sw.js + locales push strings #68 Health check enrichi - backend/main.py: GET /api/health/detailed (admin) — memory/cpu/disk/backups/index/SSE connections - backend/indexer.py: _last_full_index_ts tracking - tests/conftest.py: admin_client fixture - tests/test_api_main.py: 3 nouveaux tests health detailed #77 Desktop jumplist - desktop/src/jumplist.rs: Windows jumplist integration - Cargo.toml/lock + capabilities + main.rs - frontend/js/desktop.js: Tauri bridge (isTauriEnv, invoke, getSystemTheme, syncSystemTheme, shouldShowWizard, crash banner) - tests/frontend/desktop.test.mjs: 21 tests JSDOM (détection, invoke degradation, theme gating, wizard, crash banner) - tests/frontend/unit.test.mjs: desktop.js whitelisted (standalone global reader) # Frontend & CI - frontend/sw.js: réécriture complète (precache + push event handlers + offline) - frontend/index.html: section push dans settings + about repositionné - frontend/js/app.js: initDesktopIntegration + initPush - CI .gitea/workflows/ci.yml: excalidraw-viewer.test.mjs ajouté au lint job All checks: ruff clean, 552 backend tests pass, 9 frontend unit, 5 excalidraw-viewer, 21 desktop, 9 pane-manager, validate-imports 33 modules.
This commit is contained in:
+92
-1
@@ -1,6 +1,8 @@
|
||||
# tests/conftest.py — Shared fixtures for ObsiGate test suite
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -106,7 +108,96 @@ def app_with_vault(test_vault_dir: str):
|
||||
return client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ pytest.fixture
|
||||
def client(app_with_vault):
|
||||
"""Alias for app_with_vault."""
|
||||
return app_with_vault
|
||||
|
||||
|
||||
@ pytest.fixture
|
||||
def admin_client(tmp_path):
|
||||
"""TestClient with auth enabled, isolated temp data, admin user provisioned.
|
||||
|
||||
Used by tests that need admin authentication (e.g., /api/health/detailed).
|
||||
"""
|
||||
data_dir = tmp_path / "data"
|
||||
data_dir.mkdir()
|
||||
|
||||
import json
|
||||
from backend.auth.password import hash_password
|
||||
|
||||
pw_hash = hash_password("chab30")
|
||||
users = {
|
||||
"version": 1,
|
||||
"users": {
|
||||
"admin": {
|
||||
"id": "admin-1",
|
||||
"username": "admin",
|
||||
"display_name": "admin",
|
||||
"password_hash": pw_hash,
|
||||
"role": "admin",
|
||||
"vaults": ["*"],
|
||||
"active": True,
|
||||
"created_at": "2026-01-01T00:00:00",
|
||||
},
|
||||
"normaluser": {
|
||||
"id": "user-1",
|
||||
"username": "normaluser",
|
||||
"display_name": "normal",
|
||||
"password_hash": hash_password("normal123"),
|
||||
"role": "user",
|
||||
"vaults": ["TestVault"],
|
||||
"active": True,
|
||||
"created_at": "2026-01-01T00:00:00",
|
||||
},
|
||||
},
|
||||
}
|
||||
(data_dir / "users.json").write_text(json.dumps(users), encoding="utf-8")
|
||||
|
||||
src_secret = Path("data/secret.key")
|
||||
if src_secret.exists():
|
||||
shutil.copy2(str(src_secret), str(data_dir / "secret.key"))
|
||||
|
||||
orig_cwd = os.getcwd()
|
||||
test_vault_path = os.path.abspath("test-vault")
|
||||
os.chdir(str(tmp_path))
|
||||
|
||||
os.environ["VAULT_1_NAME"] = "TestVault"
|
||||
os.environ["VAULT_1_PATH"] = test_vault_path
|
||||
os.environ["OBSIGATE_AUTH_ENABLED"] = "true"
|
||||
os.environ["OBSIGATE_ADMIN_USER"] = "admin"
|
||||
os.environ["OBSIGATE_ADMIN_PASSWORD"] = "chab30"
|
||||
os.environ["OBSIGATE_WATCHER_ENABLED"] = "false"
|
||||
|
||||
import backend.main
|
||||
backend.main._load_config = lambda: {"watcher_enabled": False}
|
||||
|
||||
from backend.main import app
|
||||
from backend.indexer import build_index, index
|
||||
import asyncio
|
||||
|
||||
for key in list(index.keys()):
|
||||
del index[key]
|
||||
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(build_index())
|
||||
|
||||
from backend.search import init_inverted_index
|
||||
init_inverted_index()
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
client = TestClient(app)
|
||||
yield client
|
||||
|
||||
if hasattr(client, "close"):
|
||||
client.close()
|
||||
loop.run_until_complete(asyncio.sleep(0))
|
||||
|
||||
os.chdir(orig_cwd)
|
||||
shutil.rmtree(str(tmp_path), ignore_errors=True)
|
||||
for k in [
|
||||
"VAULT_1_NAME", "VAULT_1_PATH", "OBSIGATE_AUTH_ENABLED",
|
||||
"OBSIGATE_ADMIN_USER", "OBSIGATE_ADMIN_PASSWORD", "OBSIGATE_WATCHER_ENABLED",
|
||||
]:
|
||||
os.environ.pop(k, None)
|
||||
|
||||
Reference in New Issue
Block a user