Skip to content

Commit

Permalink
M3-122: Added tests for delete duration
Browse files Browse the repository at this point in the history
  • Loading branch information
hohonuuli committed Jun 12, 2020
1 parent ceac629 commit 5db4c8e
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 59 deletions.
45 changes: 31 additions & 14 deletions src/main/scala/org/mbari/vars/annotation/api/v1/ImageV1Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class ImageV1Api(controller: ImageController)(implicit val executor: ExecutionCo
.map({
case None =>
halt(
NotFound(toJson(ErrorMsg(404, s"an Image with an image_reference_uuid of $uuid was not found")))
NotFound(
toJson(ErrorMsg(404, s"an Image with an image_reference_uuid of $uuid was not found"))
)
)
case Some(v) => toJson(v)
})
Expand All @@ -57,7 +59,9 @@ class ImageV1Api(controller: ImageController)(implicit val executor: ExecutionCo
get("/videoreference/:uuid") {
val uuid = params
.getAs[UUID]("uuid")
.getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "A video reference 'uuid' parameter is required")))))
.getOrElse(
halt(BadRequest(toJson(ErrorMsg(400, "A video reference 'uuid' parameter is required"))))
)
val limit = params.getAs[Int]("limit")
val offset = params.getAs[Int]("offset")
controller
Expand All @@ -69,28 +73,31 @@ class ImageV1Api(controller: ImageController)(implicit val executor: ExecutionCo
get("/name/:name") {
val name = params
.get("name")
.getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "An image name is required as part of the path")))))
.getOrElse(
halt(BadRequest(toJson(ErrorMsg(400, "An image name is required as part of the path"))))
)
controller
.findByImageName(name)
.map(_.asJava)
.map(toJson)
}

// URL should be encoded e.g. URLEncoder.encode(...)
get("/url/:url") {
get("/url/*") {
// val url = params.get("url")
// .map(URLDecoder.decode(_, "UTF-8"))
// .map(new URL(_))
// .getOrElse(halt(BadRequest(
// ErrorMsg(400, "Please provide a URL")
// )))
val url = params
.getAs[URL]("url")
.getAs[URL]("splat")
.getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "Please provide a URL")))))
controller
.findByURL(url)
.map({
case None => halt(NotFound(toJson(ErrorMsg(404, "an Image with a URL of $url was not found"))))
case None =>
halt(NotFound(toJson(ErrorMsg(404, "an Image with a URL of $url was not found"))))
case Some(i) => toJson(i)
})
}
Expand All @@ -99,20 +106,26 @@ class ImageV1Api(controller: ImageController)(implicit val executor: ExecutionCo
validateRequest() // Apply API security
val videoReferenceUUID = params
.getAs[UUID]("video_reference_uuid")
.getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "A 'video_reference_uuid' parameter is required")))))
.getOrElse(
halt(BadRequest(toJson(ErrorMsg(400, "A 'video_reference_uuid' parameter is required"))))
)
val url =
params.getAs[URL]("url").getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "A 'url' parameter is required")))))
params
.getAs[URL]("url")
.getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "A 'url' parameter is required")))))
val timecode = params.getAs[Timecode]("timecode")
val elapsedTime = params.getAs[Duration]("elapsed_time_millis")
val recordedDate = params.getAs[Instant]("recorded_timestamp")

