feat: enhance task management with due date handling and mention support
This commit is contained in:
@@ -14,6 +14,7 @@ from app.core.error_handling import (
|
||||
_error_payload,
|
||||
_get_request_id,
|
||||
_http_exception_exception_handler,
|
||||
_json_safe,
|
||||
_request_validation_exception_handler,
|
||||
_response_validation_exception_handler,
|
||||
install_error_handling,
|
||||
@@ -209,6 +210,20 @@ def test_error_payload_omits_request_id_when_none() -> None:
|
||||
assert _error_payload(detail="x", request_id=None) == {"detail": "x"}
|
||||
|
||||
|
||||
def test_json_safe_handles_binary_inputs() -> None:
|
||||
assert _json_safe(b"\xf0\x9f\x92\xa1") == "💡"
|
||||
assert _json_safe(bytearray(b"hello")) == "hello"
|
||||
assert _json_safe(memoryview(b"world")) == "world"
|
||||
|
||||
|
||||
def test_json_safe_falls_back_to_string_for_unknown_objects() -> None:
|
||||
class Weird:
|
||||
def __str__(self) -> str:
|
||||
return "weird-value"
|
||||
|
||||
assert _json_safe(Weird()) == "weird-value"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_request_validation_exception_wrapper_rejects_wrong_exception() -> None:
|
||||
req = Request({"type": "http", "headers": [], "state": {}})
|
||||
|
||||
128
backend/tests/test_metrics_filters.py
Normal file
128
backend/tests/test_metrics_filters.py
Normal file
@@ -0,0 +1,128 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from app.api import metrics as metrics_api
|
||||
|
||||
|
||||
class _FakeSession:
|
||||
def __init__(self, exec_result: list[object]) -> None:
|
||||
self._exec_result = exec_result
|
||||
|
||||
async def exec(self, _statement: object) -> list[object]:
|
||||
return self._exec_result
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_dashboard_board_ids_returns_requested_board(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
board_id = uuid4()
|
||||
|
||||
async def _accessible(*_args: object, **_kwargs: object) -> list[object]:
|
||||
return [board_id]
|
||||
|
||||
monkeypatch.setattr(
|
||||
metrics_api,
|
||||
"list_accessible_board_ids",
|
||||
_accessible,
|
||||
)
|
||||
ctx = SimpleNamespace(member=SimpleNamespace(organization_id=uuid4()))
|
||||
|
||||
resolved = await metrics_api._resolve_dashboard_board_ids(
|
||||
_FakeSession([]),
|
||||
ctx=ctx,
|
||||
board_id=board_id,
|
||||
group_id=None,
|
||||
)
|
||||
|
||||
assert resolved == [board_id]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_dashboard_board_ids_rejects_inaccessible_board(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
accessible_board_id = uuid4()
|
||||
requested_board_id = uuid4()
|
||||
|
||||
async def _accessible(*_args: object, **_kwargs: object) -> list[object]:
|
||||
return [accessible_board_id]
|
||||
|
||||
monkeypatch.setattr(
|
||||
metrics_api,
|
||||
"list_accessible_board_ids",
|
||||
_accessible,
|
||||
)
|
||||
ctx = SimpleNamespace(member=SimpleNamespace(organization_id=uuid4()))
|
||||
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
await metrics_api._resolve_dashboard_board_ids(
|
||||
_FakeSession([]),
|
||||
ctx=ctx,
|
||||
board_id=requested_board_id,
|
||||
group_id=None,
|
||||
)
|
||||
|
||||
assert exc_info.value.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_dashboard_board_ids_filters_by_group(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
board_a = uuid4()
|
||||
board_b = uuid4()
|
||||
group_id = uuid4()
|
||||
|
||||
async def _accessible(*_args: object, **_kwargs: object) -> list[object]:
|
||||
return [board_a, board_b]
|
||||
|
||||
monkeypatch.setattr(
|
||||
metrics_api,
|
||||
"list_accessible_board_ids",
|
||||
_accessible,
|
||||
)
|
||||
ctx = SimpleNamespace(member=SimpleNamespace(organization_id=uuid4()))
|
||||
session = _FakeSession([board_b])
|
||||
|
||||
resolved = await metrics_api._resolve_dashboard_board_ids(
|
||||
session,
|
||||
ctx=ctx,
|
||||
board_id=None,
|
||||
group_id=group_id,
|
||||
)
|
||||
|
||||
assert resolved == [board_b]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_dashboard_board_ids_returns_empty_when_board_not_in_group(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
board_id = uuid4()
|
||||
group_id = uuid4()
|
||||
|
||||
async def _accessible(*_args: object, **_kwargs: object) -> list[object]:
|
||||
return [board_id]
|
||||
|
||||
monkeypatch.setattr(
|
||||
metrics_api,
|
||||
"list_accessible_board_ids",
|
||||
_accessible,
|
||||
)
|
||||
ctx = SimpleNamespace(member=SimpleNamespace(organization_id=uuid4()))
|
||||
session = _FakeSession([])
|
||||
|
||||
resolved = await metrics_api._resolve_dashboard_board_ids(
|
||||
session,
|
||||
ctx=ctx,
|
||||
board_id=board_id,
|
||||
group_id=group_id,
|
||||
)
|
||||
|
||||
assert resolved == []
|
||||
Reference in New Issue
Block a user