How to update Resource value in ReadyAPI/SoapUI dynamically by groovy? - api

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}

Related

Server side validation library for Kotlin

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()
}

Using karate built-in functions and api

Ok, so I am going to explain what my scenario is and how I have implemented it using karate. But i am looking for a better way of doing things which make my tests more readable and also want to use karate's api rather than too much javascript.
Scenario: I have a filter parameter for the api endpoint that i am testing and this filter param takes a json object of key-value pairs. So i have done the following:
Have created a filter-template.js as below:
function() {
var filter_params = {
jobId:null,
customerIds:[],
filterValues1:[],
filterValues2:[],
};
return filter_params;
}
I read this template in my karate scenario and because this is a template, at runtime i set the values in this template and run the test. I will have different values for key-value pairs so each test will set its own filter condition.
This is done by writing custom js function that takes the template as argument and also the filter condition values (referring to arg function argument below), sets the passed conditions to specific key's and then returns json object. Code below:
Scenario: Set filter scenario
* def filter_template = call read('filter-template.js')
* def filter_vals_list = [1001,1002]
* def filter_condition = { cnd1: 'foo', cnd2: '#(filter_vals_list)' }
* def setFilter =
"""
function(arg) {
var i;
var filter = arg.template;
filter.jobId = arg.condition.cnd1;
for(i=0;i<arg.condition.cnd2.length;i++)
{
filter.filterValues1.add(arg.condition.cnd2.get(i));
}
return filter;
}
"""
* def getFilter = call setFilter { template: '#(filter_template)',
condition: '#(filter_condition)' }
I then pass the getFilter as a param to my api request.
What I am hoping to understand is:
How can i get away from using JS loops above when setting filter?
Use karate's in-built functions like karate.map(), karate.forEach() to simplify the tests.
Any better approach if possible on tackling this scenario.
Help and guidance much appreciated.
From what I understood, I have simplified your scenario below:
* def filter_vals_list = [ 1001, 1002 ]
* def job_id = 'foo'
* def filter_template =
"""
{
jobId: '#(job_id)',
customerIds: [],
filterValues1: '#(filter_vals_list)',
filterValues2: [],
}
"""
Let me know if I missed anything. Please refer embedded expressions: https://github.com/intuit/karate#embedded-expressions
Now, you can easily use a re-usable JSON for the template, by changing the last step to the below, and yes - embedded expressions work even in re-usable JSON files !
* def filter_template = read('filter-template.json')
You may get even better ideas once you try the data-driven Scenario Outline. So hope that makes it clear how you are un-necessarily complicating things with JS ! You don't even need karate.map() etc.

Flask-Appbuilder - User security role required in View

If the current user role = admin then show all the records in the table. If not, then limit the rows by created user.
I can get the user name if I define a function in the View Class, but need it before the list is constructed. See source code below.
from flask_appbuilder.models.sqla.filters import FilterEqualFunction
from app import appbuilder, db
from app.models import Language
from wtforms import validators, TextField
from flask import g
from flask_appbuilder.security.sqla.models import User
def get_user():
return g.user
class LanguageView(ModelView):
datamodel = SQLAInterface(Language)
list_columns = ["id", "name"]
base_order = ("name", "asc")
page_size = 50
#This is the part that does not work - unable to import app Error: Working outside of application context
#If the user role is admin show all, if not filter only to the specific user
if g.user.roles != "admin":
base_filters = [['created_by', FilterEqualFunction, get_user]]
This is the error I'm getting:
Was unable to import app Error: Working outside of application context.
This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context(). See the
documentation for more information.
In this case it is better to create two different ModelViews, one for users with base_filters = [['created_by', FilterEqualFunction, get_user]] and the second for admins only without any filtering.
And do not forget to specify correct permissions for both.
In my case, I created new filter FilterStartsWithFunction by coping FilterStartsWith(You can find the source code in Flask-Appbuilder pack easily. ). see the codes
from flask_appbuilder.models.sqla.filters import get_field_setup_query
class FilterStartsWithFunction(BaseFilter):
name = "Filter view with a function"
arg_name = "eqf"
def apply(self, query, func):
query, field = get_field_setup_query(query, self.model, self.column_name)
return query.filter(field.ilike(func() + "%"))
def get_user():
if 'Admin' in [r.name for r in g.user.roles]:
return ''
else:
return g.user.username
...
...
base_filters = [['created_by',FilterStartsWithFunction,get_user]]

JSON to BSON conversion for testing purposes

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

How to test a helper Grok view that makes a redirect

I have a content type that needs to be modified in some way after calling a helper Grok view that checks some condition, makes some changes, sets a message and redirects to the original object.
my helper view only has a render method and I want to write some tests for it but I have no idea how to handle this.
I would like to check for an error message when some condition is not met, and for an info message when everything goes fine.
my code looks like this:
class MyHelperView(grok.View):
grok.context(IMyType)
grok.layer(IMyLayer)
grok.name('helper-view')
grok.require('my.permission')
def render(self):
variable = self.request.form.get('variable', None)
if not variable:
msg = _(u'Required input is missing.')
api.portal.show_message(message=msg, request=self.request, type='error')
else:
do_something()
msg = _(u'Information processed.')
api.portal.show_message(message=msg, request=self.request)
self.request.response.redirect(self.context.absolute_url())
when I call the view obviously I ended with a None object, as the view returns nothing. I don't know where to look for messages... request? response? any hint?
I would avoid using transaction commits in test code. The test framework is specifically designed to roll back the transactions at the end of each test. Your setUp override goes against this.
To check status messages in a unit test you should be able to do something like:
from Products.statusmessages.interfaces import IStatusMessage
IStatusMessage(request).show()
This is an adapter that adapts the request.
I ended up with test with a layer based on FunctionalTesting:
....
from plone.app.testing import TEST_USER_NAME
from plone.app.testing import TEST_USER_PASSWORD
from plone.testing.z2 import Browser
....
import transaction
...
class HelperViewTestCase(unittest.TestCase):
layer = FUNCTIONAL_TESTING
def setUp(self):
self.app = self.layer['app']
self.portal = self.layer['portal']
self.request = self.layer['request']
directlyProvides(self.request, IMyLayer)
with api.env.adopt_roles(['Manager']):
self.foo = api.content.create(self.portal, 'MyType', 'foo')
transaction.commit()
def test_response(self):
browser = Browser(self.app)
browser.handleErrors = False
browser.addHeader(
'Authorization',
'Basic {0}:{1}'.format(TEST_USER_NAME, TEST_USER_PASSWORD)
)
browser.open(self.foo.absolute_url())
browser.getControl('Do Something').click()
self.assertIn(
'Required input is missing.', browser.contents)
two things you need to check that make me spent some time debugging:
you must use transaction.commit() to reflect object creation on the ZODB
you must add an authorization header before trying to open the page
everything else is working.