[CLI] Add a seed-demo command for quick test environments #5

Closed
opened 2026-08-23 13:44:08 +02:00 by vmruiz · 1 comment
Owner

Why

We need a one-shot way to populate the database with believable dummy data so a fresh test environment (or a fresh prod you just stood up) has something to look at. Today there is no seed command — app/cli.py only manages users. Without seed data you stare at an empty Library and cannot tell if the UI works.

This is also a precondition for properly exercising infinite-scroll tests against a real-looking dataset.

Desired behaviour

A new subcommand python -m app.cli seed-demo that:

  • Default: idempotent + additive. If the DB already has items, do nothing (refuse to clobber). Prints a one-line hint pointing at --reset.
  • --reset: wipe items, sources, services (in that order, FK-safe) and re-seed. Must require both --reset and --yes, and print a red warning before running.
  • --count N: how many items to seed (default 200 so infinite scroll is genuinely exercised).
  • --source-count N: how many sources to spread items across (default 2).
  • --with-failures / --no-failures: include a couple of failed status rows (default true).
  • --allow-production: allow running against a non-localhost database. Off by default; the command refuses to run if DATABASE_URL is a postgres:// to a non-localhost host, to prevent foot-guns.

Seeded content:

  • 1–2 Source rows with realistic telegram_chat handles (@sample_channel_books, etc.).
  • 1 Service row of type local_folder (no real network calls).
  • N Item rows spread across content_type ∈ {image, audio, video, text} and status ∈ {discovered, queued, imported, failed} so badges, filters, and progress states all render.
  • Titles prefixed Sample (e.g. Sample Photo 0042, Sample Audiobook Demo — Chapter 7) so nobody confuses them with real media.
  • No Telegram calls, no real downloads/uploads. media_path (if used) points to a non-existent path so the UI shows the existing file-placeholder / file-glyph per AGENTS.md.

Goals

  • Single source of truth for fake data: a pure-Python app/seed.seed_demo(db, *, count, source_count, with_failures) function, importable from tests.
  • New CLI subcommand in app/cli.py that wraps it, reuses the existing argparse style.
  • New pytest fixture seeded_library(count=…) in tests/conftest.py that calls the same function.
  • Idempotent by default; destructive only with explicit flags.
  • Refuses to run against non-localhost DB without --allow-production.

Out of scope

  • Infinite-scroll UI (tracked in #1).
  • Generating real media files (audio/video bytes). Files are not written; only DB rows.
  • Seeding routing rules, OIDC users, or local credentials.

Acceptance

  • python -m app.cli seed-demo on an empty DB seeds the expected number of items + sources + services, prints a summary line.
  • Re-running python -m app.cli seed-demo on a populated DB exits 0 and prints a no-op hint.
  • python -m app.cli seed-demo --reset --yes wipes and re-seeds; without --yes it prompts and refuses on n.
  • python -m app.cli seed-demo against a postgres://prod-host/... DB exits non-zero with a clear error unless --allow-production is passed.
  • app/seed.seed_demo is importable from tests/conftest.py and used by a seeded_library fixture.
  • New tests: test_seed_demo_idempotent, test_seed_demo_reset_wipes_and_reseeds, test_seed_demo_default_count_is_200, test_seed_demo_refuses_production_db, test_seed_demo_allow_production_runs.
## Why We need a one-shot way to populate the database with believable dummy data so a fresh test environment (or a fresh prod you just stood up) has something to look at. Today there is no `seed` command — `app/cli.py` only manages users. Without seed data you stare at an empty Library and cannot tell if the UI works. This is also a precondition for properly exercising infinite-scroll tests against a real-looking dataset. ## Desired behaviour A new subcommand `python -m app.cli seed-demo` that: - **Default**: idempotent + additive. If the DB already has `items`, do nothing (refuse to clobber). Prints a one-line hint pointing at `--reset`. - **`--reset`**: wipe `items`, `sources`, `services` (in that order, FK-safe) and re-seed. Must require both `--reset` and `--yes`, and print a red warning before running. - **`--count N`**: how many items to seed (default **200** so infinite scroll is genuinely exercised). - **`--source-count N`**: how many sources to spread items across (default 2). - **`--with-failures` / `--no-failures`**: include a couple of `failed` status rows (default true). - **`--allow-production`**: allow running against a non-localhost database. Off by default; the command refuses to run if `DATABASE_URL` is a `postgres://` to a non-localhost host, to prevent foot-guns. Seeded content: - 1–2 `Source` rows with realistic `telegram_chat` handles (`@sample_channel_books`, etc.). - 1 `Service` row of type `local_folder` (no real network calls). - N `Item` rows spread across `content_type` ∈ {image, audio, video, text} and `status` ∈ {discovered, queued, imported, failed} so badges, filters, and progress states all render. - Titles prefixed `Sample ` (e.g. `Sample Photo 0042`, `Sample Audiobook Demo — Chapter 7`) so nobody confuses them with real media. - **No** Telegram calls, **no** real downloads/uploads. `media_path` (if used) points to a non-existent path so the UI shows the existing `file-placeholder` / `file-glyph` per `AGENTS.md`. ## Goals - Single source of truth for fake data: a pure-Python `app/seed.seed_demo(db, *, count, source_count, with_failures)` function, importable from tests. - New CLI subcommand in `app/cli.py` that wraps it, reuses the existing argparse style. - New pytest fixture `seeded_library(count=…)` in `tests/conftest.py` that calls the same function. - Idempotent by default; destructive only with explicit flags. - Refuses to run against non-localhost DB without `--allow-production`. ## Out of scope - Infinite-scroll UI (tracked in #1). - Generating real media files (audio/video bytes). Files are not written; only DB rows. - Seeding routing rules, OIDC users, or local credentials. ## Acceptance - `python -m app.cli seed-demo` on an empty DB seeds the expected number of items + sources + services, prints a summary line. - Re-running `python -m app.cli seed-demo` on a populated DB exits 0 and prints a no-op hint. - `python -m app.cli seed-demo --reset --yes` wipes and re-seeds; without `--yes` it prompts and refuses on `n`. - `python -m app.cli seed-demo` against a `postgres://prod-host/...` DB exits non-zero with a clear error unless `--allow-production` is passed. - `app/seed.seed_demo` is importable from `tests/conftest.py` and used by a `seeded_library` fixture. - New tests: `test_seed_demo_idempotent`, `test_seed_demo_reset_wipes_and_reseeds`, `test_seed_demo_default_count_is_200`, `test_seed_demo_refuses_production_db`, `test_seed_demo_allow_production_runs`.
vmruiz referenced this issue from a commit 2026-08-23 17:01:53 +02:00
Author
Owner

Closed by #7

Closed by https://git.celor.es/vmruiz/telegramarr/pulls/7
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
vmruiz/telegramarr#5
No description provided.