pytest fixtures naming as a variable - pytest

I have two pytest selenium fixtures:
wd - webdriver fixture (widely used for all webend tests)
wdwire - webdriverwire fixture (for request/response manipulating of webend)
Both work as they should, but I need to have a variable named like the fixture to get it to work. So it means two separate functions or renaming. I have lots of test and would like to
reuse the same code, just changing the fixture and function parameter.
#pytest.mark.usefixtures("wdwire")
def test01_userportal_security(self, wdwire):
""" using wdwire webdriver """
url = tools.urls.urls['user-portal']['url']
wdwire.get(url)
:
#pytest.mark.usefixtures("wd")
def test01_userportal_security(self, wd):
""" using standard webdriver """
url = tools.urls.urls['user-portal']['url']
wd.get(url)
:
Any way to add a variable to remap wd/wdwire so they can use the same function with a parameter change?
Tried:
#pytest.mark.usefixtures("wdwire")
def test01_userportal_security(self, wd=wdwire):
""" using wdwire webdriver """
url = tools.urls.urls['user-portal']['url']
wd.get(url)
:
gives: NameError: name 'wd' is not defined
#pytest.mark.usefixtures("wdwire")
def test01_userportal_security(self, wd="wdwire"):
""" using wdwire webdriver """
url = tools.urls.urls['user-portal']['url']
wd.get(url)
:
gives: AttributeError: 'str' object has no attribute 'get'

Related

Is there any way to have multiple response models in FastAPI/OpenAPI?

I am writing an app where I need to have two completely different set of response structures depending on logic.
Is there any way to handle this so that I can have two different response models serialized, validated and returned and reflect in OpenAPI JSON?
I am using pydantic to write models.
Yes this is possible. You can use Union for that in the response_model= parameter in your path decorator (I used the new python 3.10 style below). Here is a full example, this will work as is.
from typing import Union
from fastapi import FastAPI, Query
from pydantic import BaseModel
class responseA(BaseModel):
name: str
class responseB(BaseModel):
id: int
app = FastAPI()
#app.get("/", response_model=responseA|responseB )
def base(q: int|str = Query(None)):
if q and isinstance(q, str):
return responseA(name=q)
if q and isinstance(q, int):
return responseB(id=q)
raise HTTPException(status_code=400, detail="No q param provided")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000, )
Result in your documentation:

Mocking Httpcalls always return NullPointerException

