fix(audit): sort milestones, sort JSON export, extract test helper
- Fix milestone section using unsorted repos list - Apply --sort to --format json output - Rename _sort_repos to sort_repos (now used by cli.py) - Extract shared make_repo helper to tests/helpers.py - Move exporter import to module level in cli.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,8 @@ from rich.console import Console
|
|||||||
|
|
||||||
from gitea_dashboard.client import GiteaClient
|
from gitea_dashboard.client import GiteaClient
|
||||||
from gitea_dashboard.collector import collect_all
|
from gitea_dashboard.collector import collect_all
|
||||||
from gitea_dashboard.display import render_dashboard
|
from gitea_dashboard.display import render_dashboard, sort_repos
|
||||||
|
from gitea_dashboard.exporter import export_json
|
||||||
|
|
||||||
_DEFAULT_URL = "http://192.168.0.106:3000"
|
_DEFAULT_URL = "http://192.168.0.106:3000"
|
||||||
|
|
||||||
@@ -107,8 +108,7 @@ def main(argv: list[str] | None = None) -> None:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if args.format == "json":
|
if args.format == "json":
|
||||||
from gitea_dashboard.exporter import export_json
|
sorted_repos = sort_repos(repos, args.sort)
|
||||||
|
print(export_json(sorted_repos)) # noqa: T201
|
||||||
print(export_json(repos)) # noqa: T201
|
|
||||||
else:
|
else:
|
||||||
render_dashboard(repos, sort_key=args.sort)
|
render_dashboard(repos, sort_key=args.sort)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ def _colorize_milestone_due(due_on: str | None) -> str:
|
|||||||
return "green"
|
return "green"
|
||||||
|
|
||||||
|
|
||||||
def _sort_repos(repos: list[RepoData], sort_key: str) -> list[RepoData]:
|
def sort_repos(repos: list[RepoData], sort_key: str) -> list[RepoData]:
|
||||||
"""Trie la liste des repos selon le critere donne.
|
"""Trie la liste des repos selon le critere donne.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -144,7 +144,7 @@ def render_dashboard(
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Tri des repos
|
# Tri des repos
|
||||||
sorted_repos = _sort_repos(repos, sort_key)
|
sorted_repos = sort_repos(repos, sort_key)
|
||||||
|
|
||||||
# Tableau principal
|
# Tableau principal
|
||||||
table = Table(title="Gitea Dashboard")
|
table = Table(title="Gitea Dashboard")
|
||||||
@@ -172,7 +172,7 @@ def render_dashboard(
|
|||||||
console.print(table)
|
console.print(table)
|
||||||
|
|
||||||
# Section milestones — uniquement si au moins un repo en a
|
# Section milestones — uniquement si au moins un repo en a
|
||||||
repos_with_milestones = [r for r in repos if r.milestones]
|
repos_with_milestones = [r for r in sorted_repos if r.milestones]
|
||||||
|
|
||||||
if repos_with_milestones:
|
if repos_with_milestones:
|
||||||
console.print()
|
console.print()
|
||||||
|
|||||||
30
tests/helpers.py
Normal file
30
tests/helpers.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
"""Shared test fixtures and helpers."""
|
||||||
|
|
||||||
|
from gitea_dashboard.collector import RepoData
|
||||||
|
|
||||||
|
|
||||||
|
def make_repo(
|
||||||
|
name="my-repo",
|
||||||
|
full_name="admin/my-repo",
|
||||||
|
description="A repo",
|
||||||
|
open_issues=3,
|
||||||
|
is_fork=False,
|
||||||
|
is_archived=False,
|
||||||
|
is_mirror=False,
|
||||||
|
latest_release=None,
|
||||||
|
milestones=None,
|
||||||
|
last_commit_date=None,
|
||||||
|
):
|
||||||
|
"""Build a RepoData for testing."""
|
||||||
|
return RepoData(
|
||||||
|
name=name,
|
||||||
|
full_name=full_name,
|
||||||
|
description=description,
|
||||||
|
open_issues=open_issues,
|
||||||
|
is_fork=is_fork,
|
||||||
|
is_archived=is_archived,
|
||||||
|
is_mirror=is_mirror,
|
||||||
|
latest_release=latest_release,
|
||||||
|
milestones=milestones if milestones is not None else [],
|
||||||
|
last_commit_date=last_commit_date,
|
||||||
|
)
|
||||||
@@ -4,11 +4,13 @@ from io import StringIO
|
|||||||
|
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
from gitea_dashboard.collector import RepoData
|
|
||||||
from gitea_dashboard.display import (
|
from gitea_dashboard.display import (
|
||||||
render_dashboard,
|
render_dashboard,
|
||||||
|
sort_repos,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from tests.helpers import make_repo as _make_repo
|
||||||
|
|
||||||
|
|
||||||
def _make_console():
|
def _make_console():
|
||||||
"""Create a console that captures output for testing.
|
"""Create a console that captures output for testing.
|
||||||
@@ -20,33 +22,6 @@ def _make_console():
|
|||||||
return Console(file=buf, force_terminal=True, width=120, highlight=False), buf
|
return Console(file=buf, force_terminal=True, width=120, highlight=False), buf
|
||||||
|
|
||||||
|
|
||||||
def _make_repo(
|
|
||||||
name="my-repo",
|
|
||||||
full_name="admin/my-repo",
|
|
||||||
description="A repo",
|
|
||||||
open_issues=3,
|
|
||||||
is_fork=False,
|
|
||||||
is_archived=False,
|
|
||||||
is_mirror=False,
|
|
||||||
latest_release=None,
|
|
||||||
milestones=None,
|
|
||||||
last_commit_date=None,
|
|
||||||
):
|
|
||||||
"""Build a RepoData for testing."""
|
|
||||||
return RepoData(
|
|
||||||
name=name,
|
|
||||||
full_name=full_name,
|
|
||||||
description=description,
|
|
||||||
open_issues=open_issues,
|
|
||||||
is_fork=is_fork,
|
|
||||||
is_archived=is_archived,
|
|
||||||
is_mirror=is_mirror,
|
|
||||||
latest_release=latest_release,
|
|
||||||
milestones=milestones if milestones is not None else [],
|
|
||||||
last_commit_date=last_commit_date,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestRenderDashboardTable:
|
class TestRenderDashboardTable:
|
||||||
"""Test the main repos table rendering."""
|
"""Test the main repos table rendering."""
|
||||||
|
|
||||||
@@ -290,35 +265,32 @@ class TestColorizeMilestoneDue:
|
|||||||
|
|
||||||
|
|
||||||
class TestSortRepos:
|
class TestSortRepos:
|
||||||
"""Test _sort_repos function."""
|
"""Test sort_repos function."""
|
||||||
|
|
||||||
def test_sort_by_name(self):
|
def test_sort_by_name(self):
|
||||||
"""Sorts alphabetically by name (case-insensitive)."""
|
"""Sorts alphabetically by name (case-insensitive)."""
|
||||||
from gitea_dashboard.display import _sort_repos
|
|
||||||
|
|
||||||
repos = [
|
repos = [
|
||||||
_make_repo(name="Charlie"),
|
_make_repo(name="Charlie"),
|
||||||
_make_repo(name="alpha"),
|
_make_repo(name="alpha"),
|
||||||
_make_repo(name="Bravo"),
|
_make_repo(name="Bravo"),
|
||||||
]
|
]
|
||||||
result = _sort_repos(repos, "name")
|
result = sort_repos(repos, "name")
|
||||||
assert [r.name for r in result] == ["alpha", "Bravo", "Charlie"]
|
assert [r.name for r in result] == ["alpha", "Bravo", "Charlie"]
|
||||||
|
|
||||||
def test_sort_by_issues(self):
|
def test_sort_by_issues(self):
|
||||||
"""Sorts by issues count descending."""
|
"""Sorts by issues count descending."""
|
||||||
from gitea_dashboard.display import _sort_repos
|
|
||||||
|
|
||||||
repos = [
|
repos = [
|
||||||
_make_repo(name="low", open_issues=1),
|
_make_repo(name="low", open_issues=1),
|
||||||
_make_repo(name="high", open_issues=10),
|
_make_repo(name="high", open_issues=10),
|
||||||
_make_repo(name="mid", open_issues=5),
|
_make_repo(name="mid", open_issues=5),
|
||||||
]
|
]
|
||||||
result = _sort_repos(repos, "issues")
|
result = sort_repos(repos, "issues")
|
||||||
assert [r.name for r in result] == ["high", "mid", "low"]
|
assert [r.name for r in result] == ["high", "mid", "low"]
|
||||||
|
|
||||||
def test_sort_by_release(self):
|
def test_sort_by_release(self):
|
||||||
"""Sorts by release date descending; repos without release last."""
|
"""Sorts by release date descending; repos without release last."""
|
||||||
from gitea_dashboard.display import _sort_repos
|
|
||||||
|
|
||||||
repos = [
|
repos = [
|
||||||
_make_repo(name="no-rel", latest_release=None),
|
_make_repo(name="no-rel", latest_release=None),
|
||||||
@@ -331,17 +303,16 @@ class TestSortRepos:
|
|||||||
latest_release={"tag_name": "v2.0", "published_at": "2026-03-01T00:00:00Z"},
|
latest_release={"tag_name": "v2.0", "published_at": "2026-03-01T00:00:00Z"},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
result = _sort_repos(repos, "release")
|
result = sort_repos(repos, "release")
|
||||||
assert [r.name for r in result] == ["new", "old", "no-rel"]
|
assert [r.name for r in result] == ["new", "old", "no-rel"]
|
||||||
|
|
||||||
def test_sort_by_activity(self):
|
def test_sort_by_activity(self):
|
||||||
"""Sorts by last commit date descending; repos without commit last."""
|
"""Sorts by last commit date descending; repos without commit last."""
|
||||||
from gitea_dashboard.display import _sort_repos
|
|
||||||
|
|
||||||
repos = [
|
repos = [
|
||||||
_make_repo(name="inactive", last_commit_date=None),
|
_make_repo(name="inactive", last_commit_date=None),
|
||||||
_make_repo(name="old-commit", last_commit_date="2025-06-01T00:00:00Z"),
|
_make_repo(name="old-commit", last_commit_date="2025-06-01T00:00:00Z"),
|
||||||
_make_repo(name="recent", last_commit_date="2026-03-10T00:00:00Z"),
|
_make_repo(name="recent", last_commit_date="2026-03-10T00:00:00Z"),
|
||||||
]
|
]
|
||||||
result = _sort_repos(repos, "activity")
|
result = sort_repos(repos, "activity")
|
||||||
assert [r.name for r in result] == ["recent", "old-commit", "inactive"]
|
assert [r.name for r in result] == ["recent", "old-commit", "inactive"]
|
||||||
|
|||||||
@@ -2,35 +2,9 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from gitea_dashboard.collector import RepoData
|
|
||||||
from gitea_dashboard.exporter import export_json, repos_to_dicts
|
from gitea_dashboard.exporter import export_json, repos_to_dicts
|
||||||
|
|
||||||
|
from tests.helpers import make_repo as _make_repo
|
||||||
def _make_repo(
|
|
||||||
name="my-repo",
|
|
||||||
full_name="admin/my-repo",
|
|
||||||
description="A repo",
|
|
||||||
open_issues=3,
|
|
||||||
is_fork=False,
|
|
||||||
is_archived=False,
|
|
||||||
is_mirror=False,
|
|
||||||
latest_release=None,
|
|
||||||
milestones=None,
|
|
||||||
last_commit_date=None,
|
|
||||||
):
|
|
||||||
"""Build a RepoData for testing."""
|
|
||||||
return RepoData(
|
|
||||||
name=name,
|
|
||||||
full_name=full_name,
|
|
||||||
description=description,
|
|
||||||
open_issues=open_issues,
|
|
||||||
is_fork=is_fork,
|
|
||||||
is_archived=is_archived,
|
|
||||||
is_mirror=is_mirror,
|
|
||||||
latest_release=latest_release,
|
|
||||||
milestones=milestones if milestones is not None else [],
|
|
||||||
last_commit_date=last_commit_date,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestReposToDicts:
|
class TestReposToDicts:
|
||||||
|
|||||||
Reference in New Issue
Block a user