refactor: consolidate blockchain explorer into single app and update backup ignore patterns
- Remove standalone explorer-web app (README, HTML, package files) - Add /web endpoint to blockchain-explorer for web interface access - Update .gitignore to exclude application backup archives (*.tar.gz, *.zip) - Add backup documentation files to .gitignore (BACKUP_INDEX.md, README.md) - Consolidate explorer functionality into main blockchain-explorer application
This commit is contained in:
98
apps/wallet/tests/test_wallet_api.py
Normal file
98
apps/wallet/tests/test_wallet_api.py
Normal file
@@ -0,0 +1,98 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.deps import get_keystore, get_ledger, get_settings
|
||||
from app.main import create_app
|
||||
from app.keystore.service import KeystoreService
|
||||
from app.ledger_mock import SQLiteLedgerAdapter
|
||||
|
||||
|
||||
@pytest.fixture(name="client")
|
||||
def client_fixture(tmp_path, monkeypatch):
|
||||
# Override ledger path to temporary directory
|
||||
from app.settings import Settings
|
||||
|
||||
test_settings = Settings(LEDGER_DB_PATH=str(tmp_path / "ledger.db"))
|
||||
|
||||
monkeypatch.setattr("app.settings.settings", test_settings)
|
||||
|
||||
from app import deps
|
||||
|
||||
deps.get_settings.cache_clear()
|
||||
deps.get_keystore.cache_clear()
|
||||
deps.get_ledger.cache_clear()
|
||||
|
||||
app = create_app()
|
||||
|
||||
keystore = KeystoreService()
|
||||
ledger = SQLiteLedgerAdapter(Path(test_settings.ledger_db_path))
|
||||
|
||||
app.dependency_overrides[get_settings] = lambda: test_settings
|
||||
app.dependency_overrides[get_keystore] = lambda: keystore
|
||||
app.dependency_overrides[get_ledger] = lambda: ledger
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def _create_wallet(client: TestClient, wallet_id: str, password: str = "Password!234") -> None:
|
||||
payload = {
|
||||
"wallet_id": wallet_id,
|
||||
"password": password,
|
||||
}
|
||||
response = client.post("/v1/wallets", json=payload)
|
||||
assert response.status_code == 201, response.text
|
||||
|
||||
|
||||
def test_wallet_workflow(client: TestClient):
|
||||
wallet_id = "wallet-1"
|
||||
password = "StrongPass!234"
|
||||
|
||||
# Create wallet
|
||||
response = client.post(
|
||||
"/v1/wallets",
|
||||
json={
|
||||
"wallet_id": wallet_id,
|
||||
"password": password,
|
||||
"metadata": {"label": "test"},
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201, response.text
|
||||
data = response.json()["wallet"]
|
||||
assert data["wallet_id"] == wallet_id
|
||||
assert "public_key" in data
|
||||
|
||||
# List wallets
|
||||
response = client.get("/v1/wallets")
|
||||
assert response.status_code == 200
|
||||
items = response.json()["items"]
|
||||
assert any(item["wallet_id"] == wallet_id for item in items)
|
||||
|
||||
# Unlock wallet
|
||||
response = client.post(f"/v1/wallets/{wallet_id}/unlock", json={"password": password})
|
||||
assert response.status_code == 200
|
||||
assert response.json()["unlocked"] is True
|
||||
|
||||
# Sign payload
|
||||
message = base64.b64encode(b"hello").decode()
|
||||
response = client.post(
|
||||
f"/v1/wallets/{wallet_id}/sign",
|
||||
json={"password": password, "message_base64": message},
|
||||
)
|
||||
assert response.status_code == 200, response.text
|
||||
signature = response.json()["signature_base64"]
|
||||
assert isinstance(signature, str) and len(signature) > 0
|
||||
|
||||
|
||||
def test_wallet_password_rules(client: TestClient):
|
||||
response = client.post(
|
||||
"/v1/wallets",
|
||||
json={"wallet_id": "weak", "password": "short"},
|
||||
)
|
||||
assert response.status_code == 400
|
||||
body = response.json()
|
||||
assert body["detail"]["reason"] == "password_too_weak"
|
||||
assert "min_length" in body["detail"]
|
||||
Reference in New Issue
Block a user