Skip to content

Commit

Permalink
BUG FIXES: author is now updating. Blank author, rankLevel, rankName …
Browse files Browse the repository at this point in the history
…will set it to null
  • Loading branch information
hohonuuli committed Nov 18, 2024
1 parent d6860bc commit 875e9bb
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,10 @@

package org.mbari.oni.services

import org.mbari.oni.domain.{
ConceptNameCreate,
ConceptNameTypes,
ConceptNameUpdate,
RawConcept,
RawConceptName,
UserAccount,
UserAccountRoles
}
import org.mbari.oni.domain.{ConceptNameCreate, ConceptNameTypes, ConceptNameUpdate, RawConcept, RawConceptName, UserAccount, UserAccountRoles}
import org.mbari.oni.jpa.DataInitializer
import org.mbari.oni.etc.circe.CirceCodecs.{*, given}
import org.mbari.oni.etc.jdk.Strings
import org.mbari.oni.jpa.entities.TestEntityFactory

trait ConceptNameServiceSuite extends DataInitializer with UserAuthMixin:
Expand Down Expand Up @@ -95,7 +88,7 @@ trait ConceptNameServiceSuite extends DataInitializer with UserAuthMixin:
val rawRoot = RawConcept.from(root)
val name = rawRoot.primaryName
val dto =
ConceptNameUpdate(newName = Some("newName"), nameType = Some(ConceptNameTypes.PRIMARY.getType))
ConceptNameUpdate(newName = Some("newName"), nameType = Some(ConceptNameTypes.PRIMARY.getType), author = Some(Strings.random(5)))

val attempt = runWithUserAuth(user => conceptNameService.updateName(name, dto, user.username))

Expand All @@ -105,10 +98,36 @@ trait ConceptNameServiceSuite extends DataInitializer with UserAuthMixin:
val obtained = rawConcept.names.map(_.name).toSeq
assert(!obtained.contains(name))
assert(obtained.contains(dto.newName.getOrElse("")))
val updatedNameOpt = rawConcept.names.find(_.name == dto.newName.getOrElse(""))
assert(updatedNameOpt.isDefined)
val updatedName = updatedNameOpt.get
assertEquals(updatedName.nameType, ConceptNameTypes.PRIMARY.getType)
assertEquals(updatedName.author, dto.author)
case Left(error) =>
fail(error.toString)
}

test("updateName with blank author - changes author to null in the database") {

val root = init(3, 3)
assert(root != null)
val rawRoot = RawConcept.from(root)
val name = rawRoot.primaryName
val dto =
ConceptNameUpdate(author = Some(""))

val attempt = runWithUserAuth(user => conceptNameService.updateName(name, dto, user.username))

attempt match
case Right(rawConcept) =>
val updatedNameOpt = rawConcept.names.find(_.name == name)
assert(updatedNameOpt.isDefined)
val updatedName = updatedNameOpt.get
assertEquals(updatedName.author, dto.author)
case Left(error) =>
fail(error.toString)
}

test("updateName (attempt to change primary to non-primary)") {

val root = init(3, 3)
Expand Down
26 changes: 26 additions & 0 deletions it/src/main/scala/org/mbari/oni/services/ConceptServiceSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,32 @@ trait ConceptServiceSuite extends DatabaseFunSuite with UserAuthMixin:

}

test("update to remove rank name and rank level") {
val root = TestEntityFactory.buildRoot(2)
root.setRankName("genus")
root.setRankLevel("sub")
val attempt = runWithUserAuth(user =>
for
rootEntity <- conceptService.init(root)
updated <- conceptService.update(
root.getPrimaryConceptName.getName,
ConceptUpdate(rankName = Some(""), rankLevel = Some("")),
user.username
)
yield updated
)

attempt match
case Left(e) =>
fail("Failed to update")
case Right(_) =>
conceptService.findByName(root.getPrimaryConceptName.getName) match
case Left(_) =>
case Right(conceptMetadata) =>
assertEquals(conceptMetadata.rankName, None)
assertEquals(conceptMetadata.rankLevel, None)
}

test("delete") {

val root = TestEntityFactory.buildRoot(3, 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class ConceptEndpoints(entityManagerFactory: EntityManagerFactory)(using jwtServ
.serverSecurityLogic(jwtOpt => verifyLoginAsync(jwtOpt))
.serverLogic { userAccount => conceptCreate =>
handleErrorsAsync(service.create(conceptCreate, userAccount.username))
.andThen(v =>
conceptCache.clear()
v
)
}

val deleteEndpoint: Endpoint[Option[String], String, ErrorMsg, Unit, Any] = secureEndpoint
Expand All @@ -75,6 +79,9 @@ class ConceptEndpoints(entityManagerFactory: EntityManagerFactory)(using jwtServ
error => Left(ServerError(error.getMessage)),
_ => Right(())
)
).andThen(v =>
conceptCache.clear()
v
)
}

Expand Down Expand Up @@ -145,7 +152,7 @@ class ConceptEndpoints(entityManagerFactory: EntityManagerFactory)(using jwtServ
.in(jsonBody[ConceptUpdate])
.out(jsonBody[ConceptMetadata])
.name("updateConcept")
.description("Update a concept")
.description("Update a concept. To remove a rank name or level, set it to an empty string. Only administrators can remove rank names and levels.")
.tag(tag)

val updateEndpointImpl: ServerEndpoint[Any, Future] = updateEndpoint
Expand All @@ -158,6 +165,10 @@ class ConceptEndpoints(entityManagerFactory: EntityManagerFactory)(using jwtServ
concept => Right(concept)
)
)
.andThen(v =>
conceptCache.clear()
v
)
}

