mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 16:36:54 +00:00
Tests for cache info etc
This commit is contained in:
parent
4a20168da7
commit
a366afaad4
353
obp-api/src/test/scala/code/api/v6_0_0/CacheEndpointsTest.scala
Normal file
353
obp-api/src/test/scala/code/api/v6_0_0/CacheEndpointsTest.scala
Normal file
@ -0,0 +1,353 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2024, TESOBE GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH
|
||||
Osloerstrasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
*/
|
||||
package code.api.v6_0_0
|
||||
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.util.ApiRole.{CanGetCacheConfig, CanGetCacheInfo, CanInvalidateCacheNamespace}
|
||||
import code.api.util.ErrorMessages.{InvalidJsonFormat, UserHasMissingRoles, UserNotLoggedIn}
|
||||
import code.api.v6_0_0.OBPAPI6_0_0.Implementations6_0_0
|
||||
import code.entitlement.Entitlement
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.model.ErrorMessage
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.json.Serialization.write
|
||||
import org.scalatest.Tag
|
||||
|
||||
class CacheEndpointsTest extends V600ServerSetup {
|
||||
/**
|
||||
* Test tags
|
||||
* Example: To run tests with tag "getCacheConfig":
|
||||
* mvn test -D tagsToInclude
|
||||
*
|
||||
* This is made possible by the scalatest maven plugin
|
||||
*/
|
||||
object VersionOfApi extends Tag(ApiVersion.v6_0_0.toString)
|
||||
object ApiEndpoint1 extends Tag(nameOf(Implementations6_0_0.getCacheConfig))
|
||||
object ApiEndpoint2 extends Tag(nameOf(Implementations6_0_0.getCacheInfo))
|
||||
object ApiEndpoint3 extends Tag(nameOf(Implementations6_0_0.invalidateCacheNamespace))
|
||||
|
||||
// ============================================================================================================
|
||||
// GET /system/cache/config - Get Cache Configuration
|
||||
// ============================================================================================================
|
||||
|
||||
feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") {
|
||||
scenario("We call getCacheConfig without user credentials", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v6.0.0 without credentials")
|
||||
val request = (v6_0_0_Request / "system" / "cache" / "config").GET
|
||||
val response = makeGetRequest(request)
|
||||
Then("We should get a 401")
|
||||
response.code should equal(401)
|
||||
response.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint1 version $VersionOfApi - Missing role") {
|
||||
scenario("We call getCacheConfig without the CanGetCacheConfig role", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v6.0.0 without the required role")
|
||||
val request = (v6_0_0_Request / "system" / "cache" / "config").GET <@ (user1)
|
||||
val response = makeGetRequest(request)
|
||||
Then("We should get a 403")
|
||||
response.code should equal(403)
|
||||
And("error should be " + UserHasMissingRoles + CanGetCacheConfig)
|
||||
response.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanGetCacheConfig)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint1 version $VersionOfApi - Authorized access") {
|
||||
scenario("We call getCacheConfig with the CanGetCacheConfig role", ApiEndpoint1, VersionOfApi) {
|
||||
Given("We have a user with CanGetCacheConfig entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetCacheConfig.toString)
|
||||
|
||||
When("We make a request v6.0.0 with proper role")
|
||||
val request = (v6_0_0_Request / "system" / "cache" / "config").GET <@ (user1)
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("The response should have the correct structure")
|
||||
val cacheConfig = response.body.extract[CacheConfigJsonV600]
|
||||
cacheConfig.providers should not be empty
|
||||
cacheConfig.instance_id should not be empty
|
||||
cacheConfig.environment should not be empty
|
||||
cacheConfig.global_prefix should not be empty
|
||||
|
||||
And("Providers should have valid data")
|
||||
cacheConfig.providers.foreach { provider =>
|
||||
provider.provider should not be empty
|
||||
provider.enabled shouldBe a[Boolean]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
// GET /system/cache/info - Get Cache Information
|
||||
// ============================================================================================================
|
||||
|
||||
feature(s"test $ApiEndpoint2 version $VersionOfApi - Unauthorized access") {
|
||||
scenario("We call getCacheInfo without user credentials", ApiEndpoint2, VersionOfApi) {
|
||||
When("We make a request v6.0.0 without credentials")
|
||||
val request = (v6_0_0_Request / "system" / "cache" / "info").GET
|
||||
val response = makeGetRequest(request)
|
||||
Then("We should get a 401")
|
||||
response.code should equal(401)
|
||||
response.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint2 version $VersionOfApi - Missing role") {
|
||||
scenario("We call getCacheInfo without the CanGetCacheInfo role", ApiEndpoint2, VersionOfApi) {
|
||||
When("We make a request v6.0.0 without the required role")
|
||||
val request = (v6_0_0_Request / "system" / "cache" / "info").GET <@ (user1)
|
||||
val response = makeGetRequest(request)
|
||||
Then("We should get a 403")
|
||||
response.code should equal(403)
|
||||
And("error should be " + UserHasMissingRoles + CanGetCacheInfo)
|
||||
response.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanGetCacheInfo)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint2 version $VersionOfApi - Authorized access") {
|
||||
scenario("We call getCacheInfo with the CanGetCacheInfo role", ApiEndpoint2, VersionOfApi) {
|
||||
Given("We have a user with CanGetCacheInfo entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetCacheInfo.toString)
|
||||
|
||||
When("We make a request v6.0.0 with proper role")
|
||||
val request = (v6_0_0_Request / "system" / "cache" / "info").GET <@ (user1)
|
||||
val response = makeGetRequest(request)
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("The response should have the correct structure")
|
||||
val cacheInfo = response.body.extract[CacheInfoJsonV600]
|
||||
cacheInfo.namespaces should not be null
|
||||
cacheInfo.total_keys should be >= 0
|
||||
cacheInfo.redis_available shouldBe a[Boolean]
|
||||
|
||||
And("Each namespace should have valid data")
|
||||
cacheInfo.namespaces.foreach { namespace =>
|
||||
namespace.namespace_id should not be empty
|
||||
namespace.prefix should not be empty
|
||||
namespace.current_version should be > 0L
|
||||
namespace.key_count should be >= 0
|
||||
namespace.description should not be empty
|
||||
namespace.category should not be empty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
// POST /management/cache/namespaces/invalidate - Invalidate Cache Namespace
|
||||
// ============================================================================================================
|
||||
|
||||
feature(s"test $ApiEndpoint3 version $VersionOfApi - Unauthorized access") {
|
||||
scenario("We call invalidateCacheNamespace without user credentials", ApiEndpoint3, VersionOfApi) {
|
||||
When("We make a request v6.0.0 without credentials")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST
|
||||
val response = makePostRequest(request, write(InvalidateCacheNamespaceJsonV600("rd_localised")))
|
||||
Then("We should get a 401")
|
||||
response.code should equal(401)
|
||||
response.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint3 version $VersionOfApi - Missing role") {
|
||||
scenario("We call invalidateCacheNamespace without the CanInvalidateCacheNamespace role", ApiEndpoint3, VersionOfApi) {
|
||||
When("We make a request v6.0.0 without the required role")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(InvalidateCacheNamespaceJsonV600("rd_localised")))
|
||||
Then("We should get a 403")
|
||||
response.code should equal(403)
|
||||
And("error should be " + UserHasMissingRoles + CanInvalidateCacheNamespace)
|
||||
response.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanInvalidateCacheNamespace)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint3 version $VersionOfApi - Invalid JSON format") {
|
||||
scenario("We call invalidateCacheNamespace with invalid JSON", ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with CanInvalidateCacheNamespace entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We make a request with invalid JSON")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response = makePostRequest(request, """{"invalid": "json"}""")
|
||||
|
||||
Then("We should get a 400")
|
||||
response.code should equal(400)
|
||||
And("error should be InvalidJsonFormat")
|
||||
response.body.extract[ErrorMessage].message should startWith(InvalidJsonFormat)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint3 version $VersionOfApi - Invalid namespace_id") {
|
||||
scenario("We call invalidateCacheNamespace with non-existent namespace_id", ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with CanInvalidateCacheNamespace entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We make a request with invalid namespace_id")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(InvalidateCacheNamespaceJsonV600("invalid_namespace")))
|
||||
|
||||
Then("We should get a 400")
|
||||
response.code should equal(400)
|
||||
And("error should mention invalid namespace_id")
|
||||
val errorMessage = response.body.extract[ErrorMessage].message
|
||||
errorMessage should include("Invalid namespace_id")
|
||||
errorMessage should include("invalid_namespace")
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint3 version $VersionOfApi - Authorized access with valid namespace") {
|
||||
scenario("We call invalidateCacheNamespace with valid rd_localised namespace", ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with CanInvalidateCacheNamespace entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We make a request with valid namespace_id")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(InvalidateCacheNamespaceJsonV600("rd_localised")))
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("The response should have the correct structure")
|
||||
val result = response.body.extract[InvalidatedCacheNamespaceJsonV600]
|
||||
result.namespace_id should equal("rd_localised")
|
||||
result.old_version should be > 0L
|
||||
result.new_version should be > result.old_version
|
||||
result.new_version should equal(result.old_version + 1)
|
||||
result.status should equal("invalidated")
|
||||
}
|
||||
|
||||
scenario("We call invalidateCacheNamespace with valid connector namespace", ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with CanInvalidateCacheNamespace entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We make a request with connector namespace_id")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(InvalidateCacheNamespaceJsonV600("connector")))
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("The response should have the correct structure")
|
||||
val result = response.body.extract[InvalidatedCacheNamespaceJsonV600]
|
||||
result.namespace_id should equal("connector")
|
||||
result.old_version should be > 0L
|
||||
result.new_version should be > result.old_version
|
||||
result.status should equal("invalidated")
|
||||
}
|
||||
|
||||
scenario("We call invalidateCacheNamespace with valid abac_rule namespace", ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with CanInvalidateCacheNamespace entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We make a request with abac_rule namespace_id")
|
||||
val request = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(InvalidateCacheNamespaceJsonV600("abac_rule")))
|
||||
|
||||
Then("We should get a 200")
|
||||
response.code should equal(200)
|
||||
|
||||
And("The response should have the correct structure")
|
||||
val result = response.body.extract[InvalidatedCacheNamespaceJsonV600]
|
||||
result.namespace_id should equal("abac_rule")
|
||||
result.status should equal("invalidated")
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint3 version $VersionOfApi - Version increment validation") {
|
||||
scenario("We verify that cache version increments correctly on multiple invalidations", ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with CanInvalidateCacheNamespace entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We invalidate the same namespace twice")
|
||||
val request1 = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response1 = makePostRequest(request1, write(InvalidateCacheNamespaceJsonV600("rd_dynamic")))
|
||||
|
||||
Then("First invalidation should succeed")
|
||||
response1.code should equal(200)
|
||||
val result1 = response1.body.extract[InvalidatedCacheNamespaceJsonV600]
|
||||
val firstNewVersion = result1.new_version
|
||||
|
||||
When("We invalidate again")
|
||||
val request2 = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val response2 = makePostRequest(request2, write(InvalidateCacheNamespaceJsonV600("rd_dynamic")))
|
||||
|
||||
Then("Second invalidation should succeed")
|
||||
response2.code should equal(200)
|
||||
val result2 = response2.body.extract[InvalidatedCacheNamespaceJsonV600]
|
||||
|
||||
And("Version should have incremented again")
|
||||
result2.old_version should equal(firstNewVersion)
|
||||
result2.new_version should equal(firstNewVersion + 1)
|
||||
result2.status should equal("invalidated")
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================================================
|
||||
// Cross-endpoint test - Verify cache info updates after invalidation
|
||||
// ============================================================================================================
|
||||
|
||||
feature(s"Integration test - Cache endpoints interaction") {
|
||||
scenario("We verify cache info shows updated version after invalidation", ApiEndpoint2, ApiEndpoint3, VersionOfApi) {
|
||||
Given("We have a user with both CanGetCacheInfo and CanInvalidateCacheNamespace entitlements")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetCacheInfo.toString)
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanInvalidateCacheNamespace.toString)
|
||||
|
||||
When("We get the initial cache info")
|
||||
val getRequest1 = (v6_0_0_Request / "system" / "cache" / "info").GET <@ (user1)
|
||||
val getResponse1 = makeGetRequest(getRequest1)
|
||||
getResponse1.code should equal(200)
|
||||
val cacheInfo1 = getResponse1.body.extract[CacheInfoJsonV600]
|
||||
|
||||
// Find the rd_static namespace (or any other valid namespace)
|
||||
val targetNamespace = "rd_static"
|
||||
val initialVersion = cacheInfo1.namespaces.find(_.namespace_id == targetNamespace).map(_.current_version)
|
||||
|
||||
When("We invalidate the namespace")
|
||||
val invalidateRequest = (v6_0_0_Request / "management" / "cache" / "namespaces" / "invalidate").POST <@ (user1)
|
||||
val invalidateResponse = makePostRequest(invalidateRequest, write(InvalidateCacheNamespaceJsonV600(targetNamespace)))
|
||||
invalidateResponse.code should equal(200)
|
||||
val invalidateResult = invalidateResponse.body.extract[InvalidatedCacheNamespaceJsonV600]
|
||||
|
||||
When("We get the cache info again")
|
||||
val getRequest2 = (v6_0_0_Request / "system" / "cache" / "info").GET <@ (user1)
|
||||
val getResponse2 = makeGetRequest(getRequest2)
|
||||
getResponse2.code should equal(200)
|
||||
val cacheInfo2 = getResponse2.body.extract[CacheInfoJsonV600]
|
||||
|
||||
Then("The namespace version should have been incremented")
|
||||
val updatedNamespace = cacheInfo2.namespaces.find(_.namespace_id == targetNamespace)
|
||||
updatedNamespace should not be None
|
||||
|
||||
if (initialVersion.isDefined) {
|
||||
updatedNamespace.get.current_version should be > initialVersion.get
|
||||
}
|
||||
updatedNamespace.get.current_version should equal(invalidateResult.new_version)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user