530 lines
18 KiB
Python
530 lines
18 KiB
Python
"""
|
|
Unit tests for abstract functional elements.
|
|
|
|
Tests the Link, Button, Form, FormField, and related classes that handle
|
|
interactive functionality and user interface elements.
|
|
"""
|
|
|
|
import unittest
|
|
from unittest.mock import Mock, patch
|
|
from pyWebLayout.abstract.functional import (
|
|
Link, LinkType, Button, Form, FormField, FormFieldType
|
|
)
|
|
|
|
|
|
class TestLinkType(unittest.TestCase):
|
|
"""Test cases for LinkType enum."""
|
|
|
|
def test_link_types(self):
|
|
"""Test that all expected link types exist."""
|
|
expected_types = ['INTERNAL', 'EXTERNAL', 'API', 'FUNCTION']
|
|
|
|
for type_name in expected_types:
|
|
self.assertTrue(hasattr(LinkType, type_name))
|
|
|
|
# Test specific values
|
|
self.assertEqual(LinkType.INTERNAL.value, 1)
|
|
self.assertEqual(LinkType.EXTERNAL.value, 2)
|
|
self.assertEqual(LinkType.API.value, 3)
|
|
self.assertEqual(LinkType.FUNCTION.value, 4)
|
|
|
|
|
|
class TestLink(unittest.TestCase):
|
|
"""Test cases for Link class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.mock_callback = Mock(return_value="callback_result")
|
|
|
|
def test_link_creation_minimal(self):
|
|
"""Test link creation with minimal parameters."""
|
|
link = Link("test-location")
|
|
|
|
self.assertEqual(link.location, "test-location")
|
|
self.assertEqual(link.link_type, LinkType.INTERNAL) # Default
|
|
self.assertEqual(link.params, {})
|
|
self.assertIsNone(link.title)
|
|
self.assertIsNone(link._callback)
|
|
|
|
def test_link_creation_full(self):
|
|
"""Test link creation with all parameters."""
|
|
params = {"param1": "value1", "param2": "value2"}
|
|
link = Link(
|
|
location="https://example.com",
|
|
link_type=LinkType.EXTERNAL,
|
|
callback=self.mock_callback,
|
|
params=params,
|
|
title="Example Link"
|
|
)
|
|
|
|
self.assertEqual(link.location, "https://example.com")
|
|
self.assertEqual(link.link_type, LinkType.EXTERNAL)
|
|
self.assertEqual(link.params, params)
|
|
self.assertEqual(link.title, "Example Link")
|
|
self.assertEqual(link._callback, self.mock_callback)
|
|
|
|
def test_internal_link_execution(self):
|
|
"""Test executing internal links."""
|
|
link = Link("#section1", LinkType.INTERNAL)
|
|
result = link.execute()
|
|
|
|
# Internal links should return the location
|
|
self.assertEqual(result, "#section1")
|
|
|
|
def test_external_link_execution(self):
|
|
"""Test executing external links."""
|
|
link = Link("https://example.com", LinkType.EXTERNAL)
|
|
result = link.execute()
|
|
|
|
# External links should return the location
|
|
self.assertEqual(result, "https://example.com")
|
|
|
|
def test_api_link_execution(self):
|
|
"""Test executing API links with callback."""
|
|
params = {"action": "save", "id": 123}
|
|
link = Link(
|
|
location="/api/save",
|
|
link_type=LinkType.API,
|
|
callback=self.mock_callback,
|
|
params=params
|
|
)
|
|
|
|
result = link.execute()
|
|
|
|
# Should call callback with location and params
|
|
self.mock_callback.assert_called_once_with("/api/save", action="save", id=123)
|
|
self.assertEqual(result, "callback_result")
|
|
|
|
def test_function_link_execution(self):
|
|
"""Test executing function links with callback."""
|
|
params = {"data": "test"}
|
|
link = Link(
|
|
location="save_document",
|
|
link_type=LinkType.FUNCTION,
|
|
callback=self.mock_callback,
|
|
params=params
|
|
)
|
|
|
|
result = link.execute()
|
|
|
|
# Should call callback with location and params
|
|
self.mock_callback.assert_called_once_with("save_document", data="test")
|
|
self.assertEqual(result, "callback_result")
|
|
|
|
def test_api_link_without_callback(self):
|
|
"""Test API link without callback returns location."""
|
|
link = Link("/api/endpoint", LinkType.API)
|
|
result = link.execute()
|
|
|
|
# Without callback, should return location
|
|
self.assertEqual(result, "/api/endpoint")
|
|
|
|
def test_function_link_without_callback(self):
|
|
"""Test function link without callback returns location."""
|
|
link = Link("function_name", LinkType.FUNCTION)
|
|
result = link.execute()
|
|
|
|
# Without callback, should return location
|
|
self.assertEqual(result, "function_name")
|
|
|
|
def test_link_properties(self):
|
|
"""Test link property access."""
|
|
params = {"key": "value"}
|
|
link = Link(
|
|
location="test",
|
|
link_type=LinkType.API,
|
|
params=params,
|
|
title="Test Title"
|
|
)
|
|
|
|
# Test all property getters
|
|
self.assertEqual(link.location, "test")
|
|
self.assertEqual(link.link_type, LinkType.API)
|
|
self.assertEqual(link.params, params)
|
|
self.assertEqual(link.title, "Test Title")
|
|
|
|
|
|
class TestButton(unittest.TestCase):
|
|
"""Test cases for Button class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.mock_callback = Mock(return_value="button_clicked")
|
|
|
|
def test_button_creation_minimal(self):
|
|
"""Test button creation with minimal parameters."""
|
|
button = Button("Click Me", self.mock_callback)
|
|
|
|
self.assertEqual(button.label, "Click Me")
|
|
self.assertEqual(button._callback, self.mock_callback)
|
|
self.assertEqual(button.params, {})
|
|
self.assertTrue(button.enabled)
|
|
|
|
def test_button_creation_full(self):
|
|
"""Test button creation with all parameters."""
|
|
params = {"action": "submit", "form_id": "test_form"}
|
|
button = Button(
|
|
label="Submit",
|
|
callback=self.mock_callback,
|
|
params=params,
|
|
enabled=False
|
|
)
|
|
|
|
self.assertEqual(button.label, "Submit")
|
|
self.assertEqual(button._callback, self.mock_callback)
|
|
self.assertEqual(button.params, params)
|
|
self.assertFalse(button.enabled)
|
|
|
|
def test_button_label_property(self):
|
|
"""Test button label getter and setter."""
|
|
button = Button("Original", self.mock_callback)
|
|
|
|
# Test getter
|
|
self.assertEqual(button.label, "Original")
|
|
|
|
# Test setter
|
|
button.label = "New Label"
|
|
self.assertEqual(button.label, "New Label")
|
|
|
|
def test_button_enabled_property(self):
|
|
"""Test button enabled getter and setter."""
|
|
button = Button("Test", self.mock_callback, enabled=True)
|
|
|
|
# Test initial state
|
|
self.assertTrue(button.enabled)
|
|
|
|
# Test setter
|
|
button.enabled = False
|
|
self.assertFalse(button.enabled)
|
|
|
|
button.enabled = True
|
|
self.assertTrue(button.enabled)
|
|
|
|
def test_button_execute_enabled(self):
|
|
"""Test executing enabled button."""
|
|
params = {"data": "test_data"}
|
|
button = Button("Test", self.mock_callback, params=params, enabled=True)
|
|
|
|
result = button.execute()
|
|
|
|
# Should call callback with params
|
|
self.mock_callback.assert_called_once_with(data="test_data")
|
|
self.assertEqual(result, "button_clicked")
|
|
|
|
def test_button_execute_disabled(self):
|
|
"""Test executing disabled button."""
|
|
button = Button("Test", self.mock_callback, enabled=False)
|
|
|
|
result = button.execute()
|
|
|
|
# Should not call callback and return None
|
|
self.mock_callback.assert_not_called()
|
|
self.assertIsNone(result)
|
|
|
|
def test_button_execute_no_callback(self):
|
|
"""Test executing button without callback."""
|
|
button = Button("Test", None, enabled=True)
|
|
|
|
result = button.execute()
|
|
|
|
# Should return None
|
|
self.assertIsNone(result)
|
|
|
|
|
|
class TestFormFieldType(unittest.TestCase):
|
|
"""Test cases for FormFieldType enum."""
|
|
|
|
def test_form_field_types(self):
|
|
"""Test that all expected form field types exist."""
|
|
expected_types = [
|
|
'TEXT', 'PASSWORD', 'CHECKBOX', 'RADIO', 'SELECT', 'TEXTAREA',
|
|
'NUMBER', 'DATE', 'TIME', 'EMAIL', 'URL', 'COLOR', 'RANGE', 'HIDDEN'
|
|
]
|
|
|
|
for type_name in expected_types:
|
|
self.assertTrue(hasattr(FormFieldType, type_name))
|
|
|
|
# Test some specific values
|
|
self.assertEqual(FormFieldType.TEXT.value, 1)
|
|
self.assertEqual(FormFieldType.PASSWORD.value, 2)
|
|
self.assertEqual(FormFieldType.HIDDEN.value, 14)
|
|
|
|
|
|
class TestFormField(unittest.TestCase):
|
|
"""Test cases for FormField class."""
|
|
|
|
def test_form_field_creation_minimal(self):
|
|
"""Test form field creation with minimal parameters."""
|
|
field = FormField("username", FormFieldType.TEXT)
|
|
|
|
self.assertEqual(field.name, "username")
|
|
self.assertEqual(field.field_type, FormFieldType.TEXT)
|
|
self.assertEqual(field.label, "username") # Default to name
|
|
self.assertIsNone(field.value)
|
|
self.assertFalse(field.required)
|
|
self.assertEqual(field.options, [])
|
|
self.assertIsNone(field.form)
|
|
|
|
def test_form_field_creation_full(self):
|
|
"""Test form field creation with all parameters."""
|
|
options = [("value1", "Label 1"), ("value2", "Label 2")]
|
|
field = FormField(
|
|
name="country",
|
|
field_type=FormFieldType.SELECT,
|
|
label="Country",
|
|
value="value1",
|
|
required=True,
|
|
options=options
|
|
)
|
|
|
|
self.assertEqual(field.name, "country")
|
|
self.assertEqual(field.field_type, FormFieldType.SELECT)
|
|
self.assertEqual(field.label, "Country")
|
|
self.assertEqual(field.value, "value1")
|
|
self.assertTrue(field.required)
|
|
self.assertEqual(field.options, options)
|
|
|
|
def test_form_field_value_property(self):
|
|
"""Test form field value getter and setter."""
|
|
field = FormField("test", FormFieldType.TEXT, value="initial")
|
|
|
|
# Test getter
|
|
self.assertEqual(field.value, "initial")
|
|
|
|
# Test setter
|
|
field.value = "new_value"
|
|
self.assertEqual(field.value, "new_value")
|
|
|
|
def test_form_field_form_property(self):
|
|
"""Test form field form getter and setter."""
|
|
field = FormField("test", FormFieldType.TEXT)
|
|
mock_form = Mock()
|
|
|
|
# Initial state
|
|
self.assertIsNone(field.form)
|
|
|
|
# Test setter
|
|
field.form = mock_form
|
|
self.assertEqual(field.form, mock_form)
|
|
|
|
def test_form_field_properties(self):
|
|
"""Test all form field property getters."""
|
|
options = [("opt1", "Option 1")]
|
|
field = FormField(
|
|
name="test_field",
|
|
field_type=FormFieldType.CHECKBOX,
|
|
label="Test Field",
|
|
value=True,
|
|
required=True,
|
|
options=options
|
|
)
|
|
|
|
# Test all getters
|
|
self.assertEqual(field.name, "test_field")
|
|
self.assertEqual(field.field_type, FormFieldType.CHECKBOX)
|
|
self.assertEqual(field.label, "Test Field")
|
|
self.assertTrue(field.value)
|
|
self.assertTrue(field.required)
|
|
self.assertEqual(field.options, options)
|
|
|
|
|
|
class TestForm(unittest.TestCase):
|
|
"""Test cases for Form class."""
|
|
|
|
def setUp(self):
|
|
"""Set up test fixtures."""
|
|
self.mock_callback = Mock(return_value="form_submitted")
|
|
|
|
def test_form_creation_minimal(self):
|
|
"""Test form creation with minimal parameters."""
|
|
form = Form("test_form")
|
|
|
|
self.assertEqual(form.form_id, "test_form")
|
|
self.assertIsNone(form.action)
|
|
self.assertIsNone(form._callback)
|
|
self.assertEqual(len(form._fields), 0)
|
|
|
|
def test_form_creation_full(self):
|
|
"""Test form creation with all parameters."""
|
|
form = Form(
|
|
form_id="contact_form",
|
|
action="/submit",
|
|
callback=self.mock_callback
|
|
)
|
|
|
|
self.assertEqual(form.form_id, "contact_form")
|
|
self.assertEqual(form.action, "/submit")
|
|
self.assertEqual(form._callback, self.mock_callback)
|
|
|
|
def test_form_field_management(self):
|
|
"""Test adding and retrieving form fields."""
|
|
form = Form("test_form")
|
|
|
|
# Create fields
|
|
field1 = FormField("username", FormFieldType.TEXT, value="john")
|
|
field2 = FormField("password", FormFieldType.PASSWORD, value="secret")
|
|
field3 = FormField("email", FormFieldType.EMAIL, value="john@example.com")
|
|
|
|
# Add fields
|
|
form.add_field(field1)
|
|
form.add_field(field2)
|
|
form.add_field(field3)
|
|
|
|
# Test that fields are stored correctly
|
|
self.assertEqual(len(form._fields), 3)
|
|
|
|
# Test field retrieval
|
|
self.assertEqual(form.get_field("username"), field1)
|
|
self.assertEqual(form.get_field("password"), field2)
|
|
self.assertEqual(form.get_field("email"), field3)
|
|
self.assertIsNone(form.get_field("nonexistent"))
|
|
|
|
# Test that fields have form reference
|
|
self.assertEqual(field1.form, form)
|
|
self.assertEqual(field2.form, form)
|
|
self.assertEqual(field3.form, form)
|
|
|
|
def test_form_get_values(self):
|
|
"""Test getting form values."""
|
|
form = Form("test_form")
|
|
|
|
# Add fields with values
|
|
form.add_field(FormField("name", FormFieldType.TEXT, value="John Doe"))
|
|
form.add_field(FormField("age", FormFieldType.NUMBER, value=30))
|
|
form.add_field(FormField("subscribe", FormFieldType.CHECKBOX, value=True))
|
|
|
|
# Get values
|
|
values = form.get_values()
|
|
|
|
expected = {
|
|
"name": "John Doe",
|
|
"age": 30,
|
|
"subscribe": True
|
|
}
|
|
|
|
self.assertEqual(values, expected)
|
|
|
|
def test_form_get_values_empty(self):
|
|
"""Test getting values from empty form."""
|
|
form = Form("empty_form")
|
|
values = form.get_values()
|
|
|
|
self.assertEqual(values, {})
|
|
|
|
def test_form_execute_with_callback(self):
|
|
"""Test executing form with callback."""
|
|
form = Form("test_form", callback=self.mock_callback)
|
|
|
|
# Add some fields
|
|
form.add_field(FormField("field1", FormFieldType.TEXT, value="value1"))
|
|
form.add_field(FormField("field2", FormFieldType.TEXT, value="value2"))
|
|
|
|
result = form.execute()
|
|
|
|
# Should call callback with form_id and values
|
|
expected_values = {"field1": "value1", "field2": "value2"}
|
|
self.mock_callback.assert_called_once_with("test_form", expected_values)
|
|
self.assertEqual(result, "form_submitted")
|
|
|
|
def test_form_execute_without_callback(self):
|
|
"""Test executing form without callback."""
|
|
form = Form("test_form")
|
|
|
|
# Add a field
|
|
form.add_field(FormField("test", FormFieldType.TEXT, value="test_value"))
|
|
|
|
result = form.execute()
|
|
|
|
# Should return the form values
|
|
expected = {"test": "test_value"}
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_form_properties(self):
|
|
"""Test form property getters."""
|
|
form = Form("test_form", action="/submit")
|
|
|
|
self.assertEqual(form.form_id, "test_form")
|
|
self.assertEqual(form.action, "/submit")
|
|
|
|
|
|
class TestFormIntegration(unittest.TestCase):
|
|
"""Integration tests for form functionality."""
|
|
|
|
def test_complete_form_workflow(self):
|
|
"""Test a complete form creation and submission workflow."""
|
|
# Create form
|
|
form = Form("registration_form", action="/register")
|
|
|
|
# Add various field types
|
|
form.add_field(FormField(
|
|
"username", FormFieldType.TEXT,
|
|
label="Username", required=True, value="testuser"
|
|
))
|
|
|
|
form.add_field(FormField(
|
|
"password", FormFieldType.PASSWORD,
|
|
label="Password", required=True, value="secret123"
|
|
))
|
|
|
|
form.add_field(FormField(
|
|
"email", FormFieldType.EMAIL,
|
|
label="Email", required=True, value="test@example.com"
|
|
))
|
|
|
|
form.add_field(FormField(
|
|
"country", FormFieldType.SELECT,
|
|
label="Country", value="US",
|
|
options=[("US", "United States"), ("CA", "Canada"), ("UK", "United Kingdom")]
|
|
))
|
|
|
|
form.add_field(FormField(
|
|
"newsletter", FormFieldType.CHECKBOX,
|
|
label="Subscribe to newsletter", value=True
|
|
))
|
|
|
|
# Test form state
|
|
self.assertEqual(len(form._fields), 5)
|
|
|
|
# Test individual field access
|
|
username_field = form.get_field("username")
|
|
self.assertEqual(username_field.value, "testuser")
|
|
self.assertTrue(username_field.required)
|
|
|
|
# Test getting all values
|
|
values = form.get_values()
|
|
expected = {
|
|
"username": "testuser",
|
|
"password": "secret123",
|
|
"email": "test@example.com",
|
|
"country": "US",
|
|
"newsletter": True
|
|
}
|
|
self.assertEqual(values, expected)
|
|
|
|
# Test form submission
|
|
result = form.execute()
|
|
self.assertEqual(result, expected)
|
|
|
|
def test_form_field_modification(self):
|
|
"""Test modifying form fields after creation."""
|
|
form = Form("test_form")
|
|
|
|
# Add field
|
|
field = FormField("test", FormFieldType.TEXT, value="initial")
|
|
form.add_field(field)
|
|
|
|
# Modify field value
|
|
field.value = "modified"
|
|
|
|
# Test that form reflects the change
|
|
values = form.get_values()
|
|
self.assertEqual(values["test"], "modified")
|
|
|
|
# Test getting the modified field
|
|
retrieved_field = form.get_field("test")
|
|
self.assertEqual(retrieved_field.value, "modified")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|