This commit is contained in:
parent
51706d2d11
commit
853e99ca5f
21 changed files with 1402 additions and 77 deletions
|
|
@ -167,7 +167,7 @@ class AppTestCase(unittest.TestCase):
|
|||
fake_client = _FakeForgejoClient(user={"login": "kacper"})
|
||||
with (
|
||||
patch("prototype_cache.build_live_prototype_payload", new=builder),
|
||||
patch("app.ForgejoClient", return_value=fake_client),
|
||||
patch("app.ForgejoClient", return_value=fake_client) as client_factory,
|
||||
):
|
||||
response = self.client.get(
|
||||
"/api/prototype",
|
||||
|
|
@ -181,6 +181,38 @@ class AppTestCase(unittest.TestCase):
|
|||
self.assertEqual(response_payload["auth"]["authenticated"], True)
|
||||
self.assertEqual(response_payload["auth"]["login"], "kacper")
|
||||
self.assertEqual(response_payload["auth"]["source"], "authorization")
|
||||
self.assertEqual(client_factory.call_args.kwargs["auth_scheme"], "token")
|
||||
|
||||
def test_prototype_preserves_bearer_authorization_scheme(self) -> None:
|
||||
payload = {
|
||||
"hero": {"title": "Robot U"},
|
||||
"auth": {
|
||||
"authenticated": False,
|
||||
"login": None,
|
||||
"source": "none",
|
||||
"can_reply": False,
|
||||
"oauth_configured": True,
|
||||
},
|
||||
"featured_courses": [],
|
||||
"recent_posts": [],
|
||||
"recent_discussions": [],
|
||||
"upcoming_events": [],
|
||||
"source_of_truth": [],
|
||||
}
|
||||
builder = AsyncMock(return_value=payload)
|
||||
fake_client = _FakeForgejoClient(user={"login": "kacper"})
|
||||
with (
|
||||
patch("prototype_cache.build_live_prototype_payload", new=builder),
|
||||
patch("app.ForgejoClient", return_value=fake_client) as client_factory,
|
||||
):
|
||||
response = self.client.get(
|
||||
"/api/prototype",
|
||||
headers={"Authorization": "Bearer oauth-token"},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(client_factory.call_args.kwargs["forgejo_token"], "oauth-token")
|
||||
self.assertEqual(client_factory.call_args.kwargs["auth_scheme"], "Bearer")
|
||||
|
||||
def test_prototype_can_use_server_token_without_user_session(self) -> None:
|
||||
payload = {
|
||||
|
|
@ -378,7 +410,7 @@ class AppTestCase(unittest.TestCase):
|
|||
"updated_at": "2026-04-11T12:00:00Z",
|
||||
"html_url": "https://aksal.cloud/Robot-U/robot-u-site/issues/9",
|
||||
"user": {"login": "Kacper", "avatar_url": ""},
|
||||
"labels": [],
|
||||
"labels": [{"name": "discussion"}],
|
||||
"state": "open",
|
||||
},
|
||||
comments=[
|
||||
|
|
@ -400,6 +432,26 @@ class AppTestCase(unittest.TestCase):
|
|||
self.assertEqual(payload["comments"][0]["body"], "Reply body")
|
||||
self.assertEqual(payload["links"][0]["kind"], "post")
|
||||
|
||||
def test_discussion_detail_rejects_issue_without_discussion_label(self) -> None:
|
||||
fake_client = _FakeForgejoClient(
|
||||
issue={
|
||||
"id": 456,
|
||||
"number": 9,
|
||||
"title": "Encoder math question",
|
||||
"body": "Regular issue",
|
||||
"comments": 0,
|
||||
"updated_at": "2026-04-11T12:00:00Z",
|
||||
"html_url": "https://aksal.cloud/Robot-U/robot-u-site/issues/9",
|
||||
"user": {"login": "Kacper", "avatar_url": ""},
|
||||
"labels": [],
|
||||
"state": "open",
|
||||
},
|
||||
)
|
||||
with patch("app.ForgejoClient", return_value=fake_client):
|
||||
response = self.client.get("/api/discussions/Robot-U/robot-u-site/9")
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_create_discussion_reply_invalidates_prototype_cache(self) -> None:
|
||||
initial_payload = {
|
||||
"hero": {"title": "Before"},
|
||||
|
|
@ -496,6 +548,7 @@ class AppTestCase(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(payload["id"], 456)
|
||||
self.assertEqual(payload["repo"], "Robot-U/robot-u-site")
|
||||
self.assertEqual(payload["labels"], ["discussion"])
|
||||
self.assertEqual(payload["links"][0]["kind"], "post")
|
||||
|
||||
def test_create_general_discussion_uses_configured_repo(self) -> None:
|
||||
|
|
@ -532,6 +585,7 @@ class AppTestCase(unittest.TestCase):
|
|||
fake_client.created_issue,
|
||||
("Robot-U", "community", "General project help", "I need help choosing motors."),
|
||||
)
|
||||
self.assertEqual(fake_client.created_issue_labels, [123])
|
||||
|
||||
def test_create_discussion_rejects_server_token_fallback(self) -> None:
|
||||
get_settings.cache_clear()
|
||||
|
|
@ -583,6 +637,7 @@ class AppTestCase(unittest.TestCase):
|
|||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(client_factory.call_args.kwargs["forgejo_token"], "oauth-token")
|
||||
self.assertEqual(client_factory.call_args.kwargs["auth_scheme"], "Bearer")
|
||||
self.assertEqual(
|
||||
reply_client.created_comment, ("Robot-U", "RobotClass", 2, "Thanks, this helped.")
|
||||
)
|
||||
|
|
@ -638,6 +693,7 @@ class _FakeForgejoClient:
|
|||
self._repo_private = repo_private
|
||||
self.created_comment: tuple[str, str, int, str] | None = None
|
||||
self.created_issue: tuple[str, str, str, str] | None = None
|
||||
self.created_issue_labels: list[int] | None = None
|
||||
self.exchanged_code: str | None = None
|
||||
|
||||
async def __aenter__(self) -> _FakeForgejoClient:
|
||||
|
|
@ -664,12 +720,27 @@ class _FakeForgejoClient:
|
|||
repo: str,
|
||||
title: str,
|
||||
body: str,
|
||||
label_ids: list[int] | None = None,
|
||||
) -> dict[str, object]:
|
||||
self.created_issue = (owner, repo, title, body)
|
||||
self.created_issue_labels = label_ids
|
||||
if self._issue is None:
|
||||
raise AssertionError("Fake issue was not configured.")
|
||||
return self._issue
|
||||
|
||||
async def ensure_repo_label(
|
||||
self,
|
||||
_owner: str,
|
||||
_repo: str,
|
||||
_name: str,
|
||||
*,
|
||||
color: str,
|
||||
description: str,
|
||||
) -> int:
|
||||
assert color
|
||||
assert description
|
||||
return 123
|
||||
|
||||
async def fetch_issue(self, _owner: str, _repo: str, _issue_number: int) -> dict[str, object]:
|
||||
if self._issue is None:
|
||||
raise AssertionError("Fake issue was not configured.")
|
||||
|
|
|
|||
|
|
@ -3,7 +3,13 @@ from __future__ import annotations
|
|||
import unittest
|
||||
from typing import Any
|
||||
|
||||
from live_prototype import _post_card, _summarize_repo, discussion_links_from_text
|
||||
from live_prototype import (
|
||||
_post_card,
|
||||
_summarize_repo,
|
||||
discussion_card_from_issue,
|
||||
discussion_links_from_text,
|
||||
issue_has_discussion_label,
|
||||
)
|
||||
|
||||
|
||||
class LivePrototypeTestCase(unittest.IsolatedAsyncioTestCase):
|
||||
|
|
@ -16,7 +22,10 @@ class LivePrototypeTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
"full_name": "Robot-U/robot-u-site",
|
||||
"description": "Robot U site source",
|
||||
"updated_at": "2026-04-13T00:00:00Z",
|
||||
"owner": {"login": "Robot-U"},
|
||||
"owner": {
|
||||
"login": "Robot-U",
|
||||
"avatar_url": "https://aksal.cloud/avatars/robot-u.png",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -25,6 +34,7 @@ class LivePrototypeTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
self.assertEqual(summary["blog_count"], 1)
|
||||
post = _post_card(summary["blog_posts"][0])
|
||||
self.assertEqual(post["title"], "Building Robot U")
|
||||
self.assertEqual(post["owner_avatar_url"], "https://aksal.cloud/avatars/robot-u.png")
|
||||
self.assertEqual(post["slug"], "building-robot-u-site")
|
||||
self.assertEqual(post["repo"], "Robot-U/robot-u-site")
|
||||
self.assertEqual(post["path"], "blogs/building-robot-u-site")
|
||||
|
|
@ -49,6 +59,29 @@ class LivePrototypeTestCase(unittest.IsolatedAsyncioTestCase):
|
|||
self.assertEqual(links[1]["kind"], "post")
|
||||
self.assertEqual(links[1]["path"], "/posts/Robot-U/robot-u-site/building-robot-u-site")
|
||||
|
||||
def test_discussion_card_exposes_created_at(self) -> None:
|
||||
card = discussion_card_from_issue(
|
||||
{
|
||||
"id": 42,
|
||||
"number": 7,
|
||||
"title": "Encoder count issue",
|
||||
"body": "The count jumps when the motor turns.",
|
||||
"comments": 3,
|
||||
"created_at": "2026-04-12T10:00:00Z",
|
||||
"updated_at": "2026-04-13T10:00:00Z",
|
||||
"repository": {"full_name": "Robot-U/general_forum"},
|
||||
"user": {"login": "kacper", "avatar_url": "https://aksal.cloud/avatar.png"},
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(card["created_at"], "2026-04-12T10:00:00Z")
|
||||
|
||||
def test_discussion_label_detection_is_case_insensitive(self) -> None:
|
||||
self.assertTrue(
|
||||
issue_has_discussion_label({"labels": [{"name": "Discussion"}, {"name": "bug"}]})
|
||||
)
|
||||
self.assertFalse(issue_has_discussion_label({"labels": [{"name": "question"}]}))
|
||||
|
||||
|
||||
class _FakeContentClient:
|
||||
async def list_directory(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue