218 lines
7.6 KiB
Python
218 lines
7.6 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
|
|
import pytest
|
|
from sqlalchemy import select
|
|
|
|
from app.models.lifecycle import LifecycleProject, ProjectStage
|
|
from app.models.organization import Organization
|
|
from app.models.user import User
|
|
|
|
|
|
class TestLifecycleProjectModel:
|
|
|
|
def test_lifecycle_project_table_name(self):
|
|
assert LifecycleProject.__tablename__ == "lifecycle_projects"
|
|
|
|
def test_project_stage_table_name(self):
|
|
assert ProjectStage.__tablename__ == "project_stages"
|
|
|
|
def test_lifecycle_project_has_required_fields(self):
|
|
fields = LifecycleProject.__table__.columns.keys()
|
|
assert "id" in fields
|
|
assert "organization_id" in fields
|
|
assert "brand_name" in fields
|
|
assert "brand_aliases" in fields
|
|
assert "current_stage" in fields
|
|
assert "status" in fields
|
|
assert "created_by" in fields
|
|
assert "created_at" in fields
|
|
assert "updated_at" in fields
|
|
|
|
def test_project_stage_has_required_fields(self):
|
|
fields = ProjectStage.__table__.columns.keys()
|
|
assert "id" in fields
|
|
assert "project_id" in fields
|
|
assert "stage_number" in fields
|
|
assert "status" in fields
|
|
assert "started_at" in fields
|
|
assert "completed_at" in fields
|
|
assert "notes" in fields
|
|
assert "metrics" in fields
|
|
|
|
def test_lifecycle_project_field_types(self):
|
|
columns = LifecycleProject.__table__.columns
|
|
id_type = str(columns["id"].type).upper()
|
|
assert "UUID" in id_type or "CHAR" in id_type
|
|
org_id_type = str(columns["organization_id"].type).upper()
|
|
assert "UUID" in org_id_type or "CHAR" in org_id_type
|
|
brand_name_type = str(columns["brand_name"].type).upper()
|
|
assert "VARCHAR" in brand_name_type or "STRING" in brand_name_type
|
|
assert "INTEGER" in str(columns["current_stage"].type).upper()
|
|
status_type = str(columns["status"].type).upper()
|
|
assert "VARCHAR" in status_type or "STRING" in status_type
|
|
|
|
def test_project_stage_field_types(self):
|
|
columns = ProjectStage.__table__.columns
|
|
id_type = str(columns["id"].type).upper()
|
|
assert "UUID" in id_type or "CHAR" in id_type
|
|
project_id_type = str(columns["project_id"].type).upper()
|
|
assert "UUID" in project_id_type or "CHAR" in project_id_type
|
|
assert "INTEGER" in str(columns["stage_number"].type).upper()
|
|
status_type = str(columns["status"].type).upper()
|
|
assert "VARCHAR" in status_type or "STRING" in status_type
|
|
|
|
def test_lifecycle_project_relationships_defined(self):
|
|
relationships = LifecycleProject.__mapper__.relationships
|
|
rel_keys = relationships.keys()
|
|
assert "stages" in rel_keys
|
|
assert "organization" in rel_keys
|
|
assert "creator" in rel_keys
|
|
|
|
def test_project_stage_relationships_defined(self):
|
|
relationships = ProjectStage.__mapper__.relationships
|
|
rel_keys = relationships.keys()
|
|
assert "project" in rel_keys
|
|
|
|
def test_lifecycle_project_default_stage(self):
|
|
columns = LifecycleProject.__table__.columns
|
|
stage_col = columns["current_stage"]
|
|
assert stage_col.server_default is not None
|
|
|
|
def test_lifecycle_project_default_status(self):
|
|
columns = LifecycleProject.__table__.columns
|
|
status_col = columns["status"]
|
|
assert status_col.server_default is not None
|
|
|
|
def test_project_stage_default_status(self):
|
|
columns = ProjectStage.__table__.columns
|
|
status_col = columns["status"]
|
|
assert status_col.server_default is not None
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_lifecycle_project_create(self, async_session, test_user):
|
|
org = Organization(
|
|
name="Lifecycle Test Org",
|
|
slug="lifecycle-test-org",
|
|
)
|
|
async_session.add(org)
|
|
await async_session.commit()
|
|
await async_session.refresh(org)
|
|
|
|
project = LifecycleProject(
|
|
id=uuid.uuid4(),
|
|
organization_id=org.id,
|
|
brand_name="Test Brand",
|
|
brand_aliases=["TB", "TestBrand"],
|
|
current_stage=1,
|
|
status="active",
|
|
created_by=test_user.id,
|
|
)
|
|
async_session.add(project)
|
|
await async_session.commit()
|
|
await async_session.refresh(project)
|
|
|
|
assert project.id is not None
|
|
assert project.organization_id == org.id
|
|
assert project.brand_name == "Test Brand"
|
|
assert project.brand_aliases == ["TB", "TestBrand"]
|
|
assert project.current_stage == 1
|
|
assert project.status == "active"
|
|
assert project.created_by == test_user.id
|
|
assert project.created_at is not None
|
|
assert project.updated_at is not None
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_lifecycle_project_default_values(self, async_session, test_user):
|
|
org = Organization(
|
|
name="Default Lifecycle Org",
|
|
slug="default-lifecycle-org",
|
|
)
|
|
async_session.add(org)
|
|
await async_session.commit()
|
|
await async_session.refresh(org)
|
|
|
|
project = LifecycleProject(
|
|
organization_id=org.id,
|
|
brand_name="Default Brand",
|
|
created_by=test_user.id,
|
|
)
|
|
async_session.add(project)
|
|
await async_session.commit()
|
|
await async_session.refresh(project)
|
|
|
|
assert project.brand_aliases == []
|
|
assert project.current_stage == 1
|
|
assert project.status == "active"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_project_stage_create(self, async_session, test_user):
|
|
org = Organization(
|
|
name="Stage Test Org",
|
|
slug="stage-test-org",
|
|
)
|
|
async_session.add(org)
|
|
await async_session.commit()
|
|
await async_session.refresh(org)
|
|
|
|
project = LifecycleProject(
|
|
organization_id=org.id,
|
|
brand_name="Stage Test Brand",
|
|
created_by=test_user.id,
|
|
)
|
|
async_session.add(project)
|
|
await async_session.commit()
|
|
await async_session.refresh(project)
|
|
|
|
stage = ProjectStage(
|
|
id=uuid.uuid4(),
|
|
project_id=project.id,
|
|
stage_number=1,
|
|
status="in_progress",
|
|
notes="Starting brand awareness phase",
|
|
metrics={"awareness_score": 45},
|
|
)
|
|
async_session.add(stage)
|
|
await async_session.commit()
|
|
await async_session.refresh(stage)
|
|
|
|
assert stage.id is not None
|
|
assert stage.project_id == project.id
|
|
assert stage.stage_number == 1
|
|
assert stage.status == "in_progress"
|
|
assert stage.notes == "Starting brand awareness phase"
|
|
assert stage.metrics == {"awareness_score": 45}
|
|
assert stage.started_at is None
|
|
assert stage.completed_at is None
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_project_stage_default_values(self, async_session, test_user):
|
|
org = Organization(
|
|
name="Default Stage Org",
|
|
slug="default-stage-org",
|
|
)
|
|
async_session.add(org)
|
|
await async_session.commit()
|
|
await async_session.refresh(org)
|
|
|
|
project = LifecycleProject(
|
|
organization_id=org.id,
|
|
brand_name="Default Stage Brand",
|
|
created_by=test_user.id,
|
|
)
|
|
async_session.add(project)
|
|
await async_session.commit()
|
|
await async_session.refresh(project)
|
|
|
|
stage = ProjectStage(
|
|
project_id=project.id,
|
|
stage_number=2,
|
|
)
|
|
async_session.add(stage)
|
|
await async_session.commit()
|
|
await async_session.refresh(stage)
|
|
|
|
assert stage.status == "pending"
|
|
assert stage.notes is None
|
|
assert stage.metrics is None
|