Skip to content

Commit d5b48db

Browse files
fix(ontology): link value property is still not editable after updating the property metadata (DEV-1116) (#2133)
* write tests to reproduce the bug * fix the bug * streamline tests a bit
1 parent 856277b commit d5b48db

2 files changed

Lines changed: 211 additions & 18 deletions

File tree

‎webapi/src/main/scala/org/knora/webapi/responders/v2/OntologyResponderV2.scala‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,6 +2753,7 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
27532753
maybeUnescapedNewLinkValuePropertyDef.map { unescapedNewLinkPropertyDef =>
27542754
unescapedNewLinkPropertyDef.propertyIri -> ReadPropertyInfoV2(
27552755
entityInfoContent = unescapedNewLinkPropertyDef,
2756+
isEditable = true,
27562757
isResourceProp = true,
27572758
isLinkValueProp = true
27582759
)
@@ -3277,6 +3278,7 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
32773278
maybeNewLinkValuePropertyDef.map { newLinkPropertyDef: PropertyInfoContentV2 =>
32783279
newLinkPropertyDef.propertyIri -> ReadPropertyInfoV2(
32793280
entityInfoContent = newLinkPropertyDef,
3281+
isEditable = true,
32803282
isResourceProp = true,
32813283
isLinkValueProp = true
32823284
)

‎webapi/src/test/scala/org/knora/webapi/e2e/v2/OntologyV2R2RSpec.scala‎

Lines changed: 209 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ class OntologyV2R2RSpec extends R2RSpec {
216216
private val incunabulaPartOf =
217217
URLEncoder.encode(SharedOntologyTestDataADM.INCUNABULA_PartOf_Property_LocalHost, "UTF-8")
218218

219+
private val anythingOntoLocalhostIri = SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost
220+
private val hasOtherNothingIri = anythingOntoLocalhostIri + "#hasOtherNothing"
221+
private val hasOtherNothingValueIri = anythingOntoLocalhostIri + "#hasOtherNothingValue"
222+
219223
// The URLs and expected response files for each HTTP GET test.
220224
private val httpGetTests = Seq(
221225
HttpGetTest(
@@ -1747,25 +1751,21 @@ class OntologyV2R2RSpec extends R2RSpec {
17471751
}
17481752
}
17491753

1750-
"update the property label and comment and check if the property is still correctly marked as `isEditable: true`" in {
1754+
"update the property label and check if the property is still correctly marked as `isEditable: true`" in {
17511755
// update label and comment of a property
1752-
val ontoIri = SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost
1753-
val propertyIri = ontoIri + "#hasOtherNothing"
1754-
val propertyValueIri = ontoIri + "#hasOtherNothingValue"
1755-
val newLabel = "updated label"
1756-
1756+
val newLabel = "updated label"
17571757
val params =
17581758
s"""
17591759
|{
1760-
| "@id" : "$ontoIri",
1760+
| "@id" : "$anythingOntoLocalhostIri",
17611761
| "@type": "owl:Ontology",
17621762
| "knora-api:lastModificationDate" : {
17631763
| "@type" : "xsd:dateTimeStamp",
17641764
| "@value" : "$anythingLastModDate"
17651765
| },
17661766
| "@graph": [
17671767
| {
1768-
| "@id": "$propertyIri",
1768+
| "@id": "$hasOtherNothingIri",
17691769
| "@type" : "owl:ObjectProperty",
17701770
| "rdfs:label": {
17711771
| "@language": "en",
@@ -1780,8 +1780,7 @@ class OntologyV2R2RSpec extends R2RSpec {
17801780
| "xsd" : "http://www.w3.org/2001/XMLSchema#",
17811781
| "rdfs" : "http://www.w3.org/2000/01/rdf-schema#"
17821782
| }
1783-
|}
1784-
""".stripMargin
1783+
|}""".stripMargin
17851784

17861785
Put("/v2/ontologies/properties", HttpEntity(RdfMediaTypes.`application/ld+json`, params)) ~> addCredentials(
17871786
BasicHttpCredentials(anythingUsername, password)
@@ -1791,11 +1790,11 @@ class OntologyV2R2RSpec extends R2RSpec {
17911790
assert(status == StatusCodes.OK, response.toString)
17921791
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
17931792
val updatedOntologyIri = responseJsonDoc.body.value("@id").asInstanceOf[JsonLDString].value
1794-
assert(updatedOntologyIri == ontoIri)
1793+
assert(updatedOntologyIri == anythingOntoLocalhostIri)
17951794
val graph = responseJsonDoc.body.requireArray("@graph").value
17961795
val property = graph.head.asInstanceOf[JsonLDObject]
17971796
val returnedPropertyIri = property.requireString("@id")
1798-
returnedPropertyIri should equal(propertyIri)
1797+
returnedPropertyIri should equal(hasOtherNothingIri)
17991798
val returnedLabel = property.requireObject(OntologyConstants.Rdfs.Label).requireString("@value")
18001799
returnedLabel should equal(newLabel)
18011800
val lastModDate = responseJsonDoc.body.requireDatatypeValueInObject(
@@ -1817,7 +1816,199 @@ class OntologyV2R2RSpec extends R2RSpec {
18171816
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
18181817

18191818
val graph = responseJsonDoc.body.requireArray("@graph").value.map(_.asInstanceOf[JsonLDObject])
1820-
val nothingValue = graph.filter(_.requireString("@id") == propertyValueIri).head
1819+
val nothingValue = graph.filter(_.requireString("@id") == hasOtherNothingValueIri).head
1820+
val isEditableMaybe = nothingValue.maybeBoolean(OntologyConstants.KnoraApiV2Complex.IsEditable)
1821+
isEditableMaybe should equal(Some(true))
1822+
}
1823+
}
1824+
}
1825+
1826+
"update the property comment and check if the property is still correctly marked as `isEditable: true`" in {
1827+
// update label and comment of a property
1828+
val newComment = "updated comment"
1829+
1830+
val params =
1831+
s"""
1832+
|{
1833+
| "@id" : "$anythingOntoLocalhostIri",
1834+
| "@type": "owl:Ontology",
1835+
| "knora-api:lastModificationDate" : {
1836+
| "@type" : "xsd:dateTimeStamp",
1837+
| "@value" : "$anythingLastModDate"
1838+
| },
1839+
| "@graph": [
1840+
| {
1841+
| "@id": "$hasOtherNothingIri",
1842+
| "@type" : "owl:ObjectProperty",
1843+
| "rdfs:comment": {
1844+
| "@language": "en",
1845+
| "@value": "$newComment"
1846+
| }
1847+
| }
1848+
| ],
1849+
| "@context" : {
1850+
| "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
1851+
| "knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
1852+
| "owl" : "http://www.w3.org/2002/07/owl#",
1853+
| "xsd" : "http://www.w3.org/2001/XMLSchema#",
1854+
| "rdfs" : "http://www.w3.org/2000/01/rdf-schema#"
1855+
| }
1856+
|}""".stripMargin
1857+
1858+
Put("/v2/ontologies/properties", HttpEntity(RdfMediaTypes.`application/ld+json`, params)) ~> addCredentials(
1859+
BasicHttpCredentials(anythingUsername, password)
1860+
) ~> ontologiesPath ~> check {
1861+
val responseStr = responseAs[String]
1862+
1863+
assert(status == StatusCodes.OK, response.toString)
1864+
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
1865+
val updatedOntologyIri = responseJsonDoc.body.value("@id").asInstanceOf[JsonLDString].value
1866+
assert(updatedOntologyIri == anythingOntoLocalhostIri)
1867+
val graph = responseJsonDoc.body.requireArray("@graph").value
1868+
val property = graph.head.asInstanceOf[JsonLDObject]
1869+
val returnedPropertyIri = property.requireString("@id")
1870+
returnedPropertyIri should equal(hasOtherNothingIri)
1871+
val returnedComment = property.requireObject(OntologyConstants.Rdfs.Comment).requireString("@value")
1872+
returnedComment should equal(newComment)
1873+
val lastModDate = responseJsonDoc.body.requireDatatypeValueInObject(
1874+
key = OntologyConstants.KnoraApiV2Complex.LastModificationDate,
1875+
expectedDatatype = OntologyConstants.Xsd.DateTimeStamp.toSmartIri,
1876+
validationFun = stringFormatter.xsdDateTimeStampToInstant
1877+
)
1878+
1879+
assert(lastModDate.isAfter(fooLastModDate))
1880+
anythingLastModDate = lastModDate
1881+
1882+
// load back the ontology to verify that the updated property still is editable
1883+
val encodedIri = URLEncoder.encode(s"${SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost}", "UTF-8")
1884+
Get(
1885+
s"/v2/ontologies/allentities/${encodedIri}"
1886+
) ~> ontologiesPath ~> check {
1887+
val responseStr: String = responseAs[String]
1888+
assert(status == StatusCodes.OK, response.toString)
1889+
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
1890+
1891+
val graph = responseJsonDoc.body.requireArray("@graph").value.map(_.asInstanceOf[JsonLDObject])
1892+
val nothingValue = graph.filter(_.requireString("@id") == hasOtherNothingValueIri).head
1893+
val isEditableMaybe = nothingValue.maybeBoolean(OntologyConstants.KnoraApiV2Complex.IsEditable)
1894+
isEditableMaybe should equal(Some(true))
1895+
}
1896+
}
1897+
}
1898+
1899+
"delete the property comment and check if the property is still correctly marked as `isEditable: true`" in {
1900+
// update label and comment of a property
1901+
val propertyIriEncoded = URLEncoder.encode(hasOtherNothingIri, "UTF-8")
1902+
1903+
Delete(
1904+
s"/v2/ontologies/properties/comment/$propertyIriEncoded?lastModificationDate=$anythingLastModDate"
1905+
) ~> addCredentials(
1906+
BasicHttpCredentials(anythingUsername, password)
1907+
) ~> ontologiesPath ~> check {
1908+
val responseStr = responseAs[String]
1909+
1910+
assert(status == StatusCodes.OK, response.toString)
1911+
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
1912+
val updatedOntologyIri = responseJsonDoc.body.value("@id").asInstanceOf[JsonLDString].value
1913+
assert(updatedOntologyIri == anythingOntoLocalhostIri)
1914+
val graph = responseJsonDoc.body.requireArray("@graph").value
1915+
val property = graph.head.asInstanceOf[JsonLDObject]
1916+
val returnedPropertyIri = property.requireString("@id")
1917+
returnedPropertyIri should equal(hasOtherNothingIri)
1918+
assert(property.value.get(OntologyConstants.Rdfs.Comment) == None)
1919+
val lastModDate = responseJsonDoc.body.requireDatatypeValueInObject(
1920+
key = OntologyConstants.KnoraApiV2Complex.LastModificationDate,
1921+
expectedDatatype = OntologyConstants.Xsd.DateTimeStamp.toSmartIri,
1922+
validationFun = stringFormatter.xsdDateTimeStampToInstant
1923+
)
1924+
1925+
assert(lastModDate.isAfter(fooLastModDate))
1926+
anythingLastModDate = lastModDate
1927+
1928+
// load back the ontology to verify that the updated property still is editable
1929+
val encodedIri = URLEncoder.encode(s"${SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost}", "UTF-8")
1930+
Get(
1931+
s"/v2/ontologies/allentities/${encodedIri}"
1932+
) ~> ontologiesPath ~> check {
1933+
val responseStr: String = responseAs[String]
1934+
assert(status == StatusCodes.OK, response.toString)
1935+
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
1936+
1937+
val graph = responseJsonDoc.body.requireArray("@graph").value.map(_.asInstanceOf[JsonLDObject])
1938+
val nothingValue = graph.filter(_.requireString("@id") == hasOtherNothingValueIri).head
1939+
val isEditableMaybe = nothingValue.maybeBoolean(OntologyConstants.KnoraApiV2Complex.IsEditable)
1940+
isEditableMaybe should equal(Some(true))
1941+
}
1942+
}
1943+
}
1944+
1945+
"update the property guiElement and check if the property is still correctly marked as `isEditable: true`" in {
1946+
// update label and comment of a property
1947+
1948+
val params =
1949+
s"""
1950+
|{
1951+
| "@id" : "$anythingOntoLocalhostIri",
1952+
| "@type": "owl:Ontology",
1953+
| "knora-api:lastModificationDate" : {
1954+
| "@type" : "xsd:dateTimeStamp",
1955+
| "@value" : "$anythingLastModDate"
1956+
| },
1957+
| "@graph": [
1958+
| {
1959+
| "@id": "$hasOtherNothingIri",
1960+
| "@type" : "owl:ObjectProperty",
1961+
| "salsah-gui:guiElement": {
1962+
| "@id": "salsah-gui:Searchbox"
1963+
| }
1964+
| }
1965+
| ],
1966+
| "@context" : {
1967+
| "rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
1968+
| "knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
1969+
| "salsah-gui": "http://api.knora.org/ontology/salsah-gui/v2#",
1970+
| "owl" : "http://www.w3.org/2002/07/owl#",
1971+
| "xsd" : "http://www.w3.org/2001/XMLSchema#",
1972+
| "rdfs" : "http://www.w3.org/2000/01/rdf-schema#"
1973+
| }
1974+
|}""".stripMargin
1975+
1976+
Put(
1977+
"/v2/ontologies/properties/guielement",
1978+
HttpEntity(RdfMediaTypes.`application/ld+json`, params)
1979+
) ~> addCredentials(
1980+
BasicHttpCredentials(anythingUsername, password)
1981+
) ~> ontologiesPath ~> check {
1982+
val responseStr = responseAs[String]
1983+
1984+
assert(status == StatusCodes.OK, response.toString)
1985+
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
1986+
val updatedOntologyIri = responseJsonDoc.body.value("@id").asInstanceOf[JsonLDString].value
1987+
assert(updatedOntologyIri == anythingOntoLocalhostIri)
1988+
val graph = responseJsonDoc.body.requireArray("@graph").value
1989+
val property = graph.head.asInstanceOf[JsonLDObject]
1990+
val returnedPropertyIri = property.requireString("@id")
1991+
returnedPropertyIri should equal(hasOtherNothingIri)
1992+
val lastModDate = responseJsonDoc.body.requireDatatypeValueInObject(
1993+
key = OntologyConstants.KnoraApiV2Complex.LastModificationDate,
1994+
expectedDatatype = OntologyConstants.Xsd.DateTimeStamp.toSmartIri,
1995+
validationFun = stringFormatter.xsdDateTimeStampToInstant
1996+
)
1997+
1998+
assert(lastModDate.isAfter(fooLastModDate))
1999+
anythingLastModDate = lastModDate
2000+
2001+
// load back the ontology to verify that the updated property still is editable
2002+
val encodedIri = URLEncoder.encode(s"${SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost}", "UTF-8")
2003+
Get(
2004+
s"/v2/ontologies/allentities/${encodedIri}"
2005+
) ~> ontologiesPath ~> check {
2006+
val responseStr: String = responseAs[String]
2007+
assert(status == StatusCodes.OK, response.toString)
2008+
val responseJsonDoc = JsonLDUtil.parseJsonLD(responseStr)
2009+
2010+
val graph = responseJsonDoc.body.requireArray("@graph").value.map(_.asInstanceOf[JsonLDObject])
2011+
val nothingValue = graph.filter(_.requireString("@id") == hasOtherNothingValueIri).head
18212012
val isEditableMaybe = nothingValue.maybeBoolean(OntologyConstants.KnoraApiV2Complex.IsEditable)
18222013
isEditableMaybe should equal(Some(true))
18232014
}
@@ -2369,7 +2560,7 @@ class OntologyV2R2RSpec extends R2RSpec {
23692560
| "knora-api": "${OntologyConstants.KnoraApiV2Complex.KnoraApiV2PrefixExpansion}"
23702561
| }
23712562
|}
2372-
""".stripMargin
2563+
""".stripMargin
23732564

23742565
Post("/v2/ontologies", HttpEntity(RdfMediaTypes.`application/ld+json`, createOntologyJson)) ~> addCredentials(
23752566
BasicHttpCredentials(superUsername, password)
@@ -2427,7 +2618,7 @@ class OntologyV2R2RSpec extends R2RSpec {
24272618
| "useless" : "${uselessIri.get}#"
24282619
| }
24292620
|}
2430-
""".stripMargin
2621+
""".stripMargin
24312622

24322623
// Convert the submitted JSON-LD to an InputOntologyV2, without SPARQL-escaping, so we can compare it to the response.
24332624
val paramsAsInput: InputOntologyV2 =
@@ -2715,7 +2906,7 @@ class OntologyV2R2RSpec extends R2RSpec {
27152906
| "anything" : "${SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost}#"
27162907
| }
27172908
|}
2718-
""".stripMargin
2909+
""".stripMargin
27192910

27202911
Post(
27212912
"/v2/ontologies/cardinalities",
@@ -2767,7 +2958,7 @@ class OntologyV2R2RSpec extends R2RSpec {
27672958
| "anything" : "${SharedOntologyTestDataADM.ANYTHING_ONTOLOGY_IRI_LocalHost}#"
27682959
| }
27692960
|}
2770-
""".stripMargin
2961+
""".stripMargin
27712962

27722963
Put("/v2/ontologies/cardinalities", HttpEntity(RdfMediaTypes.`application/ld+json`, params)) ~> addCredentials(
27732964
BasicHttpCredentials(anythingUsername, password)
@@ -2998,7 +3189,7 @@ class OntologyV2R2RSpec extends R2RSpec {
29983189
| "freetest" : "${SharedOntologyTestDataADM.FREETEST_ONTOLOGY_IRI_LocalHost}#"
29993190
| }
30003191
|}
3001-
""".stripMargin
3192+
""".stripMargin
30023193

30033194
CollectClientTestData("candeletecardinalities-true-request", params)
30043195

0 commit comments

Comments
 (0)