Skip to content

Commit 6a13852

Browse files
author
Benjamin Geer
authored
feat(api-v2): Allow resubmitting existing class/property lablels/comments. (#1812)
1 parent 3fead13 commit 6a13852

2 files changed

Lines changed: 148 additions & 26 deletions

File tree

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

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3744,19 +3744,6 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
37443744
featureFactoryConfig = changePropertyLabelsOrCommentsRequest.featureFactoryConfig
37453745
)
37463746

3747-
// Check that the new labels/comments are different from the current ones.
3748-
3749-
currentLabelsOrComments: Seq[OntologyLiteralV2] = currentReadPropertyInfo.entityInfoContent.predicates
3750-
.get(changePropertyLabelsOrCommentsRequest.predicateToUpdate) match {
3751-
case Some(pred) => pred.objects
3752-
case None => Seq.empty[OntologyLiteralV2]
3753-
}
3754-
3755-
_ = if (currentLabelsOrComments == changePropertyLabelsOrCommentsRequest.newObjects) {
3756-
throw BadRequestException(
3757-
s"The submitted objects of ${changePropertyLabelsOrCommentsRequest.propertyIri} are the same as the current ones in property ${changePropertyLabelsOrCommentsRequest.propertyIri}")
3758-
}
3759-
37603747
// If this is a link property, also change the labels/comments of the corresponding link value property.
37613748

37623749
maybeCurrentLinkValueReadPropertyInfo: Option[ReadPropertyInfoV2] = if (currentReadPropertyInfo.isLinkProp) {
@@ -3937,19 +3924,6 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
39373924
featureFactoryConfig = changeClassLabelsOrCommentsRequest.featureFactoryConfig
39383925
)
39393926

3940-
// Check that the new labels/comments are different from the current ones.
3941-
3942-
currentLabelsOrComments: Seq[OntologyLiteralV2] = currentReadClassInfo.entityInfoContent.predicates
3943-
.get(changeClassLabelsOrCommentsRequest.predicateToUpdate) match {
3944-
case Some(pred) => pred.objects
3945-
case None => Seq.empty[OntologyLiteralV2]
3946-
}
3947-
3948-
_ = if (currentLabelsOrComments == changeClassLabelsOrCommentsRequest.newObjects) {
3949-
throw BadRequestException(
3950-
s"The submitted objects of ${changeClassLabelsOrCommentsRequest.predicateToUpdate} are the same as the current ones in class ${changeClassLabelsOrCommentsRequest.classIri}")
3951-
}
3952-
39533927
// Do the update.
39543928

39553929
currentTime: Instant = Instant.now

‎webapi/src/test/scala/org/knora/webapi/responders/v2/OntologyResponderV2Spec.scala‎

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,41 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
19501950
}
19511951
}
19521952

1953+
"change the labels of a property, submitting the same labels again" in {
1954+
val propertyIri = AnythingOntologyIri.makeEntityIri("hasName")
1955+
1956+
val newObjects = Seq(
1957+
StringLiteralV2("has name", Some("en")),
1958+
StringLiteralV2("a nom", Some("fr")),
1959+
StringLiteralV2("hat Namen", Some("de"))
1960+
)
1961+
1962+
responderManager ! ChangePropertyLabelsOrCommentsRequestV2(
1963+
propertyIri = propertyIri,
1964+
predicateToUpdate = OntologyConstants.Rdfs.Label.toSmartIri,
1965+
newObjects = newObjects,
1966+
lastModificationDate = anythingLastModDate,
1967+
apiRequestID = UUID.randomUUID,
1968+
featureFactoryConfig = defaultFeatureFactoryConfig,
1969+
requestingUser = anythingAdminUser
1970+
)
1971+
1972+
expectMsgPF(timeout) {
1973+
case msg: ReadOntologyV2 =>
1974+
val externalOntology = msg.toOntologySchema(ApiV2Complex)
1975+
assert(externalOntology.properties.size == 1)
1976+
val readPropertyInfo = externalOntology.properties(propertyIri)
1977+
readPropertyInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Label.toSmartIri).objects should ===(
1978+
newObjects)
1979+
1980+
val metadata = externalOntology.ontologyMetadata
1981+
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
1982+
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
1983+
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
1984+
anythingLastModDate = newAnythingLastModDate
1985+
}
1986+
}
1987+
19531988
"not allow a user to change the comments of a property if they are not a sysadmin or an admin in the ontology's project" in {
19541989

19551990
val propertyIri = AnythingOntologyIri.makeEntityIri("hasName")
@@ -2018,6 +2053,46 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
20182053
}
20192054
}
20202055

