Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api-v2): Allow resubmitting existing class/property lablels/comments (DSP-1323, DSP-1324) #1812

Merged
merged 2 commits into from Feb 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -3744,19 +3744,6 @@ class OntologyResponderV2(responderData: ResponderData) extends Responder(respon
featureFactoryConfig = changePropertyLabelsOrCommentsRequest.featureFactoryConfig
)

// Check that the new labels/comments are different from the current ones.

currentLabelsOrComments: Seq[OntologyLiteralV2] = currentReadPropertyInfo.entityInfoContent.predicates
.get(changePropertyLabelsOrCommentsRequest.predicateToUpdate) match {
case Some(pred) => pred.objects
case None => Seq.empty[OntologyLiteralV2]
}

_ = if (currentLabelsOrComments == changePropertyLabelsOrCommentsRequest.newObjects) {
throw BadRequestException(
s"The submitted objects of ${changePropertyLabelsOrCommentsRequest.propertyIri} are the same as the current ones in property ${changePropertyLabelsOrCommentsRequest.propertyIri}")
}

// If this is a link property, also change the labels/comments of the corresponding link value property.

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

// Check that the new labels/comments are different from the current ones.

currentLabelsOrComments: Seq[OntologyLiteralV2] = currentReadClassInfo.entityInfoContent.predicates
.get(changeClassLabelsOrCommentsRequest.predicateToUpdate) match {
case Some(pred) => pred.objects
case None => Seq.empty[OntologyLiteralV2]
}

_ = if (currentLabelsOrComments == changeClassLabelsOrCommentsRequest.newObjects) {
throw BadRequestException(
s"The submitted objects of ${changeClassLabelsOrCommentsRequest.predicateToUpdate} are the same as the current ones in class ${changeClassLabelsOrCommentsRequest.classIri}")
}

// Do the update.

currentTime: Instant = Instant.now
Expand Down
Expand Up @@ -1950,6 +1950,41 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
}
}

"change the labels of a property, submitting the same labels again" in {
val propertyIri = AnythingOntologyIri.makeEntityIri("hasName")

val newObjects = Seq(
StringLiteralV2("has name", Some("en")),
StringLiteralV2("a nom", Some("fr")),
StringLiteralV2("hat Namen", Some("de"))
)

responderManager ! ChangePropertyLabelsOrCommentsRequestV2(
propertyIri = propertyIri,
predicateToUpdate = OntologyConstants.Rdfs.Label.toSmartIri,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
featureFactoryConfig = defaultFeatureFactoryConfig,
requestingUser = anythingAdminUser
)

expectMsgPF(timeout) {
case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.properties.size == 1)
val readPropertyInfo = externalOntology.properties(propertyIri)
readPropertyInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Label.toSmartIri).objects should ===(
newObjects)

val metadata = externalOntology.ontologyMetadata
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
anythingLastModDate = newAnythingLastModDate
}
}

"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 {

val propertyIri = AnythingOntologyIri.makeEntityIri("hasName")
Expand Down Expand Up @@ -2018,6 +2053,46 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
}
}

"change the comments of a property, submitting the same comments again" in {
val propertyIri = AnythingOntologyIri.makeEntityIri("hasName")

val newObjects = Seq(
StringLiteralV2("The name of a Thing", Some("en")),
StringLiteralV2("Le nom d\\'une chose", Some("fr")), // This is SPARQL-escaped as it would be if taken from a JSON-LD request.
StringLiteralV2("Der Name eines Dinges", Some("de"))
)

// Make an unescaped copy of the new comments, because this is how we will receive them in the API response.
val newObjectsUnescaped = newObjects.map {
case StringLiteralV2(text, lang) => StringLiteralV2(stringFormatter.fromSparqlEncodedString(text), lang)
}

responderManager ! ChangePropertyLabelsOrCommentsRequestV2(
propertyIri = propertyIri,
predicateToUpdate = OntologyConstants.Rdfs.Comment.toSmartIri,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
featureFactoryConfig = defaultFeatureFactoryConfig,
requestingUser = anythingAdminUser
)

expectMsgPF(timeout) {
case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.properties.size == 1)
val readPropertyInfo = externalOntology.properties(propertyIri)
readPropertyInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Comment.toSmartIri).objects should ===(
newObjectsUnescaped)

val metadata = externalOntology.ontologyMetadata
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
anythingLastModDate = newAnythingLastModDate
}
}

"not allow a user to create a class if they are not a sysadmin or an admin in the ontology's project" in {

val classIri = AnythingOntologyIri.makeEntityIri("WildThing")
Expand Down Expand Up @@ -2449,6 +2524,40 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
}
}

"change the labels of a class, submitting the same labels again" in {
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")

val newObjects = Seq(
StringLiteralV2("nothing", Some("en")),
StringLiteralV2("rien", Some("fr"))
)

responderManager ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = OntologyConstants.Rdfs.Label.toSmartIri,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
featureFactoryConfig = defaultFeatureFactoryConfig,
requestingUser = anythingAdminUser
)

expectMsgPF(timeout) {
case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.classes.size == 1)
val readClassInfo = externalOntology.classes(classIri)
readClassInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Label.toSmartIri).objects should ===(
newObjects)

val metadata = externalOntology.ontologyMetadata
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
anythingLastModDate = newAnythingLastModDate
}
}

"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 {

val classIri = AnythingOntologyIri.makeEntityIri("Nothing")
Expand Down Expand Up @@ -2513,6 +2622,45 @@ class OntologyResponderV2Spec extends CoreSpec() with ImplicitSender {
}
}

"change the comments of a class, submitting the same comments again" in {
val classIri = AnythingOntologyIri.makeEntityIri("Nothing")

val newObjects = Seq(
StringLiteralV2("Represents nothing", Some("en")),
StringLiteralV2("ne représente rien", Some("fr"))
)

// Make an unescaped copy of the new comments, because this is how we will receive them in the API response.
val newObjectsUnescaped = newObjects.map {
case StringLiteralV2(text, lang) => StringLiteralV2(stringFormatter.fromSparqlEncodedString(text), lang)
}

responderManager ! ChangeClassLabelsOrCommentsRequestV2(
classIri = classIri,
predicateToUpdate = OntologyConstants.Rdfs.Comment.toSmartIri,
newObjects = newObjects,
lastModificationDate = anythingLastModDate,
apiRequestID = UUID.randomUUID,
featureFactoryConfig = defaultFeatureFactoryConfig,
requestingUser = anythingAdminUser
)

expectMsgPF(timeout) {
case msg: ReadOntologyV2 =>
val externalOntology = msg.toOntologySchema(ApiV2Complex)
assert(externalOntology.classes.size == 1)
val readClassInfo = externalOntology.classes(classIri)
readClassInfo.entityInfoContent.predicates(OntologyConstants.Rdfs.Comment.toSmartIri).objects should ===(
newObjectsUnescaped)

val metadata = externalOntology.ontologyMetadata
val newAnythingLastModDate = metadata.lastModificationDate.getOrElse(
throw AssertionException(s"${metadata.ontologyIri} has no last modification date"))
assert(newAnythingLastModDate.isAfter(anythingLastModDate))
anythingLastModDate = newAnythingLastModDate
}
}

"not create a class with the wrong rdf:type" in {
val classIri = AnythingOntologyIri.makeEntityIri("WrongClass")

Expand Down