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:
@@ -48,7 +48,9 @@ class TestAgentInstanceModel:
|
||||
db_session.add(instance)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(AgentInstance).filter_by(project_id=project.id).first()
|
||||
retrieved = (
|
||||
db_session.query(AgentInstance).filter_by(project_id=project.id).first()
|
||||
)
|
||||
|
||||
assert retrieved is not None
|
||||
assert retrieved.agent_type_id == agent_type.id
|
||||
@@ -92,7 +94,10 @@ class TestAgentInstanceModel:
|
||||
name="Bob",
|
||||
status=AgentStatus.WORKING,
|
||||
current_task="Implementing user authentication",
|
||||
short_term_memory={"context": "Working on auth", "recent_files": ["auth.py"]},
|
||||
short_term_memory={
|
||||
"context": "Working on auth",
|
||||
"recent_files": ["auth.py"],
|
||||
},
|
||||
long_term_memory_ref="project-123/agent-456",
|
||||
session_id="session-abc-123",
|
||||
last_activity_at=now,
|
||||
@@ -107,7 +112,10 @@ class TestAgentInstanceModel:
|
||||
|
||||
assert retrieved.status == AgentStatus.WORKING
|
||||
assert retrieved.current_task == "Implementing user authentication"
|
||||
assert retrieved.short_term_memory == {"context": "Working on auth", "recent_files": ["auth.py"]}
|
||||
assert retrieved.short_term_memory == {
|
||||
"context": "Working on auth",
|
||||
"recent_files": ["auth.py"],
|
||||
}
|
||||
assert retrieved.long_term_memory_ref == "project-123/agent-456"
|
||||
assert retrieved.session_id == "session-abc-123"
|
||||
assert retrieved.tasks_completed == 5
|
||||
@@ -116,7 +124,9 @@ class TestAgentInstanceModel:
|
||||
|
||||
def test_agent_instance_timestamps(self, db_session):
|
||||
"""Test that timestamps are automatically set."""
|
||||
project = Project(id=uuid.uuid4(), name="Timestamp Project", slug="timestamp-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Timestamp Project", slug="timestamp-project-ai"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Timestamp Agent",
|
||||
@@ -176,7 +186,9 @@ class TestAgentInstanceStatus:
|
||||
|
||||
def test_all_agent_statuses(self, db_session):
|
||||
"""Test that all agent statuses can be stored."""
|
||||
project = Project(id=uuid.uuid4(), name="Status Project", slug="status-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Status Project", slug="status-project-ai"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Status Agent",
|
||||
@@ -199,12 +211,18 @@ class TestAgentInstanceStatus:
|
||||
db_session.add(instance)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(AgentInstance).filter_by(id=instance.id).first()
|
||||
retrieved = (
|
||||
db_session.query(AgentInstance).filter_by(id=instance.id).first()
|
||||
)
|
||||
assert retrieved.status == status
|
||||
|
||||
def test_status_update(self, db_session):
|
||||
"""Test updating agent instance status."""
|
||||
project = Project(id=uuid.uuid4(), name="Update Status Project", slug="update-status-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(),
|
||||
name="Update Status Project",
|
||||
slug="update-status-project-ai",
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Update Status Agent",
|
||||
@@ -237,7 +255,9 @@ class TestAgentInstanceStatus:
|
||||
|
||||
def test_terminate_agent_instance(self, db_session):
|
||||
"""Test terminating an agent instance."""
|
||||
project = Project(id=uuid.uuid4(), name="Terminate Project", slug="terminate-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Terminate Project", slug="terminate-project-ai"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Terminate Agent",
|
||||
@@ -281,7 +301,9 @@ class TestAgentInstanceMetrics:
|
||||
|
||||
def test_increment_metrics(self, db_session):
|
||||
"""Test incrementing usage metrics."""
|
||||
project = Project(id=uuid.uuid4(), name="Metrics Project", slug="metrics-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Metrics Project", slug="metrics-project-ai"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Metrics Agent",
|
||||
@@ -326,7 +348,9 @@ class TestAgentInstanceMetrics:
|
||||
|
||||
def test_large_token_count(self, db_session):
|
||||
"""Test handling large token counts."""
|
||||
project = Project(id=uuid.uuid4(), name="Large Tokens Project", slug="large-tokens-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Large Tokens Project", slug="large-tokens-project-ai"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Large Tokens Agent",
|
||||
@@ -359,7 +383,9 @@ class TestAgentInstanceShortTermMemory:
|
||||
|
||||
def test_store_complex_memory(self, db_session):
|
||||
"""Test storing complex short-term memory."""
|
||||
project = Project(id=uuid.uuid4(), name="Memory Project", slug="memory-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Memory Project", slug="memory-project-ai"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Memory Agent",
|
||||
@@ -402,7 +428,11 @@ class TestAgentInstanceShortTermMemory:
|
||||
|
||||
def test_update_memory(self, db_session):
|
||||
"""Test updating short-term memory."""
|
||||
project = Project(id=uuid.uuid4(), name="Update Memory Project", slug="update-memory-project-ai")
|
||||
project = Project(
|
||||
id=uuid.uuid4(),
|
||||
name="Update Memory Project",
|
||||
slug="update-memory-project-ai",
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Update Memory Agent",
|
||||
|
||||
@@ -70,7 +70,10 @@ class TestAgentTypeModel:
|
||||
assert retrieved.fallback_models == ["claude-sonnet-4-20250514", "gpt-4o"]
|
||||
assert retrieved.model_params == {"temperature": 0.7, "max_tokens": 4096}
|
||||
assert retrieved.mcp_servers == ["gitea", "file-system", "slack"]
|
||||
assert retrieved.tool_permissions == {"allowed": ["*"], "denied": ["dangerous_tool"]}
|
||||
assert retrieved.tool_permissions == {
|
||||
"allowed": ["*"],
|
||||
"denied": ["dangerous_tool"],
|
||||
}
|
||||
assert retrieved.is_active is True
|
||||
|
||||
def test_agent_type_unique_slug_constraint(self, db_session):
|
||||
@@ -111,7 +114,9 @@ class TestAgentTypeModel:
|
||||
db_session.add(agent_type)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(AgentType).filter_by(slug="timestamp-agent").first()
|
||||
retrieved = (
|
||||
db_session.query(AgentType).filter_by(slug="timestamp-agent").first()
|
||||
)
|
||||
|
||||
assert isinstance(retrieved.created_at, datetime)
|
||||
assert isinstance(retrieved.updated_at, datetime)
|
||||
@@ -252,7 +257,9 @@ class TestAgentTypeJsonFields:
|
||||
db_session.add(agent_type)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(AgentType).filter_by(slug="permissions-agent").first()
|
||||
retrieved = (
|
||||
db_session.query(AgentType).filter_by(slug="permissions-agent").first()
|
||||
)
|
||||
assert retrieved.tool_permissions == tool_permissions
|
||||
assert "file:read" in retrieved.tool_permissions["allowed"]
|
||||
assert retrieved.tool_permissions["limits"]["file:write"]["max_size_mb"] == 10
|
||||
@@ -269,7 +276,9 @@ class TestAgentTypeJsonFields:
|
||||
db_session.add(agent_type)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(AgentType).filter_by(slug="empty-json-agent").first()
|
||||
retrieved = (
|
||||
db_session.query(AgentType).filter_by(slug="empty-json-agent").first()
|
||||
)
|
||||
assert retrieved.expertise == []
|
||||
assert retrieved.fallback_models == []
|
||||
assert retrieved.model_params == {}
|
||||
|
||||
@@ -107,7 +107,11 @@ class TestIssueModel:
|
||||
|
||||
def test_issue_timestamps(self, db_session):
|
||||
"""Test that timestamps are automatically set."""
|
||||
project = Project(id=uuid.uuid4(), name="Timestamp Issue Project", slug="timestamp-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(),
|
||||
name="Timestamp Issue Project",
|
||||
slug="timestamp-issue-project",
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -124,7 +128,9 @@ class TestIssueModel:
|
||||
|
||||
def test_issue_string_representation(self, db_session):
|
||||
"""Test the string representation of an issue."""
|
||||
project = Project(id=uuid.uuid4(), name="Repr Issue Project", slug="repr-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Repr Issue Project", slug="repr-issue-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -147,7 +153,9 @@ class TestIssueStatus:
|
||||
|
||||
def test_all_issue_statuses(self, db_session):
|
||||
"""Test that all issue statuses can be stored."""
|
||||
project = Project(id=uuid.uuid4(), name="Status Issue Project", slug="status-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Status Issue Project", slug="status-issue-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -170,7 +178,11 @@ class TestIssuePriority:
|
||||
|
||||
def test_all_issue_priorities(self, db_session):
|
||||
"""Test that all issue priorities can be stored."""
|
||||
project = Project(id=uuid.uuid4(), name="Priority Issue Project", slug="priority-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(),
|
||||
name="Priority Issue Project",
|
||||
slug="priority-issue-project",
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -193,7 +205,9 @@ class TestIssueSyncStatus:
|
||||
|
||||
def test_all_sync_statuses(self, db_session):
|
||||
"""Test that all sync statuses can be stored."""
|
||||
project = Project(id=uuid.uuid4(), name="Sync Issue Project", slug="sync-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Sync Issue Project", slug="sync-issue-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -218,7 +232,9 @@ class TestIssueLabels:
|
||||
|
||||
def test_store_labels(self, db_session):
|
||||
"""Test storing labels list."""
|
||||
project = Project(id=uuid.uuid4(), name="Labels Issue Project", slug="labels-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Labels Issue Project", slug="labels-issue-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -239,7 +255,9 @@ class TestIssueLabels:
|
||||
|
||||
def test_update_labels(self, db_session):
|
||||
"""Test updating labels."""
|
||||
project = Project(id=uuid.uuid4(), name="Update Labels Project", slug="update-labels-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Update Labels Project", slug="update-labels-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -255,7 +273,9 @@ class TestIssueLabels:
|
||||
issue.labels = ["updated", "new-label"]
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Issue).filter_by(title="Update Labels Issue").first()
|
||||
retrieved = (
|
||||
db_session.query(Issue).filter_by(title="Update Labels Issue").first()
|
||||
)
|
||||
assert "initial" not in retrieved.labels
|
||||
assert "updated" in retrieved.labels
|
||||
|
||||
@@ -265,7 +285,9 @@ class TestIssueAssignment:
|
||||
|
||||
def test_assign_to_agent(self, db_session):
|
||||
"""Test assigning an issue to an agent."""
|
||||
project = Project(id=uuid.uuid4(), name="Agent Assign Project", slug="agent-assign-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Agent Assign Project", slug="agent-assign-project"
|
||||
)
|
||||
agent_type = AgentType(
|
||||
id=uuid.uuid4(),
|
||||
name="Test Agent Type",
|
||||
@@ -295,13 +317,17 @@ class TestIssueAssignment:
|
||||
db_session.add(issue)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Issue).filter_by(title="Agent Assignment Issue").first()
|
||||
retrieved = (
|
||||
db_session.query(Issue).filter_by(title="Agent Assignment Issue").first()
|
||||
)
|
||||
assert retrieved.assigned_agent_id == agent_instance.id
|
||||
assert retrieved.human_assignee is None
|
||||
|
||||
def test_assign_to_human(self, db_session):
|
||||
"""Test assigning an issue to a human."""
|
||||
project = Project(id=uuid.uuid4(), name="Human Assign Project", slug="human-assign-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Human Assign Project", slug="human-assign-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -314,7 +340,9 @@ class TestIssueAssignment:
|
||||
db_session.add(issue)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Issue).filter_by(title="Human Assignment Issue").first()
|
||||
retrieved = (
|
||||
db_session.query(Issue).filter_by(title="Human Assignment Issue").first()
|
||||
)
|
||||
assert retrieved.human_assignee == "developer@example.com"
|
||||
assert retrieved.assigned_agent_id is None
|
||||
|
||||
@@ -324,7 +352,9 @@ class TestIssueSprintAssociation:
|
||||
|
||||
def test_assign_issue_to_sprint(self, db_session):
|
||||
"""Test assigning an issue to a sprint."""
|
||||
project = Project(id=uuid.uuid4(), name="Sprint Assign Project", slug="sprint-assign-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Sprint Assign Project", slug="sprint-assign-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -381,7 +411,9 @@ class TestIssueExternalTracker:
|
||||
db_session.add(issue)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Issue).filter_by(title="Gitea Synced Issue").first()
|
||||
retrieved = (
|
||||
db_session.query(Issue).filter_by(title="Gitea Synced Issue").first()
|
||||
)
|
||||
assert retrieved.external_tracker_type == "gitea"
|
||||
assert retrieved.external_issue_id == "abc123xyz"
|
||||
assert retrieved.external_issue_number == 42
|
||||
@@ -405,7 +437,9 @@ class TestIssueExternalTracker:
|
||||
db_session.add(issue)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Issue).filter_by(title="GitHub Synced Issue").first()
|
||||
retrieved = (
|
||||
db_session.query(Issue).filter_by(title="GitHub Synced Issue").first()
|
||||
)
|
||||
assert retrieved.external_tracker_type == "github"
|
||||
assert retrieved.external_issue_number == 100
|
||||
|
||||
@@ -415,7 +449,9 @@ class TestIssueLifecycle:
|
||||
|
||||
def test_close_issue(self, db_session):
|
||||
"""Test closing an issue."""
|
||||
project = Project(id=uuid.uuid4(), name="Close Issue Project", slug="close-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Close Issue Project", slug="close-issue-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -440,7 +476,9 @@ class TestIssueLifecycle:
|
||||
|
||||
def test_reopen_issue(self, db_session):
|
||||
"""Test reopening a closed issue."""
|
||||
project = Project(id=uuid.uuid4(), name="Reopen Issue Project", slug="reopen-issue-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Reopen Issue Project", slug="reopen-issue-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
|
||||
@@ -100,7 +100,9 @@ class TestProjectModel:
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Project).filter_by(slug="timestamp-project").first()
|
||||
retrieved = (
|
||||
db_session.query(Project).filter_by(slug="timestamp-project").first()
|
||||
)
|
||||
|
||||
assert isinstance(retrieved.created_at, datetime)
|
||||
assert isinstance(retrieved.updated_at, datetime)
|
||||
@@ -177,7 +179,11 @@ class TestProjectEnums:
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Project).filter_by(slug=f"project-{level.value}").first()
|
||||
retrieved = (
|
||||
db_session.query(Project)
|
||||
.filter_by(slug=f"project-{level.value}")
|
||||
.first()
|
||||
)
|
||||
assert retrieved.autonomy_level == level
|
||||
|
||||
def test_all_project_statuses(self, db_session):
|
||||
@@ -192,7 +198,11 @@ class TestProjectEnums:
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Project).filter_by(slug=f"project-status-{status.value}").first()
|
||||
retrieved = (
|
||||
db_session.query(Project)
|
||||
.filter_by(slug=f"project-status-{status.value}")
|
||||
.first()
|
||||
)
|
||||
assert retrieved.status == status
|
||||
|
||||
|
||||
@@ -227,7 +237,10 @@ class TestProjectSettings:
|
||||
|
||||
assert retrieved.settings == complex_settings
|
||||
assert retrieved.settings["mcp_servers"] == ["gitea", "slack", "file-system"]
|
||||
assert retrieved.settings["webhook_urls"]["on_issue_created"] == "https://example.com/issue"
|
||||
assert (
|
||||
retrieved.settings["webhook_urls"]["on_issue_created"]
|
||||
== "https://example.com/issue"
|
||||
)
|
||||
assert "important" in retrieved.settings["tags"]
|
||||
|
||||
def test_empty_settings(self, db_session):
|
||||
|
||||
@@ -91,7 +91,11 @@ class TestSprintModel:
|
||||
|
||||
def test_sprint_timestamps(self, db_session):
|
||||
"""Test that timestamps are automatically set."""
|
||||
project = Project(id=uuid.uuid4(), name="Timestamp Sprint Project", slug="timestamp-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(),
|
||||
name="Timestamp Sprint Project",
|
||||
slug="timestamp-sprint-project",
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -112,7 +116,9 @@ class TestSprintModel:
|
||||
|
||||
def test_sprint_string_representation(self, db_session):
|
||||
"""Test the string representation of a sprint."""
|
||||
project = Project(id=uuid.uuid4(), name="Repr Sprint Project", slug="repr-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Repr Sprint Project", slug="repr-sprint-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -139,7 +145,9 @@ class TestSprintStatus:
|
||||
|
||||
def test_all_sprint_statuses(self, db_session):
|
||||
"""Test that all sprint statuses can be stored."""
|
||||
project = Project(id=uuid.uuid4(), name="Status Sprint Project", slug="status-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Status Sprint Project", slug="status-sprint-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -166,7 +174,9 @@ class TestSprintLifecycle:
|
||||
|
||||
def test_start_sprint(self, db_session):
|
||||
"""Test starting a planned sprint."""
|
||||
project = Project(id=uuid.uuid4(), name="Start Sprint Project", slug="start-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Start Sprint Project", slug="start-sprint-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -194,7 +204,11 @@ class TestSprintLifecycle:
|
||||
|
||||
def test_complete_sprint(self, db_session):
|
||||
"""Test completing an active sprint."""
|
||||
project = Project(id=uuid.uuid4(), name="Complete Sprint Project", slug="complete-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(),
|
||||
name="Complete Sprint Project",
|
||||
slug="complete-sprint-project",
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -217,13 +231,17 @@ class TestSprintLifecycle:
|
||||
sprint.velocity = 18
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Sprint).filter_by(name="Sprint to Complete").first()
|
||||
retrieved = (
|
||||
db_session.query(Sprint).filter_by(name="Sprint to Complete").first()
|
||||
)
|
||||
assert retrieved.status == SprintStatus.COMPLETED
|
||||
assert retrieved.velocity == 18
|
||||
|
||||
def test_cancel_sprint(self, db_session):
|
||||
"""Test cancelling a sprint."""
|
||||
project = Project(id=uuid.uuid4(), name="Cancel Sprint Project", slug="cancel-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Cancel Sprint Project", slug="cancel-sprint-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -254,7 +272,9 @@ class TestSprintDates:
|
||||
|
||||
def test_sprint_date_range(self, db_session):
|
||||
"""Test storing sprint date range."""
|
||||
project = Project(id=uuid.uuid4(), name="Date Range Project", slug="date-range-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Date Range Project", slug="date-range-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -278,7 +298,9 @@ class TestSprintDates:
|
||||
|
||||
def test_one_day_sprint(self, db_session):
|
||||
"""Test creating a one-day sprint."""
|
||||
project = Project(id=uuid.uuid4(), name="One Day Project", slug="one-day-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="One Day Project", slug="one-day-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -299,7 +321,9 @@ class TestSprintDates:
|
||||
|
||||
def test_long_sprint(self, db_session):
|
||||
"""Test creating a long sprint (e.g., 4 weeks)."""
|
||||
project = Project(id=uuid.uuid4(), name="Long Sprint Project", slug="long-sprint-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Long Sprint Project", slug="long-sprint-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -325,7 +349,9 @@ class TestSprintPoints:
|
||||
|
||||
def test_sprint_with_zero_points(self, db_session):
|
||||
"""Test sprint with zero planned points."""
|
||||
project = Project(id=uuid.uuid4(), name="Zero Points Project", slug="zero-points-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Zero Points Project", slug="zero-points-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -343,13 +369,17 @@ class TestSprintPoints:
|
||||
db_session.add(sprint)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Sprint).filter_by(name="Zero Points Sprint").first()
|
||||
retrieved = (
|
||||
db_session.query(Sprint).filter_by(name="Zero Points Sprint").first()
|
||||
)
|
||||
assert retrieved.planned_points == 0
|
||||
assert retrieved.velocity == 0
|
||||
|
||||
def test_sprint_velocity_calculation(self, db_session):
|
||||
"""Test that we can calculate velocity from points."""
|
||||
project = Project(id=uuid.uuid4(), name="Velocity Project", slug="velocity-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Velocity Project", slug="velocity-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -376,7 +406,9 @@ class TestSprintPoints:
|
||||
|
||||
def test_sprint_overdelivery(self, db_session):
|
||||
"""Test sprint where completed > planned (stretch goals)."""
|
||||
project = Project(id=uuid.uuid4(), name="Overdelivery Project", slug="overdelivery-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Overdelivery Project", slug="overdelivery-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -395,7 +427,9 @@ class TestSprintPoints:
|
||||
db_session.add(sprint)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Sprint).filter_by(name="Overdelivery Sprint").first()
|
||||
retrieved = (
|
||||
db_session.query(Sprint).filter_by(name="Overdelivery Sprint").first()
|
||||
)
|
||||
assert retrieved.velocity > retrieved.planned_points
|
||||
|
||||
|
||||
@@ -404,7 +438,9 @@ class TestSprintNumber:
|
||||
|
||||
def test_sequential_sprint_numbers(self, db_session):
|
||||
"""Test creating sprints with sequential numbers."""
|
||||
project = Project(id=uuid.uuid4(), name="Sequential Project", slug="sequential-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Sequential Project", slug="sequential-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -421,14 +457,21 @@ class TestSprintNumber:
|
||||
db_session.add(sprint)
|
||||
db_session.commit()
|
||||
|
||||
sprints = db_session.query(Sprint).filter_by(project_id=project.id).order_by(Sprint.number).all()
|
||||
sprints = (
|
||||
db_session.query(Sprint)
|
||||
.filter_by(project_id=project.id)
|
||||
.order_by(Sprint.number)
|
||||
.all()
|
||||
)
|
||||
assert len(sprints) == 5
|
||||
for i, sprint in enumerate(sprints, 1):
|
||||
assert sprint.number == i
|
||||
|
||||
def test_large_sprint_number(self, db_session):
|
||||
"""Test sprint with large number (e.g., long-running project)."""
|
||||
project = Project(id=uuid.uuid4(), name="Large Number Project", slug="large-number-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Large Number Project", slug="large-number-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -453,7 +496,9 @@ class TestSprintUpdate:
|
||||
|
||||
def test_update_sprint_goal(self, db_session):
|
||||
"""Test updating sprint goal."""
|
||||
project = Project(id=uuid.uuid4(), name="Update Goal Project", slug="update-goal-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Update Goal Project", slug="update-goal-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -475,14 +520,18 @@ class TestSprintUpdate:
|
||||
sprint.goal = "Updated goal with more detail"
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Sprint).filter_by(name="Update Goal Sprint").first()
|
||||
retrieved = (
|
||||
db_session.query(Sprint).filter_by(name="Update Goal Sprint").first()
|
||||
)
|
||||
assert retrieved.goal == "Updated goal with more detail"
|
||||
assert retrieved.created_at == original_created_at
|
||||
assert retrieved.updated_at > original_created_at
|
||||
|
||||
def test_update_sprint_dates(self, db_session):
|
||||
"""Test updating sprint dates."""
|
||||
project = Project(id=uuid.uuid4(), name="Update Dates Project", slug="update-dates-project")
|
||||
project = Project(
|
||||
id=uuid.uuid4(), name="Update Dates Project", slug="update-dates-project"
|
||||
)
|
||||
db_session.add(project)
|
||||
db_session.commit()
|
||||
|
||||
@@ -502,6 +551,8 @@ class TestSprintUpdate:
|
||||
sprint.end_date = today + timedelta(days=21)
|
||||
db_session.commit()
|
||||
|
||||
retrieved = db_session.query(Sprint).filter_by(name="Update Dates Sprint").first()
|
||||
retrieved = (
|
||||
db_session.query(Sprint).filter_by(name="Update Dates Sprint").first()
|
||||
)
|
||||
delta = retrieved.end_date - retrieved.start_date
|
||||
assert delta.days == 21
|
||||
|
||||
Reference in New Issue
Block a user