Can anyone please suggest me good server side validation library for kotlin.
Which can perform basic validation like below
Checking for spaces and new line in a string
Checking the minimum and maximum of character in a string
Checking empty string
As I need to use a validation library instead of below code
val data.name = "test test"
val nameMaxLimit: Int = 256
if (data.name.contains(" ") || data.name.isNullOrEmpty() || data.name.length > nameMaxLimit) {
return true
}
My project is a Gradle Project, So gradle supported validation library will be blessed
You can use beans validation. I think it is the best way.
You would need to annotate each field with the rules you want.
Then you would tell the validations to run.
It would return to you an array of violations.
Here an example:
import javax.validation.Validator
val violations = validator.validate(data)
if (violations.isEmpty()) {
successAction()
}
Related
I am writing tests for Ktor app using Kotests, but stumbled into the problem how can I change env variables for tests preferably globally. I have tried adding withEnvironment but it throw quite strange error into me
Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module #3daa422a
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module #3daa422a
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
my test file looks like this
class VisitorSpec : FreeSpec({
val ds = createDataSourceTest()
val visitor = RegisterVisitorDTO(
email = TestConstants.VISITOR_EMAIL,
username = TestConstants.VISITOR_USERNAME,
password = TestConstants.PASSWORD,
firstName = TestConstants.VISITOR_FIRST_NAME,
lastName = TestConstants.VISITOR_LAST_NAME,
gender = TestConstants.VISITOR_GENDER,
birthday = TestConstants.VISITOR_BIRTHDAY,
)
"check visitor routes" - {
val loginData = LoginDTO(TestConstants.VISITOR_EMAIL + 0, TestConstants.PASSWORD)
"can get list of visitors with correct query" {
withEnvironment(
mapOf(
"POSTGRES_URL" to "jdbc:postgresql://localhost:5432/test",
"POSTGRES_USERNAME" to "test_user",
"POSTGRES_PASSWORD" to "test_pass"
)
) {
testApplication {
val client = getClient(ds)
repeat(6) {
registerConfirmedUser(
client, visitor.copy(
email = "${TestConstants.VISITOR_EMAIL}$it",
username = "${TestConstants.VISITOR_USERNAME}$it",
)
)
}
val accessToken = loginUser(client, loginData).run { this.body<LoginResponseDTO>().accessToken }
client.get("/api/v1/visitors?page=1&count=5") {
header("Authorization", "Bearer $accessToken")
}.apply {
val response = this.body<VisitorPaginatedResponseDTO>()
response.data.size.shouldBe(5)
response.totalCount.shouldBe(6)
response.currentPage.shouldBe(1)
}
}
}
}
...
if I remove
withEnvironment(
mapOf(
"POSTGRES_URL" to "jdbc:postgresql://localhost:5432/test",
"POSTGRES_USERNAME" to "test_user",
"POSTGRES_PASSWORD" to "test_pass"
)
)
it will just work but with default db, any advice on this?
In some places, it was advised to use
override fun listeners() = listOf(
SystemEnvironmentTestListener("fooKeyEnv", "barValueEnv"),
SystemPropertyTestListener("fooKeyProp", "barValueProp")
)
but ide tells me that this method is deprecated.
Thanks in advance for any advice.
Recent Java versions prohibit modifying the environment variables with the default access settings (JEP 403: Strongly Encapsulate JDK Internals). Kotest and some other testing frameworks that manipulate the environment variables got affected by this, you can find the related issues:
https://github.com/kotest/kotest/issues/2849
https://github.com/stefanbirkner/system-lambda/issues/23
https://github.com/junit-pioneer/junit-pioneer/issues/509
One solution would be to add the arguments to the JVM running the tests that would make the Java Platform Module System allow the access to the API used by the test framework. Here's an answer that explains the arguments: How to set environment variable in Java without 'illegal reflective access'? How to use add-opens?
The simplest form of the argument, if you are not using Java modules in your code, would be:
--add-opens java.base/java.util=ALL-UNNAMED
If you are running the tests using Gradle, then you can pass this argument to the jvmArgs of the test task:
tasks.withType<Test>().named("jvmTest") {
jvmArgs("--add-opens", "java.base/java.util=ALL-UNNAMED")
}
Note: modifying the module access in this way could make the tests pass even if some of your code needs illegal access to the JDK internals. Make sure that your code doesn't do that or that you have other tests that check for this without modifying module access rights.
It seems that some other libraries, like system-stubs, provide a way to modify the environment variables in tests without illegal reflective access to the JDK internals.
From karate-config.js I need to know what .feature files are included in the run. Is there an easy way to access that?
As a work around, have discovered that if I re-write Karate's Runner.parallel function, I can pass the feature names in an argument:
...
Map<String, Object> args = new HashMap<String,Object>();
...
String featureList = "";
for (int i = 0; i < count; i++) {
Resource resource = resources.get(i);
Feature feature = FeatureParser.parse(resource);
featureList = featureList + feature.getName();
}
args.put("featureList", featureList);
...
CallContext callContext = CallContext.forAsync(feature, options.hooks, options.hookFactory, args, false);
However, I dont know how to access the featureList argument from karate-config.js.
Is there an easy way to access the list of feature for a test run from karate-config.js?
This is not supported today. This is unlikely to be supported unless you contribute code because no one has ever requested this.
Do note that if you are anyway creating a list of features before you start the test, you can pass that to karate-config.js by means of a Java singleton.
I have the following request json body:
{
...
"attachmentIds": "${attachments}"
...
}
I have a properties file that includes the declaration of the corresponding placeholder
I want to set array of strings in code instead of "attachments" placeholder, but getProperties().setProperty() expects only string value.
How can I achieve it other way or is it possible at all?
Thanks!
As an option you can transform your array into the String in java code. And then pass this String as property value.
Another option, you can pass String array from code and then parse it in your json template.
For example:
String[] arr = { "1", "2", "3" };
apiMethod.addProperty("attachments", arr);
And then in your json:
{
"attachmentIds": [<#list attachments as val>"${val}"<#if val?has_next>,</#if></#list>]
}
Check freemarker documentation to get more details:
https://freemarker.apache.org/docs/ref_builtins_loop_var.html
Also please note that some of freemarker functions (including has_next) are available only in newest versions of library. So make sure to add into your dependencies list. Carina is now in process of migrating to latest freemarker version.
my resource is in this format "testing/101/getCustomer/99"
Here I need to change "101" and "99" part dynamically by groovy so that I can run for multiple values in same test case. I looked into the ReadyAPI's built in feature, but it was not that helpful.
I also found this link, but it changed the resource in the entire project. The solution I am looking for is in test case level. As my each test case will have different url.
https://community.smartbear.com/t5/SoapUI-Open-Source/How-to-set-the-resource-path-at-run-time-while...
Any help will be appreciated.
Here is what I have tried so far
import com.eviware.soapui.impl.rest.RestResource
import java.io.*;
def project = testRunner.testCase.testSuite.getProject()
String restServiceName = "Resource name" (From the Rest Request Properties)
List<RestResource> ops = project.getInterfaces()[restServiceName].getOperationList()
log.info("ops ::"+ops);
log.info("ops size ::"+ops.size());
for (RestResource restResource : ops) {
String pathStr = restResource.getFullPath();
log.info("pathStr first-->"+restResource.getFullPath());
restResource.setPath("testing/101/getCustomer/99");
if (pathStr.contains("101"))
{
restResource.setPath("testing/101/getCustomer/99");
restResource.setPath(pathStr.replace("testing/101/getCustomer/99", "testing/50/getCustomer/99"));
}
}
you could use a testCase level property
first set the the value of res by groovy like below
def x=101
def y=99
def res="testing/$x/getCustomer/$y"
testRunner.testCase.setPropertyValue("resourc",res)
Now the testcase level property is set. It can be used as below wherever you want
${#TestCase#res}
I'm writing a BSONDocumentReader and would like to create a BSONDocument from a JSON string in my test to verify whether it correctly builds the CC.
So far I haven't found an easy way to do so, can anyone provide an example?
Eventually I found the solution on SO, see this answer
import reactivemongo.play.json._
import play.modules.reactivemongo.json.collection._
val googleJs: JsObject = Json.parse(google).as[JsObject]
val googleBson: BSONDocument = BSONFormats.toBSON(googleJs).get.asInstanceOf[BSONDocument]
val maybeAddress = AddressReader read googleBson
maybeAddress shouldBe defined
// ... and so on...
Just make sure you have the play2-reactivemongo dependency