override val all: List[Endpoint[?, ?, ?, ?, ?]] = List(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class ConceptNameEndpoints(entityManagerFactory: EntityManagerFactory)(using jwt
.in(jsonBody[ConceptNameUpdate])
.out(jsonBody[RawConcept])
.name("updateConceptName")
.description("Update a concept name")
.description("Update a concept name. To remove the author, set it to an empty string")
.tag(tag)

val updateConceptNameEndpointImpl: ServerEndpoint[Any, Future] = updateConceptNameEndpoint
Expand Down
12 changes: 12 additions & 0 deletions oni/src/main/scala/org/mbari/oni/services/ConceptCache.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
* via any medium is strictly prohibited. Proprietary and confidential.
*/

/*
* Copyright (c) Monterey Bay Aquarium Research Institute 2024
*
* oni code is non-public software. Unauthorized copying of this file,
* via any medium is strictly prohibited. Proprietary and confidential.
*/

package org.mbari.oni.services

import com.github.benmanes.caffeine.cache.{Cache, Caffeine}
Expand Down Expand Up @@ -57,6 +64,11 @@ class ConceptCache(conceptService: ConceptService, conceptNameService: ConceptNa
}
}

def clear(): Unit = {
nameCache.invalidateAll()
allNamesCache.invalidateAll()
}

}

object ConceptCache {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ class ConceptNameService(entityManagerFactory: EntityManagerFactory) extends Con
)
case None => ()

dto.author
.foreach(author =>
if (author.isBlank) existingConceptName.setAuthor(null)
else existingConceptName.setAuthor(author)
)

dto.updateEntity(existingConceptName)

RawConcept.from(existingConceptName.getConcept, false)
Expand Down
28 changes: 20 additions & 8 deletions oni/src/main/scala/org/mbari/oni/services/ConceptService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,16 @@ class ConceptService(entityManagerFactory: EntityManagerFactory):
): Unit =
rankLevel.foreach(v =>
if v != conceptEntity.getRankLevel then
val history = HistoryEntityFactory.replaceRankLevel(userEntity, conceptEntity.getRankLevel, v)
conceptEntity.getConceptMetadata.addHistory(history)
if userEntity.isAdministrator then history.approveBy(userEntity.getUserName)
conceptEntity.setRankLevel(v)
if v.isBlank then
if userEntity.isAdministrator then
conceptEntity.setRankLevel(null)
else
throw new IllegalArgumentException("Rank level can only be removed by an administrator")
else
val history = HistoryEntityFactory.replaceRankLevel(userEntity, conceptEntity.getRankLevel, v)
conceptEntity.getConceptMetadata.addHistory(history)
if userEntity.isAdministrator then history.approveBy(userEntity.getUserName)
conceptEntity.setRankLevel(v)
)

// -- Helper function to update the rank name
Expand All @@ -327,10 +333,16 @@ class ConceptService(entityManagerFactory: EntityManagerFactory):
): Unit =
rankLevel.foreach(v =>
if v != conceptEntity.getRankName then
val history = HistoryEntityFactory.replaceRankName(userEntity, conceptEntity.getRankName, v)
conceptEntity.getConceptMetadata.addHistory(history)
if userEntity.isAdministrator then history.approveBy(userEntity.getUserName)
conceptEntity.setRankName(v)
if v.isBlank then
if userEntity.isAdministrator then
conceptEntity.setRankName(null)
else
throw new IllegalArgumentException("Rank name can only be removed by an administrator")
else
val history = HistoryEntityFactory.replaceRankName(userEntity, conceptEntity.getRankName, v)
conceptEntity.getConceptMetadata.addHistory(history)
if userEntity.isAdministrator then history.approveBy(userEntity.getUserName)
conceptEntity.setRankName(v)
)

// -- Helper function to update the aphia id
Expand Down
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ object Dependencies {
lazy val hibernateEnvers = "org.hibernate.orm" % "hibernate-envers" % hibernateVersion
lazy val hibernateHikari = "org.hibernate.orm" % "hibernate-hikaricp" % hibernateVersion

lazy val hikariCp = "com.zaxxer" % "HikariCP" % "6.1.0"
lazy val hikariCp = "com.zaxxer" % "HikariCP" % "6.2.1"
lazy val jansi = "org.fusesource.jansi" % "jansi" % "2.4.1"
lazy val jaspyt = "org.jasypt" % "jasypt" % "1.9.3"
lazy val junit = "junit" % "junit" % "4.13.2"
Expand Down

0 comments on commit 875e9bb

Please sign in to comment.