import uuid from datetime import datetime import pytest from sqlalchemy import select from app.models.brand import Brand from app.models.suggestion import Suggestion from app.models.user import User from tests.fixtures.auth import _to_uuid class TestSuggestionModel: def test_suggestion_table_name(self): assert Suggestion.__tablename__ == "suggestions" def test_suggestion_has_required_fields(self): fields = Suggestion.__table__.columns.keys() assert "id" in fields assert "brand_id" in fields assert "type" in fields assert "priority" in fields assert "title" in fields assert "description" in fields assert "action" in fields assert "expected_impact" in fields assert "difficulty" in fields assert "status" in fields assert "generated_at" in fields assert "updated_at" in fields assert "batch_id" in fields assert "source" in fields def test_suggestion_field_types(self): columns = Suggestion.__table__.columns id_type = str(columns["id"].type).upper() assert "UUID" in id_type or "CHAR" in id_type brand_id_type = str(columns["brand_id"].type).upper() assert "UUID" in brand_id_type or "CHAR" in brand_id_type type_type = str(columns["type"].type).upper() assert "VARCHAR" in type_type or "STRING" in type_type priority_type = str(columns["priority"].type).upper() assert "VARCHAR" in priority_type or "STRING" in priority_type title_type = str(columns["title"].type).upper() assert "VARCHAR" in title_type or "STRING" in title_type assert "TEXT" in str(columns["description"].type).upper() difficulty_type = str(columns["difficulty"].type).upper() assert "VARCHAR" in difficulty_type or "STRING" in difficulty_type status_type = str(columns["status"].type).upper() assert "VARCHAR" in status_type or "STRING" in status_type def test_suggestion_relationships_defined(self): relationships = Suggestion.__mapper__.relationships rel_keys = relationships.keys() assert "brand" in rel_keys def test_suggestion_priority_default(self): columns = Suggestion.__table__.columns priority_col = columns["priority"] assert priority_col.default is not None assert priority_col.default.arg == "medium" def test_suggestion_status_default(self): columns = Suggestion.__table__.columns status_col = columns["status"] assert status_col.default is not None assert status_col.default.arg == "pending" def test_suggestion_difficulty_default(self): columns = Suggestion.__table__.columns difficulty_col = columns["difficulty"] assert difficulty_col.default is not None assert difficulty_col.default.arg == "medium" def test_suggestion_source_default(self): columns = Suggestion.__table__.columns source_col = columns["source"] assert source_col.default is not None assert source_col.default.arg == "rule" @pytest.mark.asyncio async def test_suggestion_create(self, async_session, test_user): brand = Brand( user_id=_to_uuid(test_user.id), name="Suggestion Test Brand", platforms=["wenxin"], ) async_session.add(brand) await async_session.commit() await async_session.refresh(brand) suggestion = Suggestion( id=uuid.uuid4(), brand_id=brand.id, type="content_optimization", priority="high", title="Optimize content structure", description="Improve heading hierarchy for better AI citation", action="Restructure headings using H2/H3 hierarchy", expected_impact="20% increase in citation rate", difficulty="easy", status="pending", source="rule", ) async_session.add(suggestion) await async_session.commit() await async_session.refresh(suggestion) assert suggestion.id is not None assert suggestion.brand_id == brand.id assert suggestion.type == "content_optimization" assert suggestion.priority == "high" assert suggestion.title == "Optimize content structure" assert suggestion.description == "Improve heading hierarchy for better AI citation" assert suggestion.action == "Restructure headings using H2/H3 hierarchy" assert suggestion.expected_impact == "20% increase in citation rate" assert suggestion.difficulty == "easy" assert suggestion.status == "pending" assert suggestion.source == "rule" assert suggestion.generated_at is not None assert suggestion.updated_at is not None assert suggestion.batch_id is not None @pytest.mark.asyncio async def test_suggestion_default_values(self, async_session, test_user): brand = Brand( user_id=_to_uuid(test_user.id), name="Default Suggestion Brand", platforms=["kimi"], ) async_session.add(brand) await async_session.commit() await async_session.refresh(brand) suggestion = Suggestion( brand_id=brand.id, type="competitor_gap", title="Fill competitor gap", description="Address missing topics that competitors cover", ) async_session.add(suggestion) await async_session.commit() await async_session.refresh(suggestion) assert suggestion.priority == "medium" assert suggestion.difficulty == "medium" assert suggestion.status == "pending" assert suggestion.source == "rule" assert suggestion.action is None assert suggestion.expected_impact is None @pytest.mark.asyncio async def test_suggestion_query_by_brand(self, async_session, test_user): brand = Brand( user_id=_to_uuid(test_user.id), name="Query Suggestion Brand", platforms=["wenxin"], ) async_session.add(brand) await async_session.commit() await async_session.refresh(brand) s1 = Suggestion( brand_id=brand.id, type="content_optimization", title="Suggestion 1", description="Desc 1", ) s2 = Suggestion( brand_id=brand.id, type="platform_targeting", title="Suggestion 2", description="Desc 2", ) async_session.add(s1) async_session.add(s2) await async_session.commit() result = await async_session.execute( select(Suggestion).where(Suggestion.brand_id == brand.id) ) suggestions = result.scalars().all() assert len(suggestions) == 2