ViralVelocity-api / tests /test_models.py
Rolaficus's picture
fixed backend requirement inconsisetency
64e01cf
Raw History Blame Contribute Delete
3.95 kB
from unittest.mock import patch
import pytest
from app.models import (
AnomalyDetector,
ClickbaitDetector,
GenreClassifier,
TagRecommender,
VelocityPredictor,
ViralTrendPredictor,
)
from app.schemas import (
AnomalyInput,
ClickbaitInput,
GenreInput,
TagInput,
VelocityInput,
ViralInput,
)
# --- Fixtures for reusable input data ---
@pytest.fixture
def velocity_input():
return VelocityInput(
log_start_views=6.9,
log_duration=5.7,
initial_virality_slope=1.2,
interaction_density=0.1,
like_view_ratio=0.05,
comment_view_ratio=0.01,
video_age_hours=2.0,
hour_sin=0.5,
hour_cos=-0.8,
publish_day=1,
is_weekend=0,
title_len=50,
caps_ratio=0.1,
exclamation_count=1,
question_count=0,
has_digits=0,
category_id=10,
)
@pytest.fixture
def clickbait_input():
return ClickbaitInput(
title="YOU WON'T BELIEVE THIS",
view_count=50000,
like_count=100,
comment_count=10,
)
@pytest.fixture
def viral_input():
return ViralInput(
view_velocity=100.0,
like_velocity=10.0,
comment_velocity=2.0,
like_ratio=0.1,
comment_ratio=0.02,
log_start_views=5.0,
video_age_hours=2.0,
duration_seconds=300,
hour_sin=0.5,
hour_cos=-0.8,
initial_virality_slope=1.5,
interaction_density=0.2,
title_len=40,
caps_ratio=0.1,
has_digits=0,
)
@pytest.fixture(autouse=True)
def enable_mock_inference():
"""Force mock inference for all tests in this module."""
# Patch the settings object where it is used in base.py
with patch("app.models.base.settings.ENABLE_MOCK_INFERENCE", True):
yield
# --- Tests ---
def test_velocity_model_initialization(velocity_input):
model = VelocityPredictor("test_velocity", repo_path="/tmp/mock")
model.load() # Should trigger mock init
assert model.is_loaded is True
prediction = model.predict(velocity_input)
assert isinstance(prediction, int)
assert prediction >= 0
def test_viral_trend_prediction(viral_input):
model = ViralTrendPredictor("test_viral", repo_path="/tmp/mock")
model.load()
label, prob = model.predict(viral_input)
assert isinstance(label, int)
assert isinstance(prob, float)
assert 0 <= prob <= 1
def test_clickbait_logic(clickbait_input):
model = ClickbaitDetector("test_clickbait", repo_path="/tmp/mock")
model.load()
# Test the heuristic logic defined in business rules
# High views + Low engagement = Clickbait
label, prob = model.predict(clickbait_input)
assert isinstance(label, int)
assert isinstance(prob, float)
assert 0 <= prob <= 1
def test_genre_pca_pipeline():
model = GenreClassifier("test_genre", repo_path="/tmp/mock")
model.load()
input_data = GenreInput(title="Minecraft Speedrun", tags=["gaming", "glitch"])
genre, confidence = model.predict(input_data)
assert isinstance(genre, str) # Should return label like "Gaming"
assert isinstance(confidence, float)
def test_tag_recommender():
model = TagRecommender("test_tags", repo_path="/tmp/mock")
model.load()
# Test specific association rule defined in mock
input_data = TagInput(current_tags=["minecraft", "speedrun"])
recs = model.predict(input_data)
assert isinstance(recs, list)
assert "dream" in recs or "manhunt" in recs
def test_anomaly_detection():
model = AnomalyDetector("test_anomaly", repo_path="/tmp/mock")
model.load()
input_data = AnomalyInput(
view_count=1000000,
like_count=0, # suspicious
comment_count=0,
duration_seconds=60,
)
is_anomaly, score = model.predict(input_data)
assert isinstance(is_anomaly, bool)
assert isinstance(score, float)