from app.module.annotation.utils.config_validator import LabelStudioConfigValidator
import pytest
def test_validate_xml_success_with_object_and_control() -> None:
xml = """
"""
valid, error = LabelStudioConfigValidator.validate_xml(xml)
assert valid is True
assert error is None
def test_validate_xml_fails_when_no_controls() -> None:
xml = """"""
valid, error = LabelStudioConfigValidator.validate_xml(xml)
assert valid is False
assert "No annotation controls" in (error or "")
def test_validate_configuration_json_rejects_unknown_object_reference() -> None:
config = {
"labels": [
{
"fromName": "sentiment",
"toName": "missing_object",
"type": "Choices",
"options": ["positive", "negative"],
}
],
"objects": [
{"name": "text", "type": "Text", "value": "$text"}
],
}
valid, error = LabelStudioConfigValidator.validate_configuration_json(config)
assert valid is False
assert "unknown object" in (error or "")
def test_extract_label_values() -> None:
xml = """
"""
labels = LabelStudioConfigValidator.extract_label_values(xml)
assert labels == {"sentiment": ["positive", "negative"]}
def test_validate_xml_rejects_invalid_root() -> None:
xml = """"""
valid, error = LabelStudioConfigValidator.validate_xml(xml)
assert valid is False
assert "Root element must be " in (error or "")
def test_validate_configuration_json_requires_labels() -> None:
valid, error = LabelStudioConfigValidator.validate_configuration_json({"objects": []})
assert valid is False
assert "Missing 'labels' field" in (error or "")
def test_validate_xml_fails_for_invalid_xml() -> None:
xml = ""
valid, error = LabelStudioConfigValidator.validate_xml(xml)
assert valid is False
assert "XML parse error" in (error or "")
@pytest.mark.parametrize(
"label,error_text",
[
({"toName": "obj", "type": "Choices", "options": ["A"]}, "fromName"),
({"fromName": "lbl", "type": "Choices", "options": ["A"]}, "toName"),
({"fromName": "lbl", "toName": "obj", "options": ["A"]}, "type"),
],
)
def test_validate_label_definition_required_fields(label, error_text: str) -> None:
valid, error = LabelStudioConfigValidator._validate_label_definition(label)
assert valid is False
assert error_text in (error or "")
def test_validate_label_definition_rejects_unsupported_type() -> None:
label = {
"fromName": "x",
"toName": "obj",
"type": "NotSupported",
}
valid, error = LabelStudioConfigValidator._validate_label_definition(label)
assert valid is False
assert "Unsupported control type" in (error or "")
def test_validate_object_definition_rejects_value_without_dollar_prefix() -> None:
obj = {"name": "txt", "type": "Text", "value": "text"}
valid, error = LabelStudioConfigValidator._validate_object_definition(obj)
assert valid is False
assert "must start with '$'" in (error or "")
def test_extract_label_values_returns_empty_on_invalid_xml() -> None:
labels = LabelStudioConfigValidator.extract_label_values(" None:
xml = """
"""
valid, error = LabelStudioConfigValidator.validate_xml(xml)
assert valid is False
assert "Missing 'name' attribute" in (error or "")