Skip to content

test: add backend simple tests and enable ty check#542

Open
k4black wants to merge 5 commits into
maxdorninger:masterfrom
k4black:feat-tests-foundation
Open

test: add backend simple tests and enable ty check#542
k4black wants to merge 5 commits into
maxdorninger:masterfrom
k4black:feat-tests-foundation

Conversation

@k4black

@k4black k4black commented May 16, 2026

Copy link
Copy Markdown
Contributor

Hey!
While implementing #541 i was really missed quick way to make sure to check that the repo is operational / type checked.

  • Tests (just baseline): Add simple unit tests and api tests
  • Type checking: I see you are using ty already, fixed all 72 errors
  • CI: Added separate workflow with python tests; call it from the main build-push ci
  • Docs: mention ty in docs

NOT included: proper api test, db tests, e2e test -- the main gold pf this PR is not discuss and make a foundation to build on + enable auto-testing in ci.

That would be great if you can take a look! @maxdorninger
Thanks!

Summary by CodeRabbit

  • Tests

    • Added broad test suites for indexer quality, season/episode parsing, scoring rules, torrent utilities, API health/auth, and test factories/fixtures.
  • Bug Fixes

    • Improved indexer XML parsing to safely handle missing elements.
    • Fixed torrent deletion logging to reference the correct field.
  • Documentation

    • Expanded developer guide with formatting, linting, type-checking, and test-running instructions.
  • Chores

    • Added CI workflow for backend tests and linting; reused it from build workflow. Updated lint/test tooling and per-file lint ignores.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 16, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d556afcf-4131-4f3d-84b2-45305c4007d4

📥 Commits

Reviewing files that changed from the base of the PR and between 90ad7c7 and 44b2a0b.

📒 Files selected for processing (1)
  • media_manager/indexer/indexers/torznab_mixin.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • media_manager/indexer/indexers/torznab_mixin.py

📝 Walkthrough

Walkthrough

Adds a reusable backend test-and-lint CI workflow, root pytest configuration and fixtures, constrains common generics with PEP 695, hardens indexer XML parsing, expands unit tests (indexer, torrent utils, API smoke tests), and applies peripheral type-suppression/annotation fixes.

Changes

Testing & Type-Checking Infrastructure Upgrade

Layer / File(s) Summary
CI/CD workflow extraction & integration
.github/workflows/backend-test-lint.yml, .github/workflows/build-push-backend.yml
Creates a reusable backend-test-lint workflow that runs ruff, ty, and pytest; integrates it into build-push gating.
Pytest configuration & root fixtures
conftest.py, tests/factories/indexer.py, tests/types.py, pyproject.toml, ruff.toml
Root conftest.py sets env overrides and a patch_scoring_rules fixture; adds make_indexer_result factory and PatchScoringRules protocol; configures pytest discovery/markers in pyproject.toml; adds ruff per-file test ignores.
Generic type system modernisation
media_manager/common/repository.py, media_manager/common/service.py
Convert repository/service generics to bounded PEP 695 parameters; adjust add_media_file_base generics, nullable import_all_torrents_base callback, and related type-handling updates.
Service/importer signatures & schema updates
media_manager/tv/importer.py, media_manager/tv/service.py, media_manager/movies/importer.py, media_manager/common/schemas.py
Importers and services adopt TorrentId/PublicEpisode types; import_* methods call _get_import_candidates_base; update method signatures and small wiring changes.
Indexer parsing hardening & tests
media_manager/indexer/indexers/torznab_mixin.py, media_manager/indexer/indexers/jackett.py, media_manager/indexer/indexers/prowlarr.py, media_manager/indexer/tests/test_schemas.py, media_manager/indexer/tests/test_scoring.py
Defensive XML/enclosure/title handling, UTC timestamp fix, typed search param dicts; add parameterised tests for quality/season/episode extraction and ordering; add comprehensive scoring rule tests.
Torrent utils tests
media_manager/torrent/tests/test_utils.py
Adds tests for remove_special_characters, remove_special_chars_and_parentheses, and extract_external_id_from_string.
API health & smoke tests
tests/api/conftest.py, tests/api/test_health.py
Adds TestClient fixture and smoke tests for /api/v1/health, OpenAPI schema, mounted routers, and auth rejection of anonymous requests.
Peripheral type suppressions & fixes
media_manager/auth/router.py, media_manager/auth/users.py, media_manager/main.py, media_manager/torrent/download_clients/qbittorrent.py, media_manager/notification/repository.py, media_manager/movies/service.py
Add ty: ignore[...] comments, annotate external API returns, cast SQLAlchemy results to CursorResult, and fix a logging field name.
Developer guide & local workflow documentation
docs/contributing-to-mediamanager/developer-guide.md
Expand local setup doc with ruff/ty workflows, suppression syntax note, and test-running guidance.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • maxdorninger/MediaManager#526: Shares type-system modernisation in common/repository.py and common/service.py (PEP 695 generics) and related importer wiring changes.

Poem

🐰 I hopped through workflows, tests in tow,

