import io import os import pandas as pd import importlib.util import sys import types def load_scenar_module(): repo_root = os.path.dirname(os.path.dirname(__file__)) scenar_path = os.path.join(repo_root, 'cgi-bin', 'scenar.py') # Provide a minimal fake `cgi` module so top-level imports in the CGI script don't fail if 'cgi' not in sys.modules: fake_cgi = types.ModuleType('cgi') class FakeFieldStorage: def getvalue(self, key, default=None): return default def keys(self): return [] def __contains__(self, item): return False fake_cgi.FieldStorage = FakeFieldStorage sys.modules['cgi'] = fake_cgi # minimal fake cgitb (some environments don't expose it) if 'cgitb' not in sys.modules: fake_cgitb = types.ModuleType('cgitb') def fake_enable(): return None fake_cgitb.enable = fake_enable sys.modules['cgitb'] = fake_cgitb spec = importlib.util.spec_from_file_location('scenar', scenar_path) module = importlib.util.module_from_spec(spec) # executing the module will run top-level CGI code (prints etc.) but defines functions we need spec.loader.exec_module(module) return module def make_excel_bytes(df: pd.DataFrame) -> bytes: bio = io.BytesIO() with pd.ExcelWriter(bio, engine='openpyxl') as writer: df.to_excel(writer, index=False) return bio.getvalue() def test_read_excel_happy_path(): scenar = load_scenar_module() df = pd.DataFrame({ 'Datum': [pd.Timestamp('2025-11-13').date()], 'Zacatek': ['09:00'], 'Konec': ['10:00'], 'Program': ['Test program'], 'Typ': ['WORKSHOP'], 'Garant': ['Garant Name'], 'Poznamka': ['Pozn'] }) content = make_excel_bytes(df) valid, errors = scenar.read_excel(content) assert isinstance(valid, pd.DataFrame) assert len(errors) == 0 assert len(valid) == 1 assert valid.iloc[0]['Program'] == 'Test program' def test_read_excel_invalid_time(): scenar = load_scenar_module() df = pd.DataFrame({ 'Datum': [pd.Timestamp('2025-11-13').date()], 'Zacatek': ['not-a-time'], 'Konec': ['10:00'], 'Program': ['Bad Time'], 'Typ': ['LECTURE'], 'Garant': [None], 'Poznamka': [None] }) content = make_excel_bytes(df) valid, errors = scenar.read_excel(content) # invalid time should produce at least one error row and valid may be empty assert isinstance(errors, list) assert len(errors) >= 1