185 lines
5.7 KiB
Python
185 lines
5.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Tests for the Flask application
|
|
"""
|
|
|
|
import pytest
|
|
import json
|
|
# Fixtures are imported from conftest.py
|
|
|
|
|
|
def test_index_page(client):
|
|
"""Test that the index page loads correctly."""
|
|
response = client.get('/')
|
|
assert response.status_code == 200
|
|
assert b'Balotario Licencia Clase A' in response.data
|
|
assert b'Estudiar' in response.data
|
|
assert b'Practicar' in response.data
|
|
assert b'Examen' in response.data
|
|
|
|
|
|
def test_study_page(client):
|
|
"""Test that the study page loads correctly."""
|
|
response = client.get('/study')
|
|
assert response.status_code == 200
|
|
assert b'Modo Estudio' in response.data
|
|
|
|
|
|
def test_practice_page(client):
|
|
"""Test that the practice page loads correctly."""
|
|
response = client.get('/practice')
|
|
assert response.status_code == 200
|
|
assert b'Modo Pr\xc3\xa1ctica' in response.data # "Práctica" in UTF-8
|
|
|
|
|
|
def test_exam_page(client):
|
|
"""Test that the exam page loads correctly."""
|
|
response = client.get('/exam')
|
|
assert response.status_code == 200
|
|
assert b'Examen Simulado' in response.data
|
|
|
|
|
|
def test_api_questions_all(client):
|
|
"""Test the API endpoint for getting all questions."""
|
|
response = client.get('/api/questions?mode=all')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
assert isinstance(data, list)
|
|
assert len(data) > 0
|
|
|
|
# Check structure of first question
|
|
if data:
|
|
question = data[0]
|
|
assert 'id' in question
|
|
assert 'question' in question
|
|
assert 'options' in question
|
|
assert 'correct' in question
|
|
assert 'has_image' in question
|
|
assert isinstance(question['options'], list)
|
|
assert len(question['options']) >= 2
|
|
|
|
|
|
def test_api_questions_range(client):
|
|
"""Test the API endpoint for getting questions by range."""
|
|
response = client.get('/api/questions?mode=range&start=1&end=5')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
assert isinstance(data, list)
|
|
assert len(data) <= 5
|
|
|
|
# Check that question IDs are within range
|
|
for question in data:
|
|
assert 1 <= question['id'] <= 5
|
|
|
|
|
|
def test_api_questions_random(client):
|
|
"""Test the API endpoint for getting random questions."""
|
|
response = client.get('/api/questions?mode=random&count=10')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
assert isinstance(data, list)
|
|
assert len(data) <= 10
|
|
|
|
|
|
def test_api_questions_invalid_mode(client):
|
|
"""Test the API endpoint with invalid mode (falls back to all questions)."""
|
|
response = client.get('/api/questions?mode=invalid')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
assert isinstance(data, list)
|
|
# Should return all questions as fallback
|
|
assert len(data) > 0
|
|
|
|
|
|
def test_api_questions_missing_parameters(client):
|
|
"""Test the API endpoint with missing parameters (uses defaults)."""
|
|
# Range mode without start/end (uses defaults)
|
|
response = client.get('/api/questions?mode=range')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
assert isinstance(data, list)
|
|
assert len(data) > 0
|
|
|
|
# Random mode without count (uses default of 20)
|
|
response = client.get('/api/questions?mode=random')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
assert isinstance(data, list)
|
|
assert len(data) <= 20 # Should use default count
|
|
|
|
|
|
def test_static_files(client):
|
|
"""Test that static files are accessible."""
|
|
# Test CSS file
|
|
response = client.get('/static/css/fontawesome-local.css')
|
|
assert response.status_code == 200
|
|
|
|
# Test JS file
|
|
response = client.get('/static/js/app.js')
|
|
assert response.status_code == 200
|
|
|
|
|
|
def test_favicon(client):
|
|
"""Test that favicon is accessible."""
|
|
response = client.get('/static/favicon.svg')
|
|
assert response.status_code == 200
|
|
|
|
|
|
def test_question_parsing_consistency(client):
|
|
"""Test that question parsing is consistent across API calls."""
|
|
# Get the same question range twice
|
|
response1 = client.get('/api/questions?mode=range&start=1&end=3')
|
|
response2 = client.get('/api/questions?mode=range&start=1&end=3')
|
|
|
|
assert response1.status_code == 200
|
|
assert response2.status_code == 200
|
|
|
|
data1 = json.loads(response1.data)
|
|
data2 = json.loads(response2.data)
|
|
|
|
# Should return the same questions
|
|
assert len(data1) == len(data2)
|
|
for q1, q2 in zip(data1, data2):
|
|
assert q1['id'] == q2['id']
|
|
assert q1['question'] == q2['question']
|
|
assert q1['correct'] == q2['correct']
|
|
|
|
|
|
def test_question_structure_validation(client):
|
|
"""Test that all questions have the required structure."""
|
|
response = client.get('/api/questions?mode=range&start=1&end=10')
|
|
assert response.status_code == 200
|
|
|
|
data = json.loads(response.data)
|
|
|
|
for question in data:
|
|
# Required fields
|
|
assert 'id' in question
|
|
assert 'question' in question
|
|
assert 'options' in question
|
|
assert 'correct' in question
|
|
assert 'has_image' in question
|
|
|
|
# Data types
|
|
assert isinstance(question['id'], int)
|
|
assert isinstance(question['question'], str)
|
|
assert isinstance(question['options'], list)
|
|
assert isinstance(question['correct'], str)
|
|
assert isinstance(question['has_image'], bool)
|
|
|
|
# Content validation
|
|
assert len(question['question']) > 0
|
|
assert len(question['options']) >= 2
|
|
assert question['correct'] in ['a', 'b', 'c', 'd']
|
|
|
|
# If has image, should have image URL
|
|
if question['has_image']:
|
|
assert 'image' in question
|
|
assert len(question['image']) > 0
|