| Server IP : 3.147.158.171 / Your IP : 216.73.216.216 Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.21 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /tsai/www/html/api.turmansolutions.ai/tests/unit/ |
Upload File : |
"""Unit tests for the /quiz/init endpoint."""
from unittest.mock import patch
from app.appTypes import Character, LLMProvider, LLModel
def _fake_scike() -> Character:
return Character(
slug='scike',
name='Scike',
email='scike@example.test',
description='Scike is a friendly quiz host who helps readers learn.',
enabled=True,
date='2026-01-01',
siteId='',
model=LLModel(provider=LLMProvider.OPEN_AI, name='gpt-4o-mini'),
)
class TestQuizInit:
def test_init_returns_instructions_and_intro(self, test_client, mock_site_config):
with patch(
'app.api.v1.endpoints.quiz.site_config_service.get_site_by_slug',
return_value=mock_site_config,
), patch(
'app.api.v1.endpoints.quiz.drupal_service.fetch_character_by_slug',
return_value={'fake': 'drupal-node'},
), patch(
'app.api.v1.endpoints.quiz.drupal_service.create_character',
return_value=_fake_scike(),
):
payload = {
'post_id': 42,
'site_slug': 'test',
'character_slug': 'scike',
'title': 'How Photosynthesis Works',
'body': 'Photosynthesis is the process by which plants convert sunlight into energy...',
}
res = test_client.post('/api/v1/quiz/init', json=payload)
assert res.status_code == 200, res.text
data = res.json()
assert data['character']['slug'] == 'scike'
assert data['character']['name'] == 'Scike'
instructions = data['instructions']
assert 'How Photosynthesis Works' in instructions
assert 'Photosynthesis is the process' in instructions
assert 'three-question quiz' in instructions
assert 'MULTIPLE CHOICE' in instructions
assert 'SHORT ANSWER' in instructions
assert 'PASS' in instructions
assert 'Do NOT assign letter grades' in instructions
intro = data['intro_message']
assert 'Scike' in intro
assert 'How Photosynthesis Works' in intro
def test_init_unknown_site_returns_404(self, test_client):
with patch(
'app.api.v1.endpoints.quiz.site_config_service.get_site_by_slug',
return_value=None,
):
res = test_client.post(
'/api/v1/quiz/init',
json={
'post_id': 1,
'site_slug': 'nope',
'title': 't',
'body': 'b',
},
)
assert res.status_code == 404
def test_init_unknown_character_returns_404(self, test_client, mock_site_config):
with patch(
'app.api.v1.endpoints.quiz.site_config_service.get_site_by_slug',
return_value=mock_site_config,
), patch(
'app.api.v1.endpoints.quiz.drupal_service.fetch_character_by_slug',
return_value=None,
):
res = test_client.post(
'/api/v1/quiz/init',
json={
'post_id': 1,
'site_slug': 'test',
'character_slug': 'ghost',
'title': 't',
'body': 'b',
},
)
assert res.status_code == 404
def test_init_accepts_non_openai_character(self, test_client, mock_site_config):
"""The quiz always runs on QUIZ_MODEL, so a Claude-authored character is
still a valid host — it only supplies the persona. The default 'scike'
character uses Claude, which used to 500 on sites like johnturman.net."""
claude_scike = _fake_scike()
claude_scike.model = LLModel(provider=LLMProvider.CLAUDE, name='claude-sonnet-4-6')
with patch(
'app.api.v1.endpoints.quiz.site_config_service.get_site_by_slug',
return_value=mock_site_config,
), patch(
'app.api.v1.endpoints.quiz.drupal_service.fetch_character_by_slug',
return_value={'fake': 'drupal-node'},
), patch(
'app.api.v1.endpoints.quiz.drupal_service.create_character',
return_value=claude_scike,
):
res = test_client.post(
'/api/v1/quiz/init',
json={
'post_id': 1,
'site_slug': 'test',
'character_slug': 'scike',
'title': 't',
'body': 'b',
},
)
assert res.status_code == 200, res.text
assert res.json()['character']['slug'] == 'scike'
def test_init_defaults_character_slug_to_scike(self, test_client, mock_site_config):
captured = {}
def fake_fetch(slug, site):
captured['slug'] = slug
return {'fake': 'node'}
with patch(
'app.api.v1.endpoints.quiz.site_config_service.get_site_by_slug',
return_value=mock_site_config,
), patch(
'app.api.v1.endpoints.quiz.drupal_service.fetch_character_by_slug',
side_effect=fake_fetch,
), patch(
'app.api.v1.endpoints.quiz.drupal_service.create_character',
return_value=_fake_scike(),
):
res = test_client.post(
'/api/v1/quiz/init',
json={
'post_id': 1,
'site_slug': 'test',
'title': 't',
'body': 'b',
},
)
assert res.status_code == 200
assert captured['slug'] == 'scike'