Skip to content

Commit 87ebdf4

Browse files
committed
Added tests and request corrections
1 parent ef9da7d commit 87ebdf4

File tree

7 files changed

+93
-15
lines changed

7 files changed

+93
-15
lines changed

spra-play-server/src/main/scala/net/wiringbits/spra/admin/models/FieldValue.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package net.wiringbits.spra.admin.models
22

3-
trait FieldValue[T] extends Serializable {
3+
sealed trait FieldValue[T] extends Serializable {
44
val value: T
55
}
66

spra-play-server/src/main/scala/net/wiringbits/spra/admin/repositories/daos/DatabaseTablesDAO.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,9 @@ object DatabaseTablesDAO {
268268
val sql = QueryBuilder.update(tableName, fieldsAndValues, primaryKeyField)
269269
val preparedStatement = conn.prepareStatement(sql)
270270

271-
val notNullData = fieldsAndValues.filterNot { case (_, value) => value.value == "null" }
272-
notNullData.zipWithIndex.foreach { case ((_, value), i) =>
273-
preparedStatement.setObject(i + 1, value.value)
271+
val notNullData = fieldsAndValues.filterNot { case (_, field) => field.value == "null" }
272+
notNullData.zipWithIndex.foreach { case ((_, field), i) =>
273+
preparedStatement.setObject(i + 1, field.value)
274274
}
275275
// where ... = ?
276276
setPreparedStatementKey(preparedStatement, primaryKeyValue, primaryKeyType, notNullData.size + 1)

spra-play-server/src/main/scala/net/wiringbits/spra/admin/utils/QueryBuilder.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ object QueryBuilder {
3535

3636
def update(tableName: String, body: Map[TableColumn, FieldValue[_]], primaryKeyField: String): String = {
3737
val updateStatement = new mutable.StringBuilder("SET")
38-
for ((tableField, value) <- body) {
39-
val resultStatement = if (value.value == "null") "NULL" else s"?::${tableField.`type`}"
38+
for ((tableField, field) <- body) {
39+
val resultStatement = if (field.value == "null") "NULL" else s"?::${tableField.`type`}"
4040
val statement = s" ${tableField.name} = $resultStatement,"
4141
updateStatement.append(statement)
4242
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
-- !Ups
3+
4+
CREATE TABLE bytea_table (
5+
id UUID NOT NULL PRIMARY KEY,
6+
data BYTEA NOT NULL
7+
);

spra-play-server/src/test/scala/controllers/AdminControllerSpec.scala

+47-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
3939
tableName = "big_serial_table_overflow",
4040
primaryKeyField = "id",
4141
primaryKeyDataType = PrimaryKeyDataType.BigSerial
42+
),
43+
TableSettings(
44+
tableName = "bytea_table",
45+
primaryKeyField = "id"
4246
)
4347
)
4448
val dataExplorerConfig: DataExplorerConfig = DataExplorerConfig("http://localhost:9000", dataExplorerConfigTables)
@@ -50,6 +54,7 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
5054
def bigSerialSettings: TableSettings = dataExplorerConfig.tablesSettings(4)
5155
def serialOverflowSettings: TableSettings = dataExplorerConfig.tablesSettings(5)
5256
def bigSerialOverflowSettings: TableSettings = dataExplorerConfig.tablesSettings(6)
57+
def byteaSettings: TableSettings = dataExplorerConfig.tablesSettings(7)
5358

5459
def isValidUUID(str: String): Boolean = {
5560
if (str == null) return false
@@ -70,12 +75,13 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
7075
"return tables from modules" in withApiClient { client =>
7176
val response = client.getTables.futureValue
7277
response.data.map(_.name) match
73-
case List(users, userLogs, uuidTable, serialTable, bigSerialTable, _, _) =>
78+
case List(users, userLogs, uuidTable, serialTable, bigSerialTable, _, _, byteaTable) =>
7479
users must be(usersSettings.tableName)
7580
userLogs must be(userLogsSettings.tableName)
7681
uuidTable must be(uuidSettings.tableName)
7782
serialTable must be(serialSettings.tableName)
7883
bigSerialTable must be(bigSerialSettings.tableName)
84+
byteaTable must be(byteaSettings.tableName)
7985
case list => fail(s"Unexpected response: ${list.mkString(", ")}")
8086
}
8187

@@ -135,6 +141,17 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
135141
bigSerialSettings.filterableColumns must be(List.empty)
136142
bigSerialSettings.createSettings.nonRequiredColumns must be(List.empty)
137143
bigSerialSettings.createSettings.requiredColumns must be(List.empty)
144+
145+
val head6 = response.data(5)
146+
head6.primaryKeyName must be(byteaSettings.primaryKeyField)
147+
byteaSettings.referenceField must be(None)
148+
byteaSettings.hiddenColumns must be(List.empty)
149+
byteaSettings.nonEditableColumns must be(List.empty)
150+
byteaSettings.canBeDeleted must be(true)
151+
byteaSettings.columnTypeOverrides must be(Map.empty)
152+
byteaSettings.filterableColumns must be(List.empty)
153+
byteaSettings.createSettings.nonRequiredColumns must be(List.empty)
154+
byteaSettings.createSettings.requiredColumns must be(List.empty)
138155
}
139156
}
140157

@@ -680,7 +697,7 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
680697

681698
responseMetadata.head.nonEmpty mustBe true
682699
}
683-
700+
684701
"return new user id" in withApiClient { implicit client =>
685702
val user = createUser.futureValue
686703
val response = client.getTableMetadata(usersSettings.tableName, List("name", "ASC"), List(0, 9), "{}").futureValue
@@ -737,6 +754,18 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
737754
s"ERROR: nextval: reached maximum value of sequence \"big_serial_table_overflow_seq\" (9223372036854775807)"
738755
)
739756
}
757+
758+
"create a new bytea" in withApiClient { implicit client =>
759+
val stringBytea = "[0, 10, 20, 30]"
760+
// The response returns the bytea as Hex; this would be its equivalent in Hex.
761+
val correctValue = "\\x000a141e"
762+
val request = AdminCreateTable.Request(Map("data" -> stringBytea))
763+
val byteaId = client.createItem(byteaSettings.tableName, request).futureValue.id
764+
765+
val response = client.viewItem(byteaSettings.tableName, byteaId).futureValue
766+
val dataResponse = response.find(_._1 == "data").value._2
767+
dataResponse must be(correctValue)
768+
}
740769
}
741770

742771
"fail when field in request doesn't exists" in withApiClient { client =>
@@ -779,6 +808,22 @@ class AdminControllerSpec extends PlayPostgresSpec with AdminUtils {
779808
emailResponse must be(email)
780809
}
781810

811+
"update a new bytea" in withApiClient { client =>
812+
val request = AdminCreateTable.Request(Map("data" -> "[10, 10, 10, 10]"))
813+
val byteaId = client.createItem(byteaSettings.tableName, request).futureValue.id
814+
815+
val stringBytea = "[0, 10, 20, 30]"
816+
// The response returns the bytea as Hex; this would be its equivalent in Hex.
817+
val correctValue = "\\x000a141e"
818+
val updateRequest = AdminUpdateTable.Request(Map("data" -> stringBytea))
819+
val updateResponse = client.updateItem(byteaSettings.tableName, byteaId, updateRequest).futureValue
820+
821+
val newResponse = client.viewItem(byteaSettings.tableName, byteaId).futureValue
822+
val dataResponse = newResponse.find(_._1 == "data").value._2
823+
updateResponse.id must be(byteaId)
824+
dataResponse must be(correctValue)
825+
}
826+
782827
"update a new row for all tables" in withApiClient { client =>
783828
val tables = List(serialSettings, bigSerialSettings)
784829
for (table <- tables) {

spra-play-server/src/test/scala/net/wiringbits/spra/admin/QueryBuilderSpec.scala

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.wiringbits.spra.admin
22

3+
import net.wiringbits.spra.admin.models.{FieldValue, StringValue}
34
import net.wiringbits.spra.admin.repositories.models.TableColumn
45
import net.wiringbits.spra.admin.utils.QueryBuilder
56
import org.scalatest.matchers.must.Matchers.{be, must}
@@ -20,7 +21,10 @@ class QueryBuilderSpec extends AnyWordSpec {
2021
|""".stripMargin
2122
val tableName = "users"
2223
val body =
23-
Map(TableColumn("email", "citext") -> "[email protected]", TableColumn("name", "text") -> "wiringbits")
24+
Map(
25+
TableColumn("email", "citext") -> StringValue("[email protected]"),
26+
TableColumn("name", "text") -> StringValue("wiringbits")
27+
)
2428
val primaryKeyField = "user_id"
2529

2630
val response = QueryBuilder.create(tableName, body, primaryKeyField)
@@ -40,7 +44,7 @@ class QueryBuilderSpec extends AnyWordSpec {
4044
|RETURNING user_id::TEXT
4145
|""".stripMargin
4246
val tableName = "users"
43-
val body = Map.empty[TableColumn, String]
47+
val body = Map.empty[TableColumn, FieldValue[_]]
4448
val primaryKeyField = "user_id"
4549

4650
val response = QueryBuilder.create(tableName, body, primaryKeyField)
@@ -58,8 +62,8 @@ class QueryBuilderSpec extends AnyWordSpec {
5862
|""".stripMargin
5963
val tableName = "users"
6064
val body = Map(
61-
TableColumn("email", "citext") -> "[email protected]",
62-
TableColumn("name", "text") -> "[email protected]"
65+
TableColumn("email", "citext") -> StringValue("[email protected]"),
66+
TableColumn("name", "text") -> StringValue("[email protected]")
6367
)
6468
val primaryKeyField = "user_id"
6569

@@ -76,9 +80,9 @@ class QueryBuilderSpec extends AnyWordSpec {
7680
|""".stripMargin
7781
val tableName = "users"
7882
val body = Map(
79-
TableColumn("email", "citext") -> "[email protected]",
80-
TableColumn("name", "text") -> "[email protected]",
81-
TableColumn("phone_number", "text") -> "null"
83+
TableColumn("email", "citext") -> StringValue("[email protected]"),
84+
TableColumn("name", "text") -> StringValue("[email protected]"),
85+
TableColumn("phone_number", "text") -> StringValue("null")
8286
)
8387
val primaryKeyField = "user_id"
8488

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.wiringbits.spra.admin
2+
3+
import net.wiringbits.spra.admin.utils.StringParse.stringToByteArray
4+
import org.scalatest.matchers.must.Matchers.{be, must}
5+
import org.scalatest.wordspec.AnyWordSpec
6+
7+
class StringParseSpec extends AnyWordSpec {
8+
"dataParse" should {
9+
val data = List(
10+
("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]", Array[Byte](0, 1, 2, 3, 4, 5, 6, 7, 8, 9)),
11+
("[-128, -64, 0, 64, 127]", Array[Byte](-128, -64, 0, 64, 127)),
12+
("[10, 20, 30, 40, 50]", Array[Byte](10, 20, 30, 40, 50)),
13+
("[127, -127, 127, -127]", Array[Byte](127, -127, 127, -127))
14+
)
15+
16+
data.foreach { (data, valid) =>
17+
s"accept valid conversion: $data" in {
18+
stringToByteArray(data) must be(valid)
19+
}
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)