Fixed unit tests

This commit is contained in:
2025-08-01 18:55:40 +02:00
parent a6f765c624
commit 3ca23449e4
5 changed files with 181 additions and 25 deletions

View File

@@ -1,20 +1,66 @@
import os
import shutil
import pytest
from fasthtml.components import Div
from components.undo_redo.components.UndoRedo import UndoRedo
from components.undo_redo.constants import UndoRedoAttrs
from core.dbengine import DbEngine
from core.settings_management import SettingsManager, MemoryDbEngine
from helpers import matches, div_icon, Contains, DoesNotContain
from my_mocks import tabs_manager
DB_ENGINE_ROOT = "undo_redo_test_db"
TEST_DB_ENTRY = "TestDbEntry"
TEST_DB_KEY = "TestDbKey"
class TestCommand:
def __init__(self, value):
self.value = value
def __eq__(self, other):
if not isinstance(other, TestCommand):
return False
return self.value == other.value
def __hash__(self):
return hash(self.value)
@pytest.fixture()
def engine(session):
if os.path.exists(DB_ENGINE_ROOT):
shutil.rmtree(DB_ENGINE_ROOT)
engine = DbEngine(DB_ENGINE_ROOT)
engine.init(session["user_id"])
yield engine
shutil.rmtree(DB_ENGINE_ROOT)
@pytest.fixture()
def settings_manager(engine):
return SettingsManager(engine=engine)
@pytest.fixture
def undo_redo(session, tabs_manager):
def undo_redo(session, tabs_manager, settings_manager):
return UndoRedo(session,
UndoRedo.create_component_id(session),
settings_manager=SettingsManager(engine=MemoryDbEngine()),
settings_manager=settings_manager,
tabs_manager=tabs_manager)
def init_command(session, settings_manager, undo_redo, value, on_undo=None):
settings_manager.save(session, TEST_DB_ENTRY, {TEST_DB_KEY: TestCommand(value)})
undo_redo.snapshot(UndoRedoAttrs(f"Set value to {value}", on_undo=on_undo), TEST_DB_ENTRY, TEST_DB_KEY)
def test_i_can_render(undo_redo):
actual = undo_redo.__ft__()
expected = Div(
@@ -26,13 +72,13 @@ def test_i_can_render(undo_redo):
assert matches(actual, expected)
def test_i_can_render_when_undoing_and_redoing(undo_redo):
undo_redo.push(UndoableCommand(0, 1))
undo_redo.push(UndoableCommand(1, 2))
def test_i_can_render_when_undoing_and_redoing(session, settings_manager, undo_redo):
init_command(session, settings_manager, undo_redo, "1")
init_command(session, settings_manager, undo_redo, "2")
actual = undo_redo.__ft__()
expected = Div(
Div(div_icon("undo", cls=DoesNotContain("mmt-btn-disabled")), data_tooltip="Undo 'Set new value'."),
Div(div_icon("undo", cls=DoesNotContain("mmt-btn-disabled")), data_tooltip="Undo 'Set value to 2'."),
Div(div_icon("redo", cls=Contains("mmt-btn-disabled")), data_tooltip="Nothing to redo."),
id=undo_redo.get_id(),
)
@@ -41,8 +87,8 @@ def test_i_can_render_when_undoing_and_redoing(undo_redo):
undo_redo.undo() # The command is now undone. We can redo it and undo the first command.
actual = undo_redo.__ft__()
expected = Div(
Div(div_icon("undo", cls=DoesNotContain("mmt-btn-disabled")), data_tooltip="Undo 'Set new value'."),
Div(div_icon("redo", cls=DoesNotContain("mmt-btn-disabled")), data_tooltip="Redo 'Set new value'."),
Div(div_icon("undo", cls=DoesNotContain("mmt-btn-disabled")), data_tooltip="Undo 'Set value to 1'."),
Div(div_icon("redo", cls=DoesNotContain("mmt-btn-disabled")), data_tooltip="Redo 'Set value to 2'."),
id=undo_redo.get_id(),
)
assert matches(actual, expected)
@@ -75,26 +121,48 @@ def test_i_can_render_when_undoing_and_redoing(undo_redo):
assert matches(actual, expected)
def test_i_can_undo_and_redo(undo_redo):
undo_redo.push(UndoableCommand(0, 1))
undo_redo.push(UndoableCommand(1, 2))
def test_values_are_correctly_reset(session, settings_manager, undo_redo):
# checks that the values are correctly returned
# Only checks that hx_swap_oob="true" is automatically put when id is present in the return
def on_undo():
current = settings_manager.get(session, TEST_DB_ENTRY, TEST_DB_KEY)
return Div(current.value, id='an_id')
init_command(session, settings_manager, undo_redo, "1", on_undo=on_undo)
init_command(session, settings_manager, undo_redo, "2", on_undo=on_undo)
self, res = undo_redo.undo()
expected = Div(1, hx_swap_oob="true")
expected = Div("1", id='an_id', hx_swap_oob="true")
assert matches(res, expected)
self, res = undo_redo.redo()
expected = Div(2, hx_swap_oob="true")
expected = Div("2", id='an_id', hx_swap_oob="true")
assert matches(res, expected)
def test_history_is_rewritten_when_pushing_a_command(undo_redo):
undo_redo.push(UndoableCommand(0, 1))
undo_redo.push(UndoableCommand(1, 2))
undo_redo.push(UndoableCommand(2, 3))
def test_i_can_manage_when_the_entry_was_not_present(session, settings_manager, undo_redo):
def on_undo():
snapshot = settings_manager.load(session, TEST_DB_ENTRY)
if TEST_DB_KEY in snapshot:
return Div(snapshot[TEST_DB_KEY].value, id='an_id')
else:
return Div("**Not Found**", id='an_id')
init_command(session, settings_manager, undo_redo, "1", on_undo=on_undo)
self, res = undo_redo.undo()
expected = Div("**Not Found**", id='an_id', hx_swap_oob="true")
assert matches(res, expected)
def test_history_is_rewritten_when_pushing_a_command_after_undo(session, settings_manager, undo_redo):
init_command(session, settings_manager, undo_redo, "1")
init_command(session, settings_manager, undo_redo, "2")
init_command(session, settings_manager, undo_redo, "3")
undo_redo.undo()
undo_redo.undo()
undo_redo.push(UndoableCommand(1, 5))
init_command(session, settings_manager, undo_redo, "5")
assert len(undo_redo.history) == 2
assert len(undo_redo.history) == 3 # do not forget that history always has a default command with digest = None

View File

@@ -1,11 +1,15 @@
from unittest.mock import MagicMock
import pytest
from fastcore.basics import NotStr
from fasthtml.components import *
from fasthtml.xtend import Script
from components.undo_redo.components.UndoRedo import UndoRedo
from components.workflows.components.WorkflowDesigner import WorkflowDesigner, COMPONENT_TYPES
from components.workflows.constants import ProcessorTypes
from components.workflows.db_management import WorkflowsDesignerSettings, WorkflowComponent, Connection
from core.instance_manager import InstanceManager
from core.settings_management import SettingsManager, MemoryDbEngine
from helpers import matches, Contains
from my_mocks import tabs_manager
@@ -13,6 +17,27 @@ from my_mocks import tabs_manager
TEST_WORKFLOW_DESIGNER_ID = "workflow_designer_id"
@pytest.fixture(autouse=True)
def mock_undo_redo(session):
# Create a mock UndoRedo instance
undo_redo = MagicMock(spec=UndoRedo)
# Store original get method
original_get = InstanceManager.get
def mock_get(sess, instance_id, *args, **kwargs):
if instance_id == UndoRedo.create_component_id(sess):
return undo_redo
return original_get(sess, instance_id, *args, **kwargs)
# Replace get method with our mock
InstanceManager.get = mock_get
yield undo_redo
# Restore original get method after test
InstanceManager.get = original_get
@pytest.fixture
def designer(session, tabs_manager):
return WorkflowDesigner(session=session, _id=TEST_WORKFLOW_DESIGNER_ID,

View File

@@ -4,10 +4,12 @@ import pandas as pd
import pytest
from pandas.testing import assert_frame_equal
from components.undo_redo.components.UndoRedo import UndoRedo
from components.workflows.components.WorkflowDesigner import COMPONENT_TYPES, WorkflowDesigner
from components.workflows.components.WorkflowPlayer import WorkflowPlayer, WorkflowsPlayerError
from components.workflows.constants import ProcessorTypes
from components.workflows.db_management import WorkflowComponent, Connection, ComponentState, WorkflowsDesignerSettings
from core.instance_manager import InstanceManager
from core.settings_management import SettingsManager, MemoryDbEngine
from my_mocks import tabs_manager
from workflow.engine import DataProcessorError
@@ -16,6 +18,27 @@ TEST_WORKFLOW_DESIGNER_ID = "workflow_designer_id"
TEST_WORKFLOW_PLAYER_ID = "workflow_player_id"
@pytest.fixture(autouse=True)
def mock_undo_redo(session):
# Create a mock UndoRedo instance
undo_redo = MagicMock(spec=UndoRedo)
# Store original get method
original_get = InstanceManager.get
def mock_get(sess, instance_id, *args, **kwargs):
if instance_id == UndoRedo.create_component_id(sess):
return undo_redo
return original_get(sess, instance_id, *args, **kwargs)
# Replace get method with our mock
InstanceManager.get = mock_get
yield undo_redo
# Restore original get method after test
InstanceManager.get = original_get
@pytest.fixture
def settings_manager():
return SettingsManager(MemoryDbEngine())

View File

@@ -1,8 +1,12 @@
from unittest.mock import MagicMock
import pytest
from fasthtml.components import *
from components.form.components.MyForm import FormField, MyForm
from components.undo_redo.components.UndoRedo import UndoRedo
from components.workflows.components.Workflows import Workflows
from core.instance_manager import InstanceManager
from core.settings_management import SettingsManager, MemoryDbEngine
from helpers import matches, div_icon, search_elements_by_name, Contains
from my_mocks import tabs_manager
@@ -18,6 +22,28 @@ def workflows(session, tabs_manager):
tabs_manager=tabs_manager)
@pytest.fixture(autouse=True)
def mock_undo_redo(session):
# Create a mock UndoRedo instance
undo_redo = MagicMock(spec=UndoRedo)
# Store original get method
original_get = InstanceManager.get
def mock_get(sess, instance_id, *args, **kwargs):
if instance_id == UndoRedo.create_component_id(sess):
return undo_redo
return original_get(sess, instance_id, *args, **kwargs)
# Replace get method with our mock
InstanceManager.get = mock_get
yield undo_redo
# Restore original get method after test
InstanceManager.get = original_get
def test_render_no_workflow(workflows):
actual = workflows.__ft__()
expected = Div(