if (timecode.isEmpty && elapsedTime.isEmpty && recordedDate.isEmpty) {
halt(
BadRequest(
toJson(ErrorMsg(
400,
"An valid index of timecode, elapsed_time_millis, or recorded_timestamp is required"
))
toJson(
ErrorMsg(
400,
"An valid index of timecode, elapsed_time_millis, or recorded_timestamp is required"
)
)
)
)
}
Expand Down Expand Up @@ -140,7 +153,9 @@ class ImageV1Api(controller: ImageController)(implicit val executor: ExecutionCo
validateRequest() // Apply API security
val uuid = params
.getAs[UUID]("uuid")
.getOrElse(halt(BadRequest(toJson(ErrorMsg(400, "A image reference 'uuid' parameter is required")))))
.getOrElse(
halt(BadRequest(toJson(ErrorMsg(400, "A image reference 'uuid' parameter is required"))))
)
val videoReferenceUUID = params.getAs[UUID]("video_reference_uuid")
val url = params.getAs[URL]("url")
val timecode = params.getAs[Timecode]("timecode")
Expand All @@ -166,7 +181,9 @@ class ImageV1Api(controller: ImageController)(implicit val executor: ExecutionCo
.map({
case None =>
halt(
NotFound(toJson(ErrorMsg(404, s"an Image with an image_reference_uuid of $uuid was not found")))
NotFound(
toJson(ErrorMsg(404, s"an Image with an image_reference_uuid of $uuid was not found"))
)
)
case Some(v) => toJson(v)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,21 @@ class AssociationV1ApiSpec extends WebApiStack {
}

it should "create with a defined association UUID" in {
val uuid = UUID.randomUUID()
post(
s"/v1/associations/",
"observation_uuid" -> annotation.observationUuid.toString,
"link_name" -> "bounding box",
"to_concept" -> "cool thing",
"link_value" -> "{" \ x \ ": 10}",
"association_uuid"
"link_value" -> """{"x": 10}""",
"association_uuid" -> uuid.toString()
) {
status should be(200)
association = gson.fromJson(body, classOf[AssociationImpl])
association.linkName should be("color")
association.linkValue should be("red")
association.linkName should be("bounding box")
association.toConcept should be("cool thing")
association.linkValue should be("""{"x": 10}""")
association.uuid should be(uuid)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,30 @@ import java.time.{Duration, Instant}
import java.util.UUID
import java.util.concurrent.TimeUnit

import org.mbari.vars.annotation.controllers.BasicDAOFactory
import org.mbari.vars.annotation.Constants
import org.mbari.vars.annotation.api.WebApiStack
import org.mbari.vars.annotation.controllers.ObservationController
import org.mbari.vars.annotation.dao.jpa.{AnnotationImpl, AssociationImpl, ImagedMomentImpl, ObservationImpl}
import org.mbari.vars.annotation.dao.jpa.{
AnnotationImpl,
AssociationImpl,
ImagedMomentImpl,
ObservationImpl
}
import org.mbari.vars.annotation.model.Observation

import scala.collection.JavaConverters._
import scala.concurrent.Await
import scala.concurrent.duration.{Duration => SDuration}
import org.mbari.vars.annotation.controllers.AnnotationController
import scala.concurrent.Future

/**
*
*
* @author Brian Schlining
* @since 2016-09-13T14:31:00
*/
*
*
* @author Brian Schlining
* @since 2016-09-13T14:31:00
*/
class ObservationV1ApiSpec extends WebApiStack {

private[this] val timeout = SDuration(3000, TimeUnit.MILLISECONDS)
Expand All @@ -46,21 +54,31 @@ class ObservationV1ApiSpec extends WebApiStack {
new ObservationV1Api(controller)
}

protected[this] override val gson = Constants.GSON_FOR_ANNOTATION
private[this] val annoController = new AnnotationController(
daoFactory.asInstanceOf[BasicDAOFactory]
)

override protected[this] val gson = Constants.GSON_FOR_ANNOTATION

private[this] val path = "/v1/observations"

addServlet(observationV1Api, path)

def exec[R](fn: () => Future[R]): R = Await.result(fn.apply(), timeout)

var observation: Observation = _

"ObservationV1Api" should "find by uuid" in {

// --- create an observation
val dao = daoFactory.newObservationDAO()
val dao = daoFactory.newObservationDAO()
val imagedMoment = ImagedMomentImpl(Some(UUID.randomUUID()), Some(Instant.now()))
observation = ObservationImpl("rocketship", observer = Some("brian"), group = Some("ROV"),
activity = Some("transect"))
observation = ObservationImpl(
"rocketship",
observer = Some("brian"),
group = Some("ROV"),
activity = Some("transect")
)
imagedMoment.addObservation(observation)
val f = dao.runTransaction(d => d.create(observation))
f.onComplete(_ => dao.close())
Expand All @@ -81,11 +99,15 @@ class ObservationV1ApiSpec extends WebApiStack {

it should "find by videoreference" in {
val dao = daoFactory.newObservationDAO()
val newObs = ObservationImpl("submarine", observer = Some("schlin"), group = Some("AUV"),
activity = Some("descent"))
val newObs = ObservationImpl(
"submarine",
observer = Some("schlin"),
group = Some("AUV"),
activity = Some("descent")
)
val f = dao.runTransaction(d => {
dao.findByUUID(observation.uuid) match {
case None => fail(s"Unable to find observation with uuid of ${observation.uuid}")
case None => fail(s"Unable to find observation with uuid of ${observation.uuid}")
case Some(obs) => obs.imagedMoment.addObservation(newObs)
}
})
Expand All @@ -100,12 +122,12 @@ class ObservationV1ApiSpec extends WebApiStack {
}

it should "find by association" in {
val dao = daoFactory.newObservationDAO()
val assDao = daoFactory.newAssociationDAO(dao)
val dao = daoFactory.newObservationDAO()
val assDao = daoFactory.newAssociationDAO(dao)
val association = assDao.newPersistentObject("eating", Some("cake"))
val f = dao.runTransaction(d => {
dao.findByUUID(observation.uuid) match {
case None => fail(s"Unable to find observation with uuid of ${observation.uuid}")
case None => fail(s"Unable to find observation with uuid of ${observation.uuid}")
case Some(obs) => obs.addAssociation(association)
}
})
Expand All @@ -121,10 +143,14 @@ class ObservationV1ApiSpec extends WebApiStack {

it should "find all names" in {
// --- create another imagedmoment with a different video-reference uuid
val dao = daoFactory.newObservationDAO()
val dao = daoFactory.newObservationDAO()
val imagedMoment = ImagedMomentImpl(Some(UUID.randomUUID()), Some(Instant.now()))
val obs = ObservationImpl("squid", observer = Some("aine"), group = Some("Image:Benthic Rover"),
activity = Some("transit"))
val obs = ObservationImpl(
"squid",
observer = Some("aine"),
group = Some("Image:Benthic Rover"),
activity = Some("transit")
)
imagedMoment.addObservation(obs)
val f = dao.runTransaction(d => d.create(obs))
f.onComplete(_ => dao.close())
Expand All @@ -151,16 +177,17 @@ class ObservationV1ApiSpec extends WebApiStack {
it should "update" in {
put(
s"$path/${observation.uuid}",
"concept" -> "shoe",
"concept" -> "shoe",
"duration_millis" -> "3200",
"activity" -> "ascent") {
status should be(200)
val obs = gson.fromJson(body, classOf[ObservationImpl])
obs.concept should be("shoe")
obs.duration should be(Duration.ofMillis(3200))
obs.activity should be("ascent")
obs.uuid should be(observation.uuid)
}
"activity" -> "ascent"
) {
status should be(200)
val obs = gson.fromJson(body, classOf[ObservationImpl])
obs.concept should be("shoe")
obs.duration should be(Duration.ofMillis(3200))
obs.activity should be("ascent")
obs.uuid should be(observation.uuid)
}
}

it should "delete" in {
Expand All @@ -170,12 +197,20 @@ class ObservationV1ApiSpec extends WebApiStack {
}

it should "bulk delete" in {
val dao = daoFactory.newObservationDAO()
val dao = daoFactory.newObservationDAO()
val imagedMoment = ImagedMomentImpl(Some(UUID.randomUUID()), Some(Instant.now()))
val obs0 = ObservationImpl("rocketship", observer = Some("brian"), group = Some("ROV"),
activity = Some("transect"))
val obs1 = ObservationImpl("giant dragon", observer = Some("brian"), group = Some("AUV"),
activity = Some("transect"))
val obs0 = ObservationImpl(
"rocketship",
observer = Some("brian"),
group = Some("ROV"),
activity = Some("transect")
)
val obs1 = ObservationImpl(
"giant dragon",
observer = Some("brian"),
group = Some("AUV"),
activity = Some("transect")
)
imagedMoment.addObservation(obs0)
imagedMoment.addObservation(obs1)
val f = dao.runTransaction(d => {
Expand All @@ -185,18 +220,45 @@ class ObservationV1ApiSpec extends WebApiStack {
f.onComplete(t => dao.close())
Await.result(f, timeout)

val annos = Seq(obs0, obs1).map(AnnotationImpl(_))
val annos = Seq(obs0, obs1)
.map(AnnotationImpl(_))
.map(_.observationUuid)
.asJava
val json = Constants.GSON_FOR_ANNOTATION
val json = Constants
.GSON_FOR_ANNOTATION
.toJson(annos)
.getBytes(StandardCharsets.UTF_8)
post(
s"$path/delete",
body = json,
headers = Map("Content-Type" -> "application/json")) {
status should be(200)
}
post(s"$path/delete", body = json, headers = Map("Content-Type" -> "application/json")) {
status should be(200)
}
}

it should "delete duration" in {
// create an annotation
val recordedDate = Instant.now()
val duration = Duration.ofSeconds(5)
val a = exec(() =>
annoController
.create(
UUID.randomUUID(),
"Nanomia bijuga",
"brian",
recordedDate = Some(recordedDate),
duration = Some(Duration.ofSeconds(5))
)
)
a.concept should be("Nanomia bijuga")
a.observer should be("brian")
a.recordedTimestamp should be(recordedDate)
a.duration should be(duration)

put(s"$path/delete/duration/${a.observationUuid}") {
status should be(200)
val obs = gson.fromJson(body, classOf[ObservationImpl])
obs.concept should be(a.concept)
obs.uuid should be(a.observationUuid)
obs.duration should be(null)
}
}

}
Loading

0 comments on commit 5db4c8e

Please sign in to comment.