From 97c918517506c6ad1eb5b5fd664803831917a599 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 26 Sep 2023 18:22:58 -0700 Subject: [PATCH 1/2] Fix Create and Update request models --- .../spra/api/AdminDataExplorerApiClient.scala | 4 ++-- .../wiringbits/spra/api/models/AdminCreateTable.scala | 8 +++++--- .../wiringbits/spra/api/models/AdminUpdateTable.scala | 8 +++++--- .../spra/admin/controllers/AdminController.scala | 4 ++-- .../test/scala/controllers/AdminControllerSpec.scala | 10 +++++----- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/spra-api/shared/src/main/scala/net/wiringbits/spra/api/AdminDataExplorerApiClient.scala b/spra-api/shared/src/main/scala/net/wiringbits/spra/api/AdminDataExplorerApiClient.scala index 07bc3e9..19a274a 100644 --- a/spra-api/shared/src/main/scala/net/wiringbits/spra/api/AdminDataExplorerApiClient.scala +++ b/spra-api/shared/src/main/scala/net/wiringbits/spra/api/AdminDataExplorerApiClient.scala @@ -24,7 +24,7 @@ trait AdminDataExplorerApiClient { def createItem(tableName: String, request: AdminCreateTable.Request): Future[AdminCreateTable.Response] - def updateItem(tableName: String, id: String, request: Map[String, String]): Future[AdminUpdateTable.Response] + def updateItem(tableName: String, id: String, request: AdminUpdateTable.Request): Future[AdminUpdateTable.Response] def deleteItem(tableName: String, id: String): Future[AdminDeleteTable.Response] } @@ -151,7 +151,7 @@ object AdminDataExplorerApiClient { override def updateItem( tableName: String, id: String, - request: Map[String, String] + request: AdminUpdateTable.Request ): Future[AdminUpdateTable.Response] = { val path = ServerAPI.path :+ "admin" :+ "tables" :+ tableName :+ id val uri = ServerAPI.withPath(path) diff --git a/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminCreateTable.scala b/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminCreateTable.scala index 2a070f6..b447d73 100644 --- a/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminCreateTable.scala +++ b/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminCreateTable.scala @@ -1,14 +1,16 @@ package net.wiringbits.spra.api.models -import play.api.libs.json.{Format, Json} +import play.api.libs.json.{Format, Json, Reads, Writes} object AdminCreateTable { case class Request(data: Map[String, String]) case class Response(noData: String = "") - implicit val adminCreateTableRequestFormat: Format[Request] = - Json.format[Request] + implicit val adminCreateTableRequestFormat: Format[Request] = Format[Request]( + fjs = implicitly[Reads[Map[String, String]]].map(Request.apply), + tjs = Writes[Request](x => Json.toJson(x.data)) + ) implicit val adminCreateTableResponseFormat: Format[Response] = Json.format[Response] diff --git a/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminUpdateTable.scala b/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminUpdateTable.scala index adf25c3..ca90bd0 100644 --- a/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminUpdateTable.scala +++ b/spra-api/shared/src/main/scala/net/wiringbits/spra/api/models/AdminUpdateTable.scala @@ -1,13 +1,15 @@ package net.wiringbits.spra.api.models -import play.api.libs.json.{Format, Json} +import play.api.libs.json.{Format, Json, Reads, Writes} object AdminUpdateTable { case class Request(data: Map[String, String]) case class Response(id: String) - implicit val adminUpdateTableRequestFormat: Format[Request] = - Json.format[Request] + implicit val adminUpdateTableRequestFormat: Format[Request] = Format[Request]( + fjs = implicitly[Reads[Map[String, String]]].map(Request.apply), + tjs = Writes[Request](x => Json.toJson(x.data)) + ) implicit val adminUpdateTableResponseFormat: Format[Response] = Json.format[Response] diff --git a/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala b/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala index 73253b8..d9ab547 100644 --- a/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala +++ b/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala @@ -63,9 +63,9 @@ class AdminController @Inject() ( } yield Ok(Json.toJson(Map("id" -> id))) } - def update(tableName: String, primaryKeyValue: String) = handleJsonBody[Map[String, String]] { request => + def update(tableName: String, primaryKeyValue: String) = handleJsonBody[AdminUpdateTable.Request] { request => val primaryKeyFieldName = dataExplorerConfig.unsafeFindByName(tableName).primaryKeyField - val body = request.body.map { + val body = request.body.data.map { case ("id", value) => primaryKeyFieldName -> value case x => x } diff --git a/spra-play-server/src/test/scala/controllers/AdminControllerSpec.scala b/spra-play-server/src/test/scala/controllers/AdminControllerSpec.scala index 2a67426..74952fa 100644 --- a/spra-play-server/src/test/scala/controllers/AdminControllerSpec.scala +++ b/spra-play-server/src/test/scala/controllers/AdminControllerSpec.scala @@ -5,7 +5,7 @@ import controllers.common.PlayPostgresSpec import net.wiringbits.spra.admin.AppRouter import net.wiringbits.spra.admin.config.{DataExplorerConfig, PrimaryKeyDataType, TableSettings} import net.wiringbits.spra.admin.controllers.{AdminController, ImagesController} -import net.wiringbits.spra.api.models.AdminCreateTable +import net.wiringbits.spra.api.models.{AdminCreateTable, AdminUpdateTable} import org.apache.commons.lang3.StringUtils import play.api.inject import play.api.inject.guice.GuiceApplicationBuilder @@ -697,7 +697,7 @@ class AdminControllerSpec extends PlayPostgresSpec { val userId = response.headOption.value.find(_._1 == "id").value._2 val email = "wiringbits@wiringbits.net" - val updateRequest = Map("email" -> email) + val updateRequest = AdminUpdateTable.Request(Map("email" -> email)) val updateResponse = client.updateItem(usersSettings.tableName, userId, updateRequest).futureValue val newResponse = client.viewItem(usersSettings.tableName, userId).futureValue @@ -717,7 +717,7 @@ class AdminControllerSpec extends PlayPostgresSpec { val id = response.headOption.value.find(_._1 == "id").value._2 val name = "wiringbitsbitsbits" - val updateRequest = Map("name" -> name) + val updateRequest = AdminUpdateTable.Request(Map("name" -> name)) val updateResponse = client.updateItem(table.tableName, id, updateRequest).futureValue val newResponse = client.viewItem(table.tableName, id).futureValue @@ -737,7 +737,7 @@ class AdminControllerSpec extends PlayPostgresSpec { val userId = response.headOption.value.find(_._1 == "id").value._2 val email = "wiringbits@wiringbits.net" - val updateRequest = Map("nonExistentField" -> email) + val updateRequest = AdminUpdateTable.Request(Map("nonExistentField" -> email)) val error = client.updateItem("users", userId, updateRequest).expectError error must be("A field doesn't correspond to this table schema") } @@ -754,7 +754,7 @@ class AdminControllerSpec extends PlayPostgresSpec { val id = response.headOption.value.find(_._1 == "id").value._2 val name = "wiringbits" - val updateRequest = Map("nonExistentField" -> name) + val updateRequest = AdminUpdateTable.Request(Map("nonExistentField" -> name)) val error = client.updateItem(table.tableName, id, updateRequest).expectError error must be("A field doesn't correspond to this table schema") } From 2479fe3fe6be1eb4e35d605541ab984600f866f8 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 26 Sep 2023 19:42:49 -0700 Subject: [PATCH 2/2] Minor changes --- .../wiringbits/spra/admin/controllers/AdminController.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala b/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala index d9ab547..e69b3a7 100644 --- a/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala +++ b/spra-play-server/src/main/scala/net/wiringbits/spra/admin/controllers/AdminController.scala @@ -54,8 +54,8 @@ class AdminController @Inject() ( } yield Ok(Json.toJson(response.map(Json.toJson(_)))) } - def create(tableName: String) = handleJsonBody[Map[String, String]] { request => - val body = AdminCreateTable.Request(request.body) + def create(tableName: String) = handleJsonBody[AdminCreateTable.Request] { request => + val body = request.body for { _ <- adminUser(request) _ = logger.info(s"Create row in $tableName: ${body.data}")