| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- from collections.abc import Generator
- from contextlib import contextmanager
- from types import SimpleNamespace
- from sqlalchemy import create_engine
- from sqlalchemy.orm import Session, sessionmaker
- from api.auth_middleware import normal_user_can_access
- from api.services import growth_category_tree as service
- from api.services.growth_category_tree import _build_growth_tree
- from supply_infra.db.base import Base
- from supply_infra.db.models.global_category_content_weight import (
- GlobalCategoryContentWeight,
- )
- from supply_infra.db.models.global_v2 import GlobalCategoryV2
- def test_growth_tree_api_is_available_to_normal_users() -> None:
- assert normal_user_can_access("GET", "/api/growth-category-tree")
- def test_build_growth_tree_uses_stable_ids_and_daily_scores() -> None:
- categories = [
- SimpleNamespace(
- stable_id=10,
- parent_stable_id=None,
- level=1,
- name="根分类",
- description="根描述",
- ),
- SimpleNamespace(
- stable_id=11,
- parent_stable_id=10,
- level=2,
- name="子分类",
- description=None,
- ),
- SimpleNamespace(
- stable_id=12,
- parent_stable_id=999,
- level=2,
- name="孤立分类",
- description=None,
- ),
- ]
- weights = [
- SimpleNamespace(
- stable_id=10,
- source_element_count=8,
- read_rate_score=0.3,
- avg_read_rate_score=1.2,
- like_rate_score=0.04,
- ),
- SimpleNamespace(
- stable_id=11,
- source_element_count=0,
- read_rate_score=0.0,
- avg_read_rate_score=0.0,
- like_rate_score=0.0,
- ),
- ]
- nodes = _build_growth_tree(categories, weights)
- assert [node["id"] for node in nodes] == [10, 12]
- root = nodes[0]
- assert root["weights"] == {
- "read_rate": 0.3,
- "avg_read_rate": 1.2,
- "like_rate": 0.04,
- }
- assert root["counts"] == {
- "read_rate": 8,
- "avg_read_rate": 8,
- "like_rate": 8,
- }
- assert root["children"][0]["id"] == 11
- assert root["children"][0]["counts"]["read_rate"] == 0
- assert "hung_word_count" not in root
- def test_build_growth_category_tree_serializes_before_session_closes(monkeypatch) -> None:
- engine = create_engine("sqlite+pysqlite:///:memory:")
- Base.metadata.create_all(
- engine,
- tables=[
- GlobalCategoryV2.__table__,
- GlobalCategoryContentWeight.__table__,
- ],
- )
- factory = sessionmaker(bind=engine, expire_on_commit=True)
- with factory() as session:
- session.add(
- GlobalCategoryV2(
- id=1,
- stable_id=10,
- name="根分类",
- description=None,
- source_type="实质",
- level=1,
- parent_stable_id=None,
- )
- )
- session.add(
- GlobalCategoryContentWeight(
- id=1,
- stable_id=10,
- parent_stable_id=None,
- level=1,
- biz_dt="20260819",
- status="completed",
- source_element_count=5,
- read_rate_score=0.2,
- avg_read_rate_score=1.5,
- like_rate_score=0.03,
- )
- )
- session.commit()
- @contextmanager
- def get_test_session() -> Generator[Session, None, None]:
- session = factory()
- try:
- yield session
- session.commit()
- finally:
- session.close()
- monkeypatch.setattr(service, "get_session", get_test_session)
- payload = service.build_growth_category_tree()
- assert payload["biz_dt"] == "20260819"
- assert payload["nodes"][0]["weights"]["avg_read_rate"] == 1.5
|