Refactor: Oddělení business logiky + inline editor
Some checks failed
Build & Push Docker / build (push) Has been cancelled
Some checks failed
Build & Push Docker / build (push) Has been cancelled
- Nový modul scenar/core.py (491 řádků čisté logiky)
- Refactored cgi-bin/scenar.py (450 řádků CGI wrapper)
- Inline editor s JavaScript row managementem
- Custom exceptions (ScenarsError, ValidationError, TemplateError)
- Kompletní test coverage (10 testů, všechny ✅)
- Fixed Dockerfile (COPY scenar/, requirements.txt)
- Fixed requirements.txt (openpyxl==3.1.5)
- Fixed pytest.ini (pythonpath = .)
- Nové testy: test_http_inline.py, test_inline_builder.py
- HTTP testy označeny jako @pytest.mark.integration
- Build script: scripts/build_image.sh
- Dokumentace: COMPLETION.md
This commit is contained in:
138
tests/test_http_inline.py
Normal file
138
tests/test_http_inline.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""
|
||||
HTTP/CGI integration tests for inline builder workflow.
|
||||
Tests the real form submission through the CGI endpoint.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import urllib.parse
|
||||
import subprocess
|
||||
import json
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
def send_cgi_request(post_data=None, get_params=None):
|
||||
"""
|
||||
Send HTTP request to local CGI server and return response.
|
||||
Assumes server is running on localhost:8000
|
||||
"""
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
url = "http://localhost:8000/cgi-bin/scenar.py"
|
||||
|
||||
if get_params:
|
||||
url += "?" + urllib.parse.urlencode(get_params)
|
||||
|
||||
if post_data:
|
||||
data = urllib.parse.urlencode(post_data).encode('utf-8')
|
||||
else:
|
||||
data = None
|
||||
|
||||
try:
|
||||
req = urllib.request.Request(url, data=data, method='POST' if data else 'GET')
|
||||
with urllib.request.urlopen(req, timeout=10) as response:
|
||||
return response.read().decode('utf-8'), response.status
|
||||
except Exception as e:
|
||||
return str(e), None
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_inline_builder_form_submission_valid():
|
||||
"""Test inline builder with valid form data."""
|
||||
form_data = {
|
||||
'title': 'Test Event',
|
||||
'detail': 'Test Detail',
|
||||
'step': 'builder',
|
||||
|
||||
# Schedule row 0
|
||||
'datum_0': '2025-11-13',
|
||||
'zacatek_0': '09:00',
|
||||
'konec_0': '10:00',
|
||||
'program_0': 'Opening',
|
||||
'typ_0': 'KEYNOTE',
|
||||
'garant_0': 'John Smith',
|
||||
'poznamka_0': 'Welcome',
|
||||
|
||||
# Type definition 0
|
||||
'type_name_0': 'KEYNOTE',
|
||||
'type_desc_0': 'Main keynote',
|
||||
'type_color_0': '#FF0000',
|
||||
}
|
||||
|
||||
response, status = send_cgi_request(post_data=form_data)
|
||||
|
||||
# Should get 200 OK
|
||||
assert status == 200, f"Expected 200, got {status}"
|
||||
|
||||
# Response should contain success message
|
||||
assert '✅ Scénář úspěšně vygenerován' in response or 'Stáhnout scénář' in response, \
|
||||
f"Expected success message in response, got: {response[:500]}"
|
||||
|
||||
# Should have download link
|
||||
assert '/tmp/' in response, "Expected download link in response"
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_inline_builder_missing_type():
|
||||
"""Test that missing type definition is rejected."""
|
||||
form_data = {
|
||||
'title': 'Test Event',
|
||||
'detail': 'Test Detail',
|
||||
'step': 'builder',
|
||||
|
||||
# Schedule with type WORKSHOP
|
||||
'datum_0': '2025-11-13',
|
||||
'zacatek_0': '09:00',
|
||||
'konec_0': '10:00',
|
||||
'program_0': 'Workshop',
|
||||
'typ_0': 'WORKSHOP', # This type is not defined!
|
||||
'garant_0': 'John',
|
||||
'poznamka_0': '',
|
||||
|
||||
# Only KEYNOTE defined
|
||||
'type_name_0': 'KEYNOTE',
|
||||
'type_desc_0': 'Keynote',
|
||||
'type_color_0': '#FF0000',
|
||||
}
|
||||
|
||||
response, status = send_cgi_request(post_data=form_data)
|
||||
|
||||
# Should get error response
|
||||
assert status == 200 # CGI returns 200 with error content
|
||||
assert 'Chyba' in response or 'Missing type' in response, \
|
||||
f"Expected error message, got: {response[:500]}"
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_home_page_load():
|
||||
"""Test that home page loads without errors."""
|
||||
response, status = send_cgi_request()
|
||||
|
||||
assert status == 200
|
||||
assert '<!DOCTYPE html>' in response
|
||||
assert 'Scenar Creator' in response
|
||||
assert 'Importovat Excel' in response # Tab 1
|
||||
assert 'Vytvořit inline' in response # Tab 2
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
def test_inline_editor_tabs_present():
|
||||
"""Test that inline editor form elements are present."""
|
||||
response, status = send_cgi_request()
|
||||
|
||||
assert status == 200
|
||||
# Check for key form elements
|
||||
assert 'id="builderForm"' in response
|
||||
assert 'id="scheduleTable"' in response
|
||||
assert 'id="typesContainer"' in response
|
||||
assert 'id="availableTypes"' in response # datalist
|
||||
|
||||
# Check for JavaScript functions
|
||||
assert 'function addScheduleRow' in response
|
||||
assert 'function removeScheduleRow' in response
|
||||
assert 'function addTypeRow' in response
|
||||
assert 'function removeTypeRow' in response
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__, '-v'])
|
||||
Reference in New Issue
Block a user