2056+
"change the comments of a property, submitting the same comments again" in {
2057+
val propertyIri = AnythingOntologyIri.makeEntityIri("hasName")
2058+
2059+
val newObjects = Seq(
2060+
StringLiteralV2("The name of a Thing", Some("en")),
2061+
StringLiteralV2("Le nom d\\'une chose", Some("fr")), // This is SPARQL-escaped as it would be if taken from a JSON-LD request.
2062+
StringLiteralV2("Der Name eines Dinges", Some("de"))
2063+
)
2064+
2065+
// Make an unescaped copy of the new comments, because this is how we will receive them in the API response.
2066+
val newObjectsUnescaped = newObjects.map {
2067+
case StringLiteralV2(text, lang) => StringLiteralV2(stringFormatter.fromSparqlEncodedString(text), lang)
2068+
}
2069+
2070+
responderManager ! ChangePropertyLabelsOrCommentsRequestV2(
2071+
propertyIri = propertyIri,
2072+
predicateToUpdate = OntologyConstants.Rdfs.Comment.toSmartIri,
2073+
newObjects = newObjects,
2074+
lastModificationDate = anythingLastModDate,
2075+
apiRequestID = UUID.randomUUID,
2076+
featureFactoryConfig = defaultFeatureFactoryConfig,
2077+
requestingUser = anythingAdminUser
2078+
)
2079+
2080+
expectMsgPF(timeout) {
2081+
case msg: ReadOntologyV2 =>
2082+
val externalOntology = msg.toOntologySchema(ApiV2Complex)
2083+
assert(externalOntology.properties.size == 1)
2084+
val readPropertyInfo = externalOntology.properties(propertyIri)
2085+
readPropertyInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Comment.toSmartIri).objects should ===(
2086+
newObjectsUnescaped)
2087+
2088+
val metadata = externalOntology.ontologyMetadata
2089+
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
2090+
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
2091+
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
2092+
anythingLastModDate = newAnythingLastModDate
2093+
}
2094+
}
2095+
20212096
"not allow a user to create a class if they are not a sysadmin or an admin in the ontology's project" in {
20222097

20232098
val classIri = AnythingOntologyIri.makeEntityIri("WildThing")
@@ -2449,6 +2524,40 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
24492524
}
24502525
}
24512526

2527+
"change the labels of a class, submitting the same labels again" in {
2528+
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
2529+
2530+
val newObjects = Seq(
2531+
StringLiteralV2("nothing", Some("en")),
2532+
StringLiteralV2("rien", Some("fr"))
2533+
)
2534+
2535+
responderManager ! ChangeClassLabelsOrCommentsRequestV2(
2536+
classIri = classIri,
2537+
predicateToUpdate = OntologyConstants.Rdfs.Label.toSmartIri,
2538+
newObjects = newObjects,
2539+
lastModificationDate = anythingLastModDate,
2540+
apiRequestID = UUID.randomUUID,
2541+
featureFactoryConfig = defaultFeatureFactoryConfig,
2542+
requestingUser = anythingAdminUser
2543+
)
2544+
2545+
expectMsgPF(timeout) {
2546+
case msg: ReadOntologyV2 =>
2547+
val externalOntology = msg.toOntologySchema(ApiV2Complex)
2548+
assert(externalOntology.classes.size == 1)
2549+
val readClassInfo = externalOntology.classes(classIri)
2550+
readClassInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Label.toSmartIri).objects should ===(
2551+
newObjects)
2552+
2553+
val metadata = externalOntology.ontologyMetadata
2554+
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
2555+
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
2556+
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
2557+
anythingLastModDate = newAnythingLastModDate
2558+
}
2559+
}
2560+
24522561
"not allow a user to change the comments of a class if they are not a sysadmin or an admin in the ontology's project" in {
24532562

24542563
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
@@ -2513,6 +2622,45 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
25132622
}
25142623
}
25152624

2625+
"change the comments of a class, submitting the same comments again" in {
2626+
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
2627+
2628+
val newObjects = Seq(
2629+
StringLiteralV2("Represents nothing", Some("en")),
2630+
StringLiteralV2("ne représente rien", Some("fr"))
2631+
)
2632+
2633+
// Make an unescaped copy of the new comments, because this is how we will receive them in the API response.
2634+
val newObjectsUnescaped = newObjects.map {
2635+
case StringLiteralV2(text, lang) => StringLiteralV2(stringFormatter.fromSparqlEncodedString(text), lang)
2636+
}
2637+
2638+
responderManager ! ChangeClassLabelsOrCommentsRequestV2(
2639+
classIri = classIri,
2640+
predicateToUpdate = OntologyConstants.Rdfs.Comment.toSmartIri,
2641+
newObjects = newObjects,
2642+
lastModificationDate = anythingLastModDate,
2643+
apiRequestID = UUID.randomUUID,
2644+
featureFactoryConfig = defaultFeatureFactoryConfig,
2645+
requestingUser = anythingAdminUser
2646+
)
2647+
2648+
expectMsgPF(timeout) {
2649+
case msg: ReadOntologyV2 =>
2650+
val externalOntology = msg.toOntologySchema(ApiV2Complex)
2651+
assert(externalOntology.classes.size == 1)
2652+
val readClassInfo = externalOntology.classes(classIri)
2653+
readClassInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Comment.toSmartIri).objects should ===(
2654+
newObjectsUnescaped)
2655+
2656+
val metadata = externalOntology.ontologyMetadata
2657+
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
2658+
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
2659+
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
2660+
anythingLastModDate = newAnythingLastModDate
2661+
}
2662+
}
2663+
25162664
"not create a class with the wrong rdf:type" in {
25172665
val classIri = AnythingOntologyIri.makeEntityIri("WrongClass")
25182666

0 commit comments

Comments
 (0)