From f7c7a4f19724f0767f10f2ce88e0f2c09d67873f Mon Sep 17 00:00:00 2001
From: Daniel <d.hornung@indiscale.com>
Date: Thu, 4 Apr 2024 16:51:19 +0200
Subject: [PATCH] FIX: Json schema exporter is more relaxed now.

---
 src/caosadvancedtools/json_schema_exporter.py | 36 +++++++++++++------
 unittests/test_json_schema_exporter.py        | 16 ++++-----
 2 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py
index 5d18ad06..11e74369 100644
--- a/src/caosadvancedtools/json_schema_exporter.py
+++ b/src/caosadvancedtools/json_schema_exporter.py
@@ -147,16 +147,25 @@ class JsonSchemaExporter:
     def _make_segment_from_prop(self, prop: db.Property) -> Tuple[OrderedDict, dict]:
         """Return the JSON Schema and ui schema segments for the given property.
 
-        The result may either be a simple json schema segment, such as a `string
-        <https://json-schema.org/understanding-json-schema/reference/string>`_ element (or another
-        simple type), a combination such as `anyOf
-        <https://json-schema.org/understanding-json-schema/reference/combining#anyof>`_ or an `array
-        <https://json-schema.org/understanding-json-schema/reference/array>`_ element
+The result may either be a simple json schema segment, such as a `string
+<https://json-schema.org/understanding-json-schema/reference/string>`_ element (or another
+simple type), a combination such as `anyOf
+<https://json-schema.org/understanding-json-schema/reference/combining#anyof>`_ or an `array
+<https://json-schema.org/understanding-json-schema/reference/array>`_ element
 
-        Parameters
-        ----------
-        prop : db.Property
-            The property to be transformed.
+Parameters
+----------
+prop : db.Property
+    The property to be transformed.
+
+Returns
+-------
+
+json_schema : OrderedDict
+    The Json schema.
+
+ui_schema : dict
+    An appropriate UI schema.
         """
         json_prop = OrderedDict()
         ui_schema: dict = {}
@@ -202,6 +211,11 @@ class JsonSchemaExporter:
             list_element_prop = db.Property(
                 name=prop.name, datatype=get_list_datatype(prop.datatype, strict=True))
             json_prop["items"], inner_ui_schema = self._make_segment_from_prop(list_element_prop)
+            if "type" in json_prop["items"] and (
+                    json_prop["items"]["type"] in ["boolean", "integer", "number", "string"]
+            ):
+                json_prop["items"]["type"] = [json_prop["items"]["type"], "null"]
+
             if prop.name in self._multiple_choice and prop.name in self._do_not_create:
                 # TODO: if not multiple_choice, but do_not_create:
                 # "ui:widget" = "radio" & "ui:inline" = true
@@ -235,8 +249,10 @@ class JsonSchemaExporter:
                     json_prop["items"] = {
                         "type": "object",
                         "title": "Next file",
+                        # TODO Why can't it be empty?
                         # The wrapper object must wrap a file and can't be empty.
-                        "required": ["file"],
+                        "required": [  # "file"
+                        ],
                         # Wrapper objects must only contain the wrapped file.
                         "additionalProperties": False,
                         "properties": {
diff --git a/unittests/test_json_schema_exporter.py b/unittests/test_json_schema_exporter.py
index b8c1ddd1..1cea2f58 100644
--- a/unittests/test_json_schema_exporter.py
+++ b/unittests/test_json_schema_exporter.py
@@ -268,7 +268,7 @@ def test_units():
     assert "ListWithUnit" in props
     assert props["ListWithUnit"]["type"] == "array"
     assert "items" in props["ListWithUnit"]
-    assert props["ListWithUnit"]["items"]["type"] == "number"
+    assert props["ListWithUnit"]["items"]["type"] == ["number", "null"]
     assert "description" in props["ListWithUnit"]
     assert props["ListWithUnit"]["description"] == "This is a list. Unit is m."
     assert "unit" not in props["ListWithUnit"]
@@ -285,7 +285,7 @@ def test_units():
     assert "ListWithUnit" in props
     assert props["ListWithUnit"]["type"] == "array"
     assert "items" in props["ListWithUnit"]
-    assert props["ListWithUnit"]["items"]["type"] == "number"
+    assert props["ListWithUnit"]["items"]["type"] == ["number", "null"]
     assert "description" in props["ListWithUnit"]
     assert props["ListWithUnit"]["description"] == "This is a list."
     assert "unit" in props["ListWithUnit"]
@@ -306,14 +306,14 @@ def test_rt_with_list_props():
     assert "ListOfIntegers" in props
     assert props["ListOfIntegers"]["type"] == "array"
     assert "items" in props["ListOfIntegers"]
-    assert props["ListOfIntegers"]["items"]["type"] == "integer"
+    assert props["ListOfIntegers"]["items"]["type"] == ["integer", "null"]
     assert "description" not in props["ListOfIntegers"]["items"]
     assert props["ListOfIntegers"]["description"] == "List of integers"
 
     assert "ListOfPatterns" in props
     assert props["ListOfPatterns"]["type"] == "array"
     assert "items" in props["ListOfPatterns"]
-    assert props["ListOfPatterns"]["items"]["type"] == "string"
+    assert props["ListOfPatterns"]["items"]["type"] == ["string", "null"]
     assert props["ListOfPatterns"]["items"]["pattern"] == "[A-Z]+"
 
     # Validation
@@ -575,8 +575,7 @@ def test_rt_with_references():
     assert "items" in schema["properties"]["FileProp"]
     items = schema["properties"]["FileProp"]["items"]
     assert items["type"] == "object"
-    assert len(items["required"]) == 1
-    assert "file" in items["required"]
+    assert len(items["required"]) == 0
     assert items["additionalProperties"] is False
     assert len(items["properties"]) == 1
     assert "file" in items["properties"]
@@ -588,7 +587,7 @@ def test_rt_with_references():
 
     schema = rtjs(rt)
     assert schema["properties"]["FileProp"]["type"] == "array"
-    assert schema["properties"]["FileProp"]["items"]["type"] == "string"
+    assert schema["properties"]["FileProp"]["items"]["type"] == ["string", "null"]
     assert schema["properties"]["FileProp"]["items"]["format"] == "data-url"
 
     # wrap in array (cf. https://github.com/rjsf-team/react-jsonschema-form/issues/3957)
@@ -599,8 +598,7 @@ def test_rt_with_references():
     assert "items" in schema["properties"]["FileProp"]
     items = schema["properties"]["FileProp"]["items"]
     assert items["type"] == "object"
-    assert len(items["required"]) == 1
-    assert "file" in items["required"]
+    assert len(items["required"]) == 0
     assert items["additionalProperties"] is False
     assert len(items["properties"]) == 1
     assert "file" in items["properties"]
-- 
GitLab