version conflicts in VsCode web for test

This commit is contained in:
Wander Madeira 2025-12-14 14:11:46 +00:00
commit 626ffed95c
6 changed files with 518 additions and 10 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"develop"
]
}

View File

@ -824,5 +824,4 @@ Steps to add Spanish language:
Please note that default translation file is `lift-core.properties`
Test in VS Code Workspace
Testing VS Code Workspace Web

View File

@ -40,7 +40,7 @@ import code.util.Helper
import code.util.Helper.{MdcLoggable, ObpS, SILENCE_IS_GOLDEN}
import code.views.Views
import code.views.system.ViewDefinition
import code.webuiprops.{MappedWebUiPropsProvider, WebUiPropsCommons}
import code.webuiprops.{MappedWebUiPropsProvider, WebUiPropsCommons, WebUiPropsPutJsonV600}
import code.dynamicEntity.DynamicEntityCommons
import code.DynamicData.{DynamicData, DynamicDataProvider}
import com.github.dwickern.macros.NameOf.nameOf
@ -3634,6 +3634,181 @@ trait APIMethods600 {
}
}
staticResourceDocs += ResourceDoc(
createOrUpdateWebUiProps,
implementedInApiVersion,
nameOf(createOrUpdateWebUiProps),
"PUT",
"/management/webui_props/WEBUI_PROP_NAME",
"Create or Update WebUiProps",
s"""Create or Update a WebUiProps.
|
|${userAuthenticationMessage(true)}
|
|This endpoint is idempotent - it will create the property if it doesn't exist, or update it if it does.
|The property is identified by WEBUI_PROP_NAME in the URL path.
|
|Explanation of Fields:
|
|* WEBUI_PROP_NAME in URL path (must start with `webui_`, contain only alphanumeric characters, underscore, and dot, not exceed 255 characters, and will be converted to lowercase)
|* value is required String value in request body
|
|The line break and double quotations should be escaped, example:
|
|```
|
|{"name": "webui_some", "value": "this value
|have "line break" and double quotations."}
|
|```
|should be escaped like this:
|
|```
|
|{"name": "webui_some", "value": "this value\\nhave \\"line break\\" and double quotations."}
|
|```
|
|Insert image examples:
|
|```
|// set width=100 and height=50
|{"name": "webui_some_pic", "value": "here is a picture ![hello](http://somedomain.com/images/pic.png =100x50)"}
|
|// only set height=50
|{"name": "webui_some_pic", "value": "here is a picture ![hello](http://somedomain.com/images/pic.png =x50)"}
|
|// only width=20%
|{"name": "webui_some_pic", "value": "here is a picture ![hello](http://somedomain.com/images/pic.png =20%x)"}
|
|```
|
|""",
WebUiPropsPutJsonV600("https://apiexplorer.openbankproject.com"),
WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com", Some("some-web-ui-props-id")),
List(
UserNotLoggedIn,
UserHasMissingRoles,
InvalidJsonFormat,
InvalidWebUiProps,
UnknownError
),
List(apiTagWebUiProps),
Some(List(canCreateWebUiProps))
)
lazy val createOrUpdateWebUiProps: OBPEndpoint = {
case "management" :: "webui_props" :: webUiPropName :: Nil JsonPut json -> _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
_ <- NewStyle.function.hasEntitlement("", u.userId, canCreateWebUiProps, callContext)
// Convert name to lowercase
webUiPropNameLower = webUiPropName.toLowerCase
invalidMsg = s"""$InvalidWebUiProps name must start with webui_, but current name is: ${webUiPropNameLower} """
_ <- NewStyle.function.tryons(invalidMsg, 400, callContext) {
require(webUiPropNameLower.startsWith("webui_"))
}
invalidCharsMsg = s"""$InvalidWebUiProps name must contain only alphanumeric characters, underscore, and dot. Current name: ${webUiPropNameLower} """
_ <- NewStyle.function.tryons(invalidCharsMsg, 400, callContext) {
require(webUiPropNameLower.matches("^[a-zA-Z0-9_.]+$"))
}
invalidLengthMsg = s"""$InvalidWebUiProps name must not exceed 255 characters. Current length: ${webUiPropNameLower.length} """
_ <- NewStyle.function.tryons(invalidLengthMsg, 400, callContext) {
require(webUiPropNameLower.length <= 255)
}
// Check if resource already exists to determine status code
existingProp <- Future { MappedWebUiPropsProvider.getByName(webUiPropNameLower) }
resourceExists = existingProp.isDefined
failMsg = s"$InvalidJsonFormat The Json body should contain a value field"
valueJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
json.extract[WebUiPropsPutJsonV600]
}
webUiPropsData = WebUiPropsCommons(webUiPropNameLower, valueJson.value)
Full(webUiProps) <- Future { MappedWebUiPropsProvider.createOrUpdate(webUiPropsData) }
} yield {
val commonsData: WebUiPropsCommons = webUiProps
val statusCode = if (resourceExists) HttpCode.`200`(callContext) else HttpCode.`201`(callContext)
(commonsData, statusCode)
}
}
}
staticResourceDocs += ResourceDoc(
deleteWebUiProps,
implementedInApiVersion,
nameOf(deleteWebUiProps),
"DELETE",
"/management/webui_props/WEBUI_PROP_NAME",
"Delete WebUiProps",
s"""Delete a WebUiProps specified by WEBUI_PROP_NAME.
|
|${userAuthenticationMessage(true)}
|
|The property name will be converted to lowercase before deletion.
|
|Returns 204 No Content on successful deletion.
|
|This endpoint is idempotent - if the property does not exist, it still returns 204 No Content.
|
|Requires the $canDeleteWebUiProps role.
|
|""",
EmptyBody,
EmptyBody,
List(
UserNotLoggedIn,
UserHasMissingRoles,
InvalidWebUiProps,
UnknownError
),
List(apiTagWebUiProps),
Some(List(canDeleteWebUiProps))
)
lazy val deleteWebUiProps: OBPEndpoint = {
case "management" :: "webui_props" :: webUiPropName :: Nil JsonDelete _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- authenticatedAccess(cc)
_ <- NewStyle.function.hasEntitlement("", u.userId, canDeleteWebUiProps, callContext)
// Convert name to lowercase
webUiPropNameLower = webUiPropName.toLowerCase
invalidMsg = s"""$InvalidWebUiProps name must start with webui_, but current name is: ${webUiPropNameLower} """
_ <- NewStyle.function.tryons(invalidMsg, 400, callContext) {
require(webUiPropNameLower.startsWith("webui_"))
}
invalidCharsMsg = s"""$InvalidWebUiProps name must contain only alphanumeric characters, underscore, and dot. Current name: ${webUiPropNameLower} """
_ <- NewStyle.function.tryons(invalidCharsMsg, 400, callContext) {
require(webUiPropNameLower.matches("^[a-zA-Z0-9_.]+$"))
}
invalidLengthMsg = s"""$InvalidWebUiProps name must not exceed 255 characters. Current length: ${webUiPropNameLower.length} """
_ <- NewStyle.function.tryons(invalidLengthMsg, 400, callContext) {
require(webUiPropNameLower.length <= 255)
}
// Check if resource exists
existingProp <- Future { MappedWebUiPropsProvider.getByName(webUiPropNameLower) }
_ <- existingProp match {
case Full(prop) =>
// Property exists - delete it
Future { MappedWebUiPropsProvider.delete(prop.webUiPropsId.getOrElse("")) } map {
case Full(true) => Full(())
case Full(false) => ObpApiFailure(s"$UnknownError Cannot delete WebUI prop", 500, callContext)
case Empty => ObpApiFailure(s"$UnknownError Cannot delete WebUI prop", 500, callContext)
case Failure(msg, _, _) => ObpApiFailure(msg, 500, callContext)
}
case Empty =>
// Property not found - idempotent delete returns success
Future.successful(Full(()))
case Failure(msg, _, _) =>
Future.failed(new Exception(msg))
}
} yield {
(EmptyBody, HttpCode.`204`(callContext))
}
}
}
staticResourceDocs += ResourceDoc(
getSystemDynamicEntities,
implementedInApiVersion,

View File

@ -19,6 +19,7 @@ object MappedWebUiPropsProvider extends WebUiPropsProvider {
override def getAll(): List[WebUiPropsT] = WebUiProps.findAll()
override def getByName(name: String): Box[WebUiPropsT] = WebUiProps.find(By(WebUiProps.Name, name))
override def createOrUpdate(webUiProps: WebUiPropsT): Box[WebUiPropsT] = {
WebUiProps.find(By(WebUiProps.Name, webUiProps.name))

View File

@ -19,9 +19,13 @@ case class WebUiPropsCommons(name: String,
object WebUiPropsCommons extends Converter[WebUiPropsT, WebUiPropsCommons]
case class WebUiPropsPutJsonV600(value: String) extends JsonFieldReName
trait WebUiPropsProvider {
def getAll(): List[WebUiPropsT]
def getByName(name: String): Box[WebUiPropsT]
def createOrUpdate(webUiProps: WebUiPropsT): Box[WebUiPropsT]
def delete(webUiPropsId: String):Box[Boolean]

View File

@ -48,7 +48,9 @@ class WebUiPropsTest extends V600ServerSetup {
* This is made possible by the scalatest maven plugin
*/
object VersionOfApi extends Tag(ApiVersion.v6_0_0.toString)
object ApiEndpoint extends Tag(nameOf(Implementations6_0_0.getWebUiProp))
object ApiEndpoint1 extends Tag(nameOf(Implementations6_0_0.getWebUiProp))
object ApiEndpoint2 extends Tag(nameOf(Implementations6_0_0.createOrUpdateWebUiProps))
object ApiEndpoint3 extends Tag(nameOf(Implementations6_0_0.deleteWebUiProps))
val rightEntity = WebUiPropsCommons("webui_api_explorer_url", "https://apiexplorer.openbankproject.com")
val anotherEntity = WebUiPropsCommons("webui_api_manager_url", "https://apimanager.openbankproject.com")
@ -57,7 +59,7 @@ class WebUiPropsTest extends V600ServerSetup {
feature("Get Single WebUiProp by Name v6.0.0") {
scenario("Get WebUiProp - successful case with explicit prop from database", VersionOfApi, ApiEndpoint) {
scenario("Get WebUiProp - successful case with explicit prop from database", VersionOfApi, ApiEndpoint1) {
// First create a webui prop
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop")
@ -76,7 +78,7 @@ class WebUiPropsTest extends V600ServerSetup {
webUiPropJson.value should equal(rightEntity.value)
}
scenario("Get WebUiProp - successful case with active=true returns explicit prop", VersionOfApi, ApiEndpoint) {
scenario("Get WebUiProp - successful case with active=true returns explicit prop", VersionOfApi, ApiEndpoint1) {
// First create a webui prop
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop")
@ -95,7 +97,7 @@ class WebUiPropsTest extends V600ServerSetup {
webUiPropJson.value should equal(anotherEntity.value)
}
scenario("Get WebUiProp - not found without active flag", VersionOfApi, ApiEndpoint) {
scenario("Get WebUiProp - not found without active flag", VersionOfApi, ApiEndpoint1) {
When("We get a non-existent webui prop by name without active flag")
val requestGet = (v6_0_0_Request / "webui-props" / "webui_non_existent_prop").GET
val responseGet = makeGetRequest(requestGet)
@ -105,7 +107,7 @@ class WebUiPropsTest extends V600ServerSetup {
error.message should include(WebUiPropsNotFoundByName)
}
scenario("Get WebUiProp - with active=true returns implicit prop from config", VersionOfApi, ApiEndpoint) {
scenario("Get WebUiProp - with active=true returns implicit prop from config", VersionOfApi, ApiEndpoint1) {
// Test that we can get implicit props from sample.props.template when active=true
When("We get a webui prop by name with active=true that exists in config but not in DB")
// Use a prop that should exist in sample.props.template like webui_sandbox_introduction
@ -118,7 +120,7 @@ class WebUiPropsTest extends V600ServerSetup {
webUiPropJson.webUiPropsId should equal(Some("default"))
}
scenario("Get WebUiProp - invalid active parameter", VersionOfApi, ApiEndpoint) {
scenario("Get WebUiProp - invalid active parameter", VersionOfApi, ApiEndpoint1) {
When("We get a webui prop with invalid active parameter")
val requestGet = (v6_0_0_Request / "webui-props" / "webui_api_explorer_url").GET.addQueryParameter("active", "invalid")
val responseGet = makeGetRequest(requestGet)
@ -128,7 +130,7 @@ class WebUiPropsTest extends V600ServerSetup {
error.message should include(InvalidFilterParameterFormat)
}
scenario("Get WebUiProp - database prop takes precedence over config prop when active=true", VersionOfApi, ApiEndpoint) {
scenario("Get WebUiProp - database prop takes precedence over config prop when active=true", VersionOfApi, ApiEndpoint1) {
// Create a webui prop that overrides a config value
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
val customValue = WebUiPropsCommons("webui_get_started_text", "Custom Get Started Text")
@ -149,5 +151,327 @@ class WebUiPropsTest extends V600ServerSetup {
webUiPropJson.webUiPropsId should not equal(Some("default"))
}
}
feature("Create or Update WebUiProp (PUT) v6.0.0") {
scenario("PUT WebUiProp - create new property successfully", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a new webui prop using PUT")
val putValue = """{"value": "https://new-api-explorer.com"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_test_new_prop").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 201 Created")
responsePut.code should equal(201)
val webUiProp = responsePut.body.extract[WebUiPropsCommons]
webUiProp.name should equal("webui_test_new_prop")
webUiProp.value should equal("https://new-api-explorer.com")
webUiProp.webUiPropsId.isDefined should equal(true)
}
scenario("PUT WebUiProp - update existing property successfully", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop")
val putValue1 = """{"value": "original value"}"""
val requestPut1 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_update_prop").PUT <@(user1)
val responsePut1 = makePutRequest(requestPut1, putValue1)
Then("We should get a 201 Created")
responsePut1.code should equal(201)
When("We update the same webui prop")
val putValue2 = """{"value": "updated value"}"""
val requestPut2 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_update_prop").PUT <@(user1)
val responsePut2 = makePutRequest(requestPut2, putValue2)
Then("We should get a 200 OK")
responsePut2.code should equal(200)
val webUiProp = responsePut2.body.extract[WebUiPropsCommons]
webUiProp.name should equal("webui_test_update_prop")
webUiProp.value should equal("updated value")
}
scenario("PUT WebUiProp - idempotent create (same value twice)", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
val putValue = """{"value": "idempotent value"}"""
When("We create a webui prop")
val requestPut1 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_idempotent").PUT <@(user1)
val responsePut1 = makePutRequest(requestPut1, putValue)
Then("We should get a 201 Created")
responsePut1.code should equal(201)
val webUiPropsId1 = responsePut1.body.extract[WebUiPropsCommons].webUiPropsId
When("We PUT the same value again")
val requestPut2 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_idempotent").PUT <@(user1)
val responsePut2 = makePutRequest(requestPut2, putValue)
Then("We should get a 200 OK with same ID")
responsePut2.code should equal(200)
val webUiPropsId2 = responsePut2.body.extract[WebUiPropsCommons].webUiPropsId
webUiPropsId1 should equal(webUiPropsId2)
}
scenario("PUT WebUiProp - name converted to lowercase", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop with UPPERCASE name")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "WEBUI_UPPERCASE_TEST").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 201 and name should be lowercase")
responsePut.code should equal(201)
val webUiProp = responsePut.body.extract[WebUiPropsCommons]
webUiProp.name should equal("webui_uppercase_test")
}
scenario("PUT WebUiProp - dot allowed in name", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop with dots in name")
val putValue = """{"value": "https://api.v1.example.com"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_api.v1.endpoint").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 201")
responsePut.code should equal(201)
val webUiProp = responsePut.body.extract[WebUiPropsCommons]
webUiProp.name should equal("webui_api.v1.endpoint")
}
scenario("PUT WebUiProp - fail without webui_ prefix", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop without webui_ prefix")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "invalid_name").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 400")
responsePut.code should equal(400)
val error = responsePut.body.extract[ErrorMessage]
error.message should include(InvalidWebUiProps)
error.message should include("must start with webui_")
}
scenario("PUT WebUiProp - fail with hyphen in name", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop with hyphen")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_api-explorer").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 400")
responsePut.code should equal(400)
val error = responsePut.body.extract[ErrorMessage]
error.message should include(InvalidWebUiProps)
error.message should include("alphanumeric characters, underscore, and dot")
}
scenario("PUT WebUiProp - fail with space in name", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop with space")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_invalid name").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 400")
responsePut.code should equal(400)
val error = responsePut.body.extract[ErrorMessage]
error.message should include(InvalidWebUiProps)
}
scenario("PUT WebUiProp - fail without authentication", VersionOfApi, ApiEndpoint2) {
When("We try to PUT without authentication")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_test_noauth").PUT
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 401")
responsePut.code should equal(401)
}
scenario("PUT WebUiProp - fail without CanCreateWebUiProps role", VersionOfApi, ApiEndpoint2) {
When("We try to PUT without proper role")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_test_norole").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 403")
responsePut.code should equal(403)
val error = responsePut.body.extract[ErrorMessage]
error.message should include(UserHasMissingRoles)
}
scenario("PUT WebUiProp - fail with invalid JSON body", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We PUT with invalid JSON")
val putValue = """{"invalid": "no value field"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_test_invalid_json").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 400")
responsePut.code should equal(400)
val error = responsePut.body.extract[ErrorMessage]
error.message should include(InvalidJsonFormat)
}
scenario("PUT WebUiProp - fail with name exceeding 255 characters", VersionOfApi, ApiEndpoint2) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
When("We create a webui prop with name exceeding 255 chars")
val longName = "webui_" + ("a" * 250) // 256 chars total
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / longName).PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 400")
responsePut.code should equal(400)
val error = responsePut.body.extract[ErrorMessage]
error.message should include(InvalidWebUiProps)
error.message should include("255 characters")
}
}
feature("Delete WebUiProp (DELETE) v6.0.0") {
scenario("DELETE WebUiProp - delete existing property successfully", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We create a webui prop")
val putValue = """{"value": "to be deleted"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_test_delete").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
Then("We should get a 201")
responsePut.code should equal(201)
When("We delete the webui prop")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "webui_test_delete").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 204 No Content")
responseDelete.code should equal(204)
responseDelete.body.toString should equal("{}")
}
scenario("DELETE WebUiProp - idempotent delete (delete twice)", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We create a webui prop")
val putValue = """{"value": "to be deleted twice"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_test_delete_twice").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
responsePut.code should equal(201)
When("We delete the webui prop first time")
val requestDelete1 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_delete_twice").DELETE <@(user1)
val responseDelete1 = makeDeleteRequest(requestDelete1)
Then("We should get a 204")
responseDelete1.code should equal(204)
When("We delete the same webui prop again (idempotent)")
val requestDelete2 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_delete_twice").DELETE <@(user1)
val responseDelete2 = makeDeleteRequest(requestDelete2)
Then("We should still get a 204")
responseDelete2.code should equal(204)
}
scenario("DELETE WebUiProp - delete non-existent property (idempotent)", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We delete a non-existent webui prop")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "webui_never_existed").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 204 (idempotent)")
responseDelete.code should equal(204)
}
scenario("DELETE WebUiProp - name converted to lowercase", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We create a webui prop with lowercase name")
val putValue = """{"value": "test value"}"""
val requestPut = (v6_0_0_Request / "management" / "webui_props" / "webui_delete_uppercase").PUT <@(user1)
val responsePut = makePutRequest(requestPut, putValue)
responsePut.code should equal(201)
When("We delete using UPPERCASE name")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "WEBUI_DELETE_UPPERCASE").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 204 (lowercase conversion works)")
responseDelete.code should equal(204)
}
scenario("DELETE WebUiProp - fail without webui_ prefix", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We try to delete with invalid name")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "invalid_name").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 400")
responseDelete.code should equal(400)
val error = responseDelete.body.extract[ErrorMessage]
error.message should include(InvalidWebUiProps)
error.message should include("must start with webui_")
}
scenario("DELETE WebUiProp - fail with hyphen in name", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We try to delete with hyphen in name")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "webui_api-explorer").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 400")
responseDelete.code should equal(400)
val error = responseDelete.body.extract[ErrorMessage]
error.message should include(InvalidWebUiProps)
}
scenario("DELETE WebUiProp - fail without authentication", VersionOfApi, ApiEndpoint3) {
When("We try to DELETE without authentication")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "webui_test_noauth").DELETE
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 401")
responseDelete.code should equal(401)
}
scenario("DELETE WebUiProp - fail without CanDeleteWebUiProps role", VersionOfApi, ApiEndpoint3) {
When("We try to DELETE without proper role")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "webui_test_norole").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 403")
responseDelete.code should equal(403)
val error = responseDelete.body.extract[ErrorMessage]
error.message should include(UserHasMissingRoles)
}
scenario("DELETE WebUiProp - complete CRUD workflow", VersionOfApi, ApiEndpoint3) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateWebUiProps.toString)
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanDeleteWebUiProps.toString)
When("We create a webui prop")
val putValue1 = """{"value": "initial value"}"""
val requestPut1 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_crud").PUT <@(user1)
val responsePut1 = makePutRequest(requestPut1, putValue1)
Then("We should get a 201")
responsePut1.code should equal(201)
When("We read the webui prop")
val requestGet1 = (v6_0_0_Request / "webui-props" / "webui_test_crud").GET
val responseGet1 = makeGetRequest(requestGet1)
Then("We should get a 200 with correct value")
responseGet1.code should equal(200)
responseGet1.body.extract[WebUiPropsCommons].value should equal("initial value")
When("We update the webui prop")
val putValue2 = """{"value": "updated value"}"""
val requestPut2 = (v6_0_0_Request / "management" / "webui_props" / "webui_test_crud").PUT <@(user1)
val responsePut2 = makePutRequest(requestPut2, putValue2)
Then("We should get a 200")
responsePut2.code should equal(200)
When("We read the updated webui prop")
val requestGet2 = (v6_0_0_Request / "webui-props" / "webui_test_crud").GET
val responseGet2 = makeGetRequest(requestGet2)
Then("We should get the updated value")
responseGet2.code should equal(200)
responseGet2.body.extract[WebUiPropsCommons].value should equal("updated value")
When("We delete the webui prop")
val requestDelete = (v6_0_0_Request / "management" / "webui_props" / "webui_test_crud").DELETE <@(user1)
val responseDelete = makeDeleteRequest(requestDelete)
Then("We should get a 204")
responseDelete.code should equal(204)
When("We try to read the deleted webui prop")
val requestGet3 = (v6_0_0_Request / "webui-props" / "webui_test_crud").GET
val responseGet3 = makeGetRequest(requestGet3)
Then("We should get a 400 (not found in database)")
responseGet3.code should equal(400)
}
}
}