I'm trying to mock Http calls for unit test.
To do that I have done the following, I have created a RequestMock case class:
case class RequestMock() {
def sendRequest(httpRequest: HttpRequest)(implicit actorSystem: ActorSystem): Future[HttpResponse] = {
Http().singleRequest(httpRequest)
}
}
and in my service, I have written the following piece of code :
case class Service(requestHandler: RequestMock) {
....
for {
response <- {
requestHandler.sendRequest(
HttpRequest(
method = HttpMethods.GET,
uri = "http://database:9000"
)
)
} yield {
response
}
}
For the unit test, I'm trying to mock HttpCalls, to do that, I have done the following :
def test_2 = mock[RequestMock]
And for defining the mock behaviour I have done the following
when(test_2.sendRequest(
HttpRequest(
method = HttpMethods.GET,
uri = "http://database:9000")
)).thenReturn{
Future(
HttpResponse(
StatusCodes.OK,
entity = HttpEntity(ContentTypes.`text/plain(UTF-8)`,"connection established"))
But, when I execute unit tests, I always get the following error:
java.lang.NullPointerException
Does anyone know how I can solve this issue ?
A couple of problems.
First of all, test_2 should be a val, not a def.
With def like you have it, you get a different instance every time you access it. So, you define the stub on one instance, but then create your Service with a different one, that does not have sendRequest defined, so returns null by default, and that causes your NPE.
The next problem, that you will probably encounter after you fix this one is that you are not defining all of the behavior.
when(test_2.sendRequest(
HttpRequest(
method = HttpMethods.GET,
uri = "http://database:9000")
))
Only creates a stub for a method call with this specific parameter value. So, if your tests try to make a POST for example or hit a different endpoint, you'll get an NPE again.
Even if you only ever use one request, it is better to define the stub for any argument, to avoid weird NPE failures if the code happens to send a different one (you are writing a test, so should not just assume automatically, that the code will always do what you expect - you would not need the test in the first place if that was the case):
when(test2.sendRequest(any)),thenReturn(Future.successful(...))
(Note Future.successful above – that's the correct way to create Future that is immediately satisfied, what you are doing makes it run on a thread ... not a big deal in your case, but still icky).
Then, after the test code is run, you can check that the parameter value passed to the sendRequest was actually what you expect:
verify(test2)
.sendRequest(HttpRequest(method = HttpMethods.GET, uri = "http://database:9000"))

Using variables in js.eval() function in scala js

I am using javascript to fetch data from a text box using js.eval() function like :
val amount=js.eval("document.getElementById('amount').value;")
It is working fine when I am writing the id directly i.e. 'amount' in this case. But I want to create a function which will receive the id and then use the variable id.
I tried using '$' sign also like :
def getAmount(amount_id:String):Unit={
println("Amount is : "+js.eval(s"document.getElementById(${id}).value;"))
But it is not working. Any suggestions ?
Do not use js.eval. Use the interoperability features of Scala.js instead:
import org.scalajs.dom
import dom.html
def getAmount(amount_id:String): Unit = {
val input = dom.document.getElementById(amount_id).asInstanceOf[html.Input]
println(s"Amount is : ${input.value}")
}

plone.formwidget - Is it possible to set a MasterSelect Field as an AutocompleteFieldWidget?

I am trying to set a MasterSelect field to an AutocompleteFieldWidget.
I'm using AutocompleteFieldWidget from plone.formwidget.autocomplete and the MasterSelectField from plone.formwidget.MasterSelect. The slave field belonging to the MasterSelectField is also a MasterSelectField.
The autocomplete functions as it should (retrieving the values based on input), but the slave field's choices do not change. However, when its not set as an autocomplete, everything works as it should.
Edit:
In my buildout-cache, I looked at widget.py in plone.formwidget.masterselect and tried placing a print statement in getSlaves and that function wasn't getting called. I tried the render function and that wasn't getting called either. Then I placed a print statement in MasterSelectField and that was notgetting called. Setting the field to an Autocomplete widget removes any trace that its a Master Select field.
Edit: In the init.py file in plone.formwidget.masterselect, I placed a print statement in the init function of the MasterSelectField, and the slave widget does print, where as in getSlaves in widget.py it doesn't. This is the output I'm getting from printing in the init and what I should be getting in getSlaves:
({'action': 'vocabulary', 'masterID': 'form-widgets-IMyForm-master_field',
'control_param': 'master_value', 'name': 'IMyForm.slave_field',
'vocab_method': <class 'my.product.vocabulary.SlaveVocab'>},)
I have my interface:
from plone.directives import form
class IMyForm(model.Schema):
form.widget(master_field=AutocompleteFieldWidget)
master_field = MasterSelectField(
title=_(u'Master'),
slave_fields=({'name':'IMyForm.slave_field',
'action':'vocabulary',
'source':MySource,
'control_param':'master_value'
}),
required=True,
)
slave_field = MasterSelectField(title=_(u'Slave Field'),
source=SlaveVocab,
slave_fields=(....
)
required=False,
)
I have my source object for the master field:
class MySource(object):
implements(IQuerySource)
def __init__(self, context):
simple_terms = []
#Query portal catalog for unique indexes, and fill with simple terms
self.vocab = SimpleVocabulary(simple_terms)
def __contains__(self, term):
return self.vocab.__contains__(term)
def getTermByToken(self, token):
return self.getTermByToken(token)
def getTerm(self, value):
return self.getTerm(value)
def search(self, query_string):
return [term for term in self.vocab if query_string in term.title.lower()]
class MySourceBinder(object):
implements(IContextSourceBinder)
def __call__(self, context):
return MySource(context)
My slave field's source is:
class SlaveVocab(object):
grok.implements(IContextSourceBinder)
def __init__(self, **kw):
self.master_value = kw.get('master_value', None)
def __call__(self, context):
if self.master_value is None or self.master_value == "--NOVALUE--"
self.master_value = getattr(context,'master_field',None)
#Still nothing, return empty vocabulary
if self.master_value is None or self.master_value == '--NOVALUE--':
return SimpleVocabulary([])
terms = []
#If not null, building a simple vocabulary to return
return SimpleVocabulary(terms)
I did a print statement in call of the Slave Vocabulary and it was being called, but nothing was being passed in.
I also tried using another widget, ChosenFieldWidget. I get the same results in that it functions as it should, but the slave field's choices do not change. Is it possible to set a master select field to an autocomplete? If so, what am I doing wrong?
Also, I'm using Solgema.fullcalendar and the content type extends the IEventBasic behavior, so I don't have access to using my own form class I would've liked to have used since Solgema seems to render its own forms.
Edit:
I am using Plone 4.3

How to send an array of a complex object with GroovyWS

I'm about to call a webservice created in C#, that takes a parameter
KmlSystemVariable[] sysVariables
How can I pass a parameter like that using GroovyWS? It doesn't need to have any values, could be an empty array.
Looks like the full class name is Consorte.Pulse.Data.KmlSystemVariable
I enabled logging as described in GroovyWS and complex requests to get the namespace for KmlSystemVariable, and it looks like I can create a KmlSystemVariable with:
proxy.create("org.datacontract.schemas._2004._07.consorte_pulse.KmlSystemVariable")
But how do I create an array of KmlSystemVariable?
It should be enough to just wrap your proxied objects into a Groovy list and use it as the parameter. GroovyWS will do the transformation from List to SOAP array for you behind the scenes.
Example:
def ksv1 = proxy.create("org.datacontract.schemas._2004._07.consorte_pulse.KmlSystemVariable")
def ksv2 = ...
def ksv3 = ...
def list = [ksv1, ksv2, ksv3]
proxy.<some ws method>(list)