Types now tighter, lint checks glow,
Fixtures steady, parsers wise,
Tests confirm what meets the eyes,
The warren's code is set to grow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely and accurately describes the main changes: adding tests and enabling type checking with ty.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the enhancement New feature or request label May 16, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@media_manager/indexer/indexers/torznab_mixin.py`:
- Around line 31-35: The code accesses enclosure.attrib['type'] and
enclosure.attrib['url'] directly which raises when attributes are missing;
update the handling in the torznab_mixin logic (where enclosure is found/checked
and later referenced around the enclosure variable and the code at the second
access near line 79) to explicitly guard attribute access: use
enclosure.get('type') and enclosure.get('url') (or check 'type' in
enclosure.attrib and 'url' in enclosure.attrib'), and if either is missing log a
warning like "Torznab item missing enclosure type/url, skipping." and continue
so malformed items are skipped deterministically instead of triggering the broad
exception path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: def51c93-4abb-4d42-8c83-5f11237498a1

📥 Commits

Reviewing files that changed from the base of the PR and between 25cd4b0 and 90ad7c7.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • .github/workflows/backend-test-lint.yml
  • .github/workflows/build-push-backend.yml
  • conftest.py
  • docs/contributing-to-mediamanager/developer-guide.md
  • media_manager/auth/router.py
  • media_manager/auth/users.py
  • media_manager/common/repository.py
  • media_manager/common/schemas.py
  • media_manager/common/service.py
  • media_manager/indexer/indexers/jackett.py
  • media_manager/indexer/indexers/prowlarr.py
  • media_manager/indexer/indexers/torznab_mixin.py
  • media_manager/indexer/tests/test_schemas.py
  • media_manager/indexer/tests/test_scoring.py
  • media_manager/main.py
  • media_manager/movies/importer.py
  • media_manager/movies/service.py
  • media_manager/notification/repository.py
  • media_manager/torrent/download_clients/qbittorrent.py
  • media_manager/torrent/tests/test_utils.py
  • media_manager/tv/importer.py
  • media_manager/tv/service.py
  • pyproject.toml
  • ruff.toml
  • tests/api/__init__.py
  • tests/api/conftest.py
  • tests/api/test_health.py
  • tests/factories/indexer.py
  • tests/types.py
📜 Review details
🔇 Additional comments (30)
media_manager/common/repository.py (1)

2-2: LGTM!

Also applies to: 5-6, 10-11, 19-19, 142-144, 148-150, 180-182

media_manager/common/service.py (1)

4-4: LGTM!

Also applies to: 7-8, 26-26, 52-52, 85-85, 97-97, 137-137, 155-155, 208-210

media_manager/auth/router.py (1)

37-37: LGTM!

Also applies to: 53-53

media_manager/auth/users.py (1)

60-62: LGTM!

Also applies to: 141-143, 228-236

media_manager/main.py (1)

147-147: LGTM!

Also applies to: 152-152

media_manager/movies/service.py (1)

91-91: LGTM!

media_manager/notification/repository.py (1)

2-2: LGTM!

Also applies to: 4-4, 94-94

media_manager/torrent/download_clients/qbittorrent.py (1)

63-65: LGTM!

Also applies to: 177-179

media_manager/torrent/tests/test_utils.py (1)

1-62: LGTM!

docs/contributing-to-mediamanager/developer-guide.md (2)

200-224: LGTM!


225-236: LGTM!

media_manager/common/schemas.py (1)

7-7: LGTM!

Also applies to: 28-28

media_manager/tv/importer.py (1)

14-14: LGTM!

Also applies to: 40-40, 59-59, 121-121

media_manager/movies/importer.py (1)

38-38: LGTM!

Also applies to: 125-125

media_manager/tv/service.py (1)

25-25: LGTM!

Also applies to: 224-224

media_manager/indexer/indexers/torznab_mixin.py (1)

3-3: LGTM!

Also applies to: 26-29, 44-44, 66-66

media_manager/indexer/indexers/jackett.py (1)

93-96: LGTM!

Also applies to: 203-203

media_manager/indexer/indexers/prowlarr.py (1)

135-135: LGTM!

Also applies to: 164-164

media_manager/indexer/tests/test_schemas.py (1)

1-80: LGTM!

media_manager/indexer/tests/test_scoring.py (1)

1-134: LGTM!

tests/factories/indexer.py (1)

1-22: LGTM!

tests/types.py (1)

1-17: LGTM!

.github/workflows/backend-test-lint.yml (1)

1-65: LGTM!

.github/workflows/build-push-backend.yml (1)

36-38: LGTM!

Also applies to: 59-59

conftest.py (1)

1-66: LGTM!

pyproject.toml (2)

53-64: LGTM!


45-46: ⚡ Quick win

Dependency versions are valid and compatible.

Pytest 9.0.3 (released 7 April 2026) and pytest-asyncio 1.3.0 (released as stable version) are confirmed compatible. pytest-asyncio 1.3.0 was specifically updated to support pytest 9, confirming compatibility with the asyncio_mode = "strict" configuration.

ruff.toml (1)

46-58: LGTM!

tests/api/conftest.py (1)

1-11: LGTM!

tests/api/test_health.py (1)

10-45: LGTM!

Comment thread media_manager/indexer/indexers/torznab_mixin.py Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant