One app fixture for the tests, and ViewModels built where they are used
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Android / Build, or is the channel already serving this? (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Skipped
Desktop (Tauri) / Tauri desktop (Linux) (push) Skipped
Desktop (Tauri) / Windows installer (cross-compiled) (push) Skipped
Desktop (Tauri) / Update manifest (push) Skipped
CI & Build / Web typecheck and unit tests (push) Successful in 8s
CI & Build / Python tests (push) Successful in 13s
Android / Core and FFI clippy and tests (push) Successful in 25s
CI & Build / integration (push) Successful in 1m31s
CI & Build / Build & push image (push) Skipped
Android / Kotlin + Rust (APK) (push) Successful in 6m41s
Android / Build the server image (push) Successful in 1s

The tests' `app` fixture, the same two lines in eleven files, now lives once in
tests/conftest.py.

On Android each ViewModel carried a companion `factory` that only wrapped its
constructor in viewModelFactory { initializer { … } }. MainActivity now builds
each one with Compose's viewModel { … } builder, so the five factories and their
imports are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 21:25:05 -04:00
co-authored by Claude Opus 5.5
parent 463b22bbe4
commit b74dc7c1fe
18 changed files with 21 additions and 145 deletions
+7
View File
@@ -1,5 +1,6 @@
import pytest
from inkwell.app import create_app
from inkwell.config import Config
@@ -10,3 +11,9 @@ def _isolated_data_dir(tmp_path, monkeypatch):
signing key from env-or-random, not a file), but this stays defensive."""
monkeypatch.setattr(Config, "DATA_DIR", str(tmp_path / "data"))
yield
@pytest.fixture
def app():
"""A fresh app for a test that drives routes through `app.test_client()`."""
return create_app()
-10
View File
@@ -1,13 +1,3 @@
import pytest
from inkwell.app import create_app
@pytest.fixture
def app():
return create_app()
async def test_settings_requires_auth(app):
# require_admin returns 401 before any DB access when unauthenticated.
client = app.test_client()
-7
View File
@@ -1,13 +1,6 @@
import pytest
from inkwell.app import create_app
@pytest.fixture
def app():
return create_app()
async def test_health_ok(app):
client = app.test_client()
resp = await client.get("/api/health")
-6
View File
@@ -4,7 +4,6 @@ from pathlib import Path
import pytest
from inkwell import client_dist
from inkwell.app import create_app
from inkwell.client_dist import (
BY_ID,
PLATFORMS,
@@ -54,11 +53,6 @@ def _empty_baked_client(tmp_path, monkeypatch):
yield
@pytest.fixture
def app():
return create_app()
def place(
platform_id: str = "android",
payload: bytes = PAYLOAD,
-10
View File
@@ -1,13 +1,3 @@
import pytest
from inkwell.app import create_app
@pytest.fixture
def app():
return create_app()
async def test_create_device_requires_auth(app):
# No session cookie and no bearer header → 401 before any DB access.
client = app.test_client()
-6
View File
@@ -1,7 +1,6 @@
import pytest
from inkwell import installer, settings
from inkwell.app import create_app
from inkwell.installer import PLACEHOLDER, SOURCE_SCRIPT, render, server_address
# DB-free, like test_client_dist: the route reads `public_url` from the live cache
@@ -17,11 +16,6 @@ def _defaults():
settings.reset_live()
@pytest.fixture
def app():
return create_app()
def test_the_published_script_carries_the_line_the_server_rewrites_exactly_once():
"""The forge-served script and the server-served one are the same file; this is
the one line that differs. Edit it and the server stops serving rather than
-8
View File
@@ -1,17 +1,9 @@
import uuid
import pytest
from inkwell.app import create_app
from inkwell.models.label import Label
from inkwell.serialize import serialize_label
@pytest.fixture
def app():
return create_app()
def test_serialize_label_shape():
# The base {id, name, color} shape the labels API and (S4) sync deltas both build on.
lid = uuid.uuid4()
-6
View File
@@ -5,7 +5,6 @@ from datetime import datetime, timezone
import pytest
from inkwell.app import create_app
from inkwell.common import coerce_bool, parse_dt
from inkwell.colors import NOTE_COLORS
from inkwell.models.note import Note
@@ -34,11 +33,6 @@ from inkwell.notes.recurrence import next_occurrence, normalize_recurrence
from inkwell.notes.tags import parse_tags, split_body_tags
@pytest.fixture
def app():
return create_app()
def test_all_note_routes_registered(app):
# Guards the notes package split: every route handler must still be attached to the
# blueprint. A route whose module isn't imported by notes/__init__ would silently
-6
View File
@@ -10,7 +10,6 @@ import pytest
from inkwell import ratelimit
from inkwell.settings import live
from inkwell.app import create_app
from inkwell.ratelimit import SlidingWindow
@@ -28,11 +27,6 @@ def _clean_counters():
ratelimit.reset_all()
@pytest.fixture
def app():
return create_app()
def test_under_the_limit_is_not_blocked():
w = window(3, 60)
for i in range(3):
-8
View File
@@ -4,14 +4,6 @@ Asserted on /api/health because it is the one route that needs no database and n
session — the headers are set in an after_request hook, so any response proves the
hook, and this suite has no Postgres.
"""
import pytest
from inkwell.app import create_app
@pytest.fixture
def app():
return create_app()
async def test_content_security_policy_locks_scripts_to_self(app):
-8
View File
@@ -1,8 +1,5 @@
from datetime import datetime, timezone
import pytest
from inkwell.app import create_app
from inkwell.sync import (
DEFAULT_LIMIT,
MAX_LIMIT,
@@ -17,11 +14,6 @@ from inkwell.sync import (
)
@pytest.fixture
def app():
return create_app()
async def test_changes_requires_auth(app):
client = app.test_client()
resp = await client.get("/api/sync/changes")
-6
View File
@@ -2,15 +2,9 @@ import ipaddress
import pytest
from inkwell.app import create_app
from inkwell.unfurl import UnfurlError, extract_preview, is_public_ip, validate_url
@pytest.fixture
def app():
return create_app()
def test_is_public_ip_blocks_internal_ranges():
assert is_public_ip(ipaddress.ip_address("8.8.8.8"))
assert is_public_ip(ipaddress.ip_address("2606:4700:4700::1111"))