@@ -1567,6 +1567,77 @@ def test_filter_properties_required_field_missing(
15671567 assert "required" not in result [0 ]["properties" ][0 ]
15681568
15691569
1570+ @pytest .mark .asyncio
1571+ async def test_schema_from_text_with_required_properties (
1572+ schema_from_text : SchemaFromTextExtractor ,
1573+ mock_llm : AsyncMock ,
1574+ schema_json_with_required_properties : str ,
1575+ ) -> None :
1576+ mock_llm .ainvoke .return_value = LLMResponse (
1577+ content = schema_json_with_required_properties
1578+ )
1579+
1580+ schema = await schema_from_text .run (text = "Sample text for test" )
1581+
1582+ person = schema .node_type_from_label ("Person" )
1583+ assert person is not None
1584+
1585+ # Check required properties
1586+ name_prop = next ((p for p in person .properties if p .name == "name" ), None )
1587+ email_prop = next ((p for p in person .properties if p .name == "email" ), None )
1588+ phone_prop = next ((p for p in person .properties if p .name == "phone" ), None )
1589+
1590+ assert name_prop is not None and name_prop .required is True
1591+ assert email_prop is not None and email_prop .required is False
1592+ assert phone_prop is not None and phone_prop .required is False
1593+
1594+
1595+ @pytest .mark .asyncio
1596+ async def test_schema_from_text_sanitizes_string_required_values (
1597+ schema_from_text : SchemaFromTextExtractor ,
1598+ mock_llm : AsyncMock ,
1599+ schema_json_with_string_required_values : str ,
1600+ ) -> None :
1601+ mock_llm .ainvoke .return_value = LLMResponse (
1602+ content = schema_json_with_string_required_values
1603+ )
1604+
1605+ schema = await schema_from_text .run (text = "Sample text for test" )
1606+
1607+ person = schema .node_type_from_label ("Person" )
1608+ assert person is not None
1609+
1610+ # true and yes should become True
1611+ name_prop = next ((p for p in person .properties if p .name == "name" ), None )
1612+ email_prop = next ((p for p in person .properties if p .name == "email" ), None )
1613+ assert name_prop is not None and name_prop .required is True
1614+ assert email_prop is not None and email_prop .required is True
1615+
1616+ # false and no should become False
1617+ phone_prop = next ((p for p in person .properties if p .name == "phone" ), None )
1618+ address_prop = next ((p for p in person .properties if p .name == "address" ), None )
1619+ assert phone_prop is not None and phone_prop .required is False
1620+ assert address_prop is not None and address_prop .required is False
1621+
1622+
1623+ @pytest .mark .asyncio
1624+ async def test_schema_from_text_handles_missing_required_field (
1625+ schema_from_text : SchemaFromTextExtractor ,
1626+ mock_llm : AsyncMock ,
1627+ valid_schema_json : str ,
1628+ ) -> None :
1629+ mock_llm .ainvoke .return_value = LLMResponse (content = valid_schema_json )
1630+
1631+ schema = await schema_from_text .run (text = "Sample text" )
1632+
1633+ person = schema .node_type_from_label ("Person" )
1634+ assert person is not None
1635+
1636+ # All properties should have required=False (default)
1637+ for prop in person .properties :
1638+ assert prop .required is False
1639+
1640+
15701641@pytest .mark .asyncio
15711642@patch ("neo4j_graphrag.experimental.components.schema.get_structured_schema" )
15721643async def test_schema_from_existing_graph (mock_get_structured_schema : Mock ) -> None :
0 commit comments