Fix: step 2 -> step 2b/3 workflow
Some checks failed
Build & Push Docker / build (push) Has been cancelled
Some checks failed
Build & Push Docker / build (push) Has been cancelled
Problem:
- Když uživatel importoval Excel a klikl 'Upravit v inline editoru' nebo 'Generovat',
dostal chybu 'Neplatný krok nebo chybějící data'
- step 2b vyžadoval file_item, ale formulář posílal file_content_base64
Řešení:
- Upravena podmínka pro step=2b aby akceptovala i file_content_base64
- Přidány 2 nové testy:
* test_excel_import_to_step2_workflow - testuje import -> step 2 -> step 3 (generate)
* test_excel_import_to_inline_editor_workflow - testuje import -> step 2 -> step 2b (inline editor)
Testy: 18/18 unit testů prošlo ✅
This commit is contained in:
@@ -583,10 +583,21 @@ button:hover { background: #0056b3; }
|
||||
logger.error(f"Unexpected error: {str(e)}")
|
||||
render_error(f"Neočekávaná chyba: {str(e)}")
|
||||
|
||||
elif step == '2b' and file_item is not None and file_item.filename:
|
||||
elif step == '2b':
|
||||
"""Load Excel data into inline editor for editing."""
|
||||
try:
|
||||
# Get file content from either file upload or base64
|
||||
file_content = None
|
||||
if file_item is not None and file_item.filename:
|
||||
file_content = file_item.file.read()
|
||||
else:
|
||||
file_content_base64 = form.getvalue('file_content_base64', '')
|
||||
if file_content_base64:
|
||||
file_content = base64.b64decode(file_content_base64)
|
||||
|
||||
if not file_content:
|
||||
render_error("Chyba: Soubor nebyl nalezen.")
|
||||
else:
|
||||
file_size = len(file_content)
|
||||
|
||||
# Validate inputs
|
||||
|
||||
@@ -249,3 +249,113 @@ def test_inline_workflow_integration():
|
||||
ws = wb.active
|
||||
assert ws['A1'].value == "Integration Test Event"
|
||||
assert ws['A2'].value == "Testing inline workflow"
|
||||
|
||||
|
||||
def test_excel_import_to_step2_workflow():
|
||||
"""Test workflow: Excel import -> step 2 (type definition) -> step 3 (generate).
|
||||
This simulates the user uploading Excel, then filling type definitions.
|
||||
"""
|
||||
import base64
|
||||
|
||||
# Step 1: Create Excel file
|
||||
df = pd.DataFrame({
|
||||
'Datum': [pd.Timestamp('2025-11-13').date()],
|
||||
'Zacatek': ['09:00'],
|
||||
'Konec': ['10:00'],
|
||||
'Program': ['Opening Keynote'],
|
||||
'Typ': ['KEYNOTE'],
|
||||
'Garant': ['John Smith'],
|
||||
'Poznamka': ['Welcome speech']
|
||||
})
|
||||
|
||||
file_content = make_excel_bytes(df)
|
||||
|
||||
# Step 2: Read Excel (simulating step=2 processing)
|
||||
valid_data, errors = read_excel(file_content)
|
||||
assert len(errors) == 0
|
||||
assert len(valid_data) == 1
|
||||
|
||||
# Extract types
|
||||
program_types = sorted([str(t).strip() for t in valid_data["Typ"].dropna().unique()])
|
||||
assert program_types == ['KEYNOTE']
|
||||
|
||||
# Step 3: User fills type definitions (simulating form submission in step=2)
|
||||
# This would be base64 encoded in the hidden field
|
||||
file_content_base64 = base64.b64encode(file_content).decode('utf-8')
|
||||
|
||||
form_data = {
|
||||
'title': 'Test Event',
|
||||
'detail': 'Test Detail',
|
||||
'file_content_base64': file_content_base64,
|
||||
'type_code_0': 'KEYNOTE',
|
||||
'desc_0': 'Main keynote presentation',
|
||||
'color_0': '#FF0000',
|
||||
'step': '3'
|
||||
}
|
||||
|
||||
# Parse types (simulating step=3 processing)
|
||||
descriptions, colors = get_program_types(form_data)
|
||||
|
||||
assert descriptions['KEYNOTE'] == 'Main keynote presentation'
|
||||
assert colors['KEYNOTE'] == 'FFFF0000'
|
||||
|
||||
# Step 4: Generate timetable
|
||||
# Re-read Excel from base64
|
||||
file_content_decoded = base64.b64decode(form_data['file_content_base64'])
|
||||
data, _ = read_excel(file_content_decoded)
|
||||
|
||||
wb = create_timetable(
|
||||
data,
|
||||
title=form_data['title'],
|
||||
detail=form_data['detail'],
|
||||
program_descriptions=descriptions,
|
||||
program_colors=colors
|
||||
)
|
||||
|
||||
assert wb is not None
|
||||
ws = wb.active
|
||||
assert ws['A1'].value == 'Test Event'
|
||||
assert ws['A2'].value == 'Test Detail'
|
||||
|
||||
|
||||
def test_excel_import_to_inline_editor_workflow():
|
||||
"""Test workflow: Excel import -> step 2 -> step 2b (inline editor).
|
||||
This simulates clicking 'Upravit v inline editoru' button.
|
||||
"""
|
||||
import base64
|
||||
|
||||
# Create Excel file
|
||||
df = pd.DataFrame({
|
||||
'Datum': [pd.Timestamp('2025-11-13').date(), pd.Timestamp('2025-11-14').date()],
|
||||
'Zacatek': ['09:00', '14:00'],
|
||||
'Konec': ['10:00', '15:30'],
|
||||
'Program': ['Morning Session', 'Afternoon Workshop'],
|
||||
'Typ': ['KEYNOTE', 'WORKSHOP'],
|
||||
'Garant': ['Alice', 'Bob'],
|
||||
'Poznamka': ['', 'Hands-on']
|
||||
})
|
||||
|
||||
file_content = make_excel_bytes(df)
|
||||
|
||||
# Step 2: Read Excel
|
||||
valid_data, errors = read_excel(file_content)
|
||||
assert len(errors) == 0
|
||||
assert len(valid_data) == 2
|
||||
|
||||
# Step 2b: User clicks "Upravit v inline editoru"
|
||||
# The form would pass file_content_base64 to step=2b
|
||||
file_content_base64 = base64.b64encode(file_content).decode('utf-8')
|
||||
|
||||
# Simulate step 2b: decode and re-read Excel
|
||||
file_content_decoded = base64.b64decode(file_content_base64)
|
||||
data_in_editor, _ = read_excel(file_content_decoded)
|
||||
|
||||
# Verify data loaded correctly
|
||||
assert len(data_in_editor) == 2
|
||||
assert data_in_editor.iloc[0]['Program'] == 'Morning Session'
|
||||
assert data_in_editor.iloc[1]['Program'] == 'Afternoon Workshop'
|
||||
|
||||
# Extract types for editor
|
||||
program_types = sorted([str(t).strip() for t in data_in_editor["Typ"].dropna().unique()])
|
||||
assert set(program_types) == {'KEYNOTE', 'WORKSHOP'}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user