test(backend): add comprehensive tests for OAuth and agent endpoints

- Added tests for OAuth provider admin and consent endpoints covering edge cases.
- Extended agent-related tests to handle incorrect project associations and lifecycle state transitions.
- Introduced tests for sprint status transitions and validation checks.
- Improved multiline formatting consistency across all test functions.
This commit is contained in:
2026-01-03 01:44:11 +01:00
parent acd18ff694
commit 664415111a
28 changed files with 1530 additions and 216 deletions

View File

@@ -74,7 +74,9 @@ async def terminated_agent(client, user_token, test_project, test_agent):
f"/api/v1/projects/{test_project['id']}/agents/{test_agent['id']}",
headers={"Authorization": f"Bearer {user_token}"},
)
assert response.status_code == status.HTTP_200_OK, f"Failed to terminate: {response.json()}"
assert response.status_code == status.HTTP_200_OK, (
f"Failed to terminate: {response.json()}"
)
# Return agent info with terminated status
return {**test_agent, "status": "terminated"}
@@ -432,7 +434,7 @@ class TestProjectArchivingEdgeCases:
agent_id = test_agent["id"]
# Set agent to working status
status_response = await client.patch(
await client.patch(
f"/api/v1/projects/{project_id}/agents/{agent_id}/status",
json={"status": "working", "current_task": "Processing something"},
headers={"Authorization": f"Bearer {user_token}"},
@@ -475,7 +477,6 @@ class TestConcurrencyEdgeCases:
If two requests try to start sprints simultaneously, only one should succeed.
"""
import asyncio
from datetime import date, timedelta
project_id = test_project["id"]
@@ -509,7 +510,9 @@ class TestConcurrencyEdgeCases:
)
# Exactly one should succeed
successes = sum(1 for r in [start1, start2] if r.status_code == status.HTTP_200_OK)
successes = sum(
1 for r in [start1, start2] if r.status_code == status.HTTP_200_OK
)
failures = sum(1 for r in [start1, start2] if r.status_code in [400, 409, 422])
assert successes == 1, f"Expected exactly 1 success, got {successes}"
@@ -593,9 +596,7 @@ class TestDataIntegrityEdgeCases:
assert update_response.status_code == status.HTTP_404_NOT_FOUND
async def test_assign_issue_to_other_projects_sprint(
self, client, user_token
):
async def test_assign_issue_to_other_projects_sprint(self, client, user_token):
"""
IDOR Test: Try to assign an issue to a sprint from a different project.
"""
@@ -624,6 +625,7 @@ class TestDataIntegrityEdgeCases:
# Create a sprint in project 2
from datetime import date, timedelta
sprint_response = await client.post(
f"/api/v1/projects/{p2['id']}/sprints",
json={
@@ -662,7 +664,9 @@ class TestDataIntegrityEdgeCases:
status.HTTP_400_BAD_REQUEST,
status.HTTP_404_NOT_FOUND,
status.HTTP_422_UNPROCESSABLE_ENTITY,
], f"IDOR BUG: Assigned issue to another project's sprint! Status: {update_response.status_code}"
], (
f"IDOR BUG: Assigned issue to another project's sprint! Status: {update_response.status_code}"
)
async def test_assign_issue_to_other_projects_agent(
self, client, user_token, superuser_token
@@ -744,7 +748,9 @@ class TestDataIntegrityEdgeCases:
status.HTTP_400_BAD_REQUEST,
status.HTTP_404_NOT_FOUND,
status.HTTP_422_UNPROCESSABLE_ENTITY,
], f"IDOR BUG: Assigned issue to another project's agent! Status: {update_response.status_code}"
], (
f"IDOR BUG: Assigned issue to another project's agent! Status: {update_response.status_code}"
)
@pytest.mark.asyncio
@@ -1084,6 +1090,6 @@ class TestArchiveProjectCleanup:
# BUG CHECK: Sprint should be cancelled after project archive
if sprint_data.get("status") == "active":
pytest.fail(
f"BUG: Sprint status is still 'active' after project archive. "
f"Expected 'cancelled'. Archive should cancel active sprints."
"BUG: Sprint status is still 'active' after project archive. "
"Expected 'cancelled'. Archive should cancel active sprints."
)