How do you post form data using pytest? - pytest

I'm trying to write a unit test that posts form data. The actual line in question is:
def test_create_request():
with app.test_client() as test_client:
app_url = '/requests/'
with app.app_context():
new_request = get_new_request()
form_data = json.dumps(new_request, default=str)
print('FORM DATA: ', form_data)
resp = test_client.post(app_url, data=form_data, headers={'Content-Type': 'application/json'})
assert resp.status_code == 200
s = json.loads(resp.data)
assert s['success'] == True
Where new_request is a dict representation of an object. The print statement yields (I've formatted it a bit):
FORM DATA: {
"request_id": "6",
"state_id": 1,
"orig_project_id": "1",
"orig_project_code": "QQQ",
"orig_allocated_funding": "123.45",
"orig_ytd_spend": "123.45",
"orig_ytd_commit": "123.45",
"orig_ytd_ocnr": "123.45",
"new_project_id": 2,
"new_funding_amount": 123.45,
"new_ytd_spend": 123.45,
"new_ytd_commit": 123.45,
"new_ytd_ocnr": 123.45,
"plan": "this is the plan",
"reason": "this is the reason",
"sm_director": "sm.dir#example.com",
"submitted_by": "xfgbn#vexample.com",
"created_on": "2021-09-14 16:32:55",
"meets_approval_guidelines": null
}
In the flask form, most fields are required. When I try to post the data, the form.validate_on_submit() function in the view's route returns False, and the 2nd assert fails. WTForms claims that none of the required orig_allocated_funding, orig_ytd_spend, orig_ytd_commit, orig_ytd_ocnr, new_project_id, new_funding_amount, new_ytd_spend, new_ytd_commit, new_ytd_ocnr, reason, plan, sm_director, or submitted_by fields are supplied.
I've read several tutorials, and I can't see what I'm doing wrong. Can anyone help?

What I was able to make work was scraping form_data altogether:
def test_create_request():
with app.test_client() as test_client:
app_url = '/requests/'
with app.app_context():
new_request = get_new_request()
resp = test_client.post(app_url, data=new_request)
assert resp.status_code == 200
s = json.loads(resp.data)
print(s['html'])
assert s['success'] == True

Related

Make JSON Parsing & Error Handling More Functional in Scala

I have the following piece of code that I use to read the incoming JSON which looks like this:
{
"messageTypeId": 2,
"messageId": "19223201",
"BootNotification" :
{
"reason": "PowerUp",
"chargingStation": {
"serialNumber" : "12345",
"model" : "",
"vendorName" : "",
"firmwareVersion" : "",
"modem": {
"iccid": "",
"imsi": ""
}
}
}
}
I have the following reads using play-json that would process this JSON:
implicit val ocppCallRequestReads: Reads[OCPPCallRequest] = Reads { jsValue =>
val messageTypeId = (jsValue \ 0).toOption
val messageId = (jsValue \ 1).toOption
val actionName = (jsValue \ 2).toOption
val payload = (jsValue \ 3).toOption
(messageTypeId.zip(messageId.zip(actionName.zip(payload)))) match {
case Some(_) => JsSuccess(
OCPPCallRequest( // Here I know all 4 exists, so safe to call head
messageTypeId.head.as[Int],
messageId.head.as[String],
actionName.head.as[String],
payload.head
)
)
case None => JsError( // Here, I know that I have to send a CallError back!
"ERROR OCCURRED" // TODO: Work on this!
)
}
}
It is not playing nicely when it comes to delivering the exact error message for the case None. It is all in or nothing, but what I want to avoid is that in my case None block, I would like to avoid looking into each of the Option and populate the corresponding error message. Any ideas on how I could make it more functional?

How mock requests exception using Pytest fixture for mock_requests?

So I was using the requests-mock library to mock the HTTP requests that I do with the requests library and everything went fine until I had to do a test to catch the exception.
Example of my function to be tested
def get_wordpress_installed_plugins(url: str, user: str, password: str) -> bytes:
try:
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}
response = requests.get(url, headers=header, verify=False)
response.raise_for_status()
except requests.exceptions.HTTPError as err:
logger.exception(f"Got response from {url} correctly with error {err}.")
raise CouldNotConnectWithApi(f"Problem retrieving information.")
logger.info(f"Got response from {url} correctly.")
return response.content
And the test to assert function did ok
#mock.patch("checkpluginsversion.logging.Logger.info")
def test_api_wordpress_list_plugins(logger_mock, requests_mock):
user = "user"
password = "password"
url = "https://www.example.com"
expected_result = b'[{"plugin": "akismet\\/akismet", "status": "active", "name": "Akismet Anti-Spam","version": "4.2.2"}]'
requests_mock.get(url,
content=b'[{"plugin": "akismet\\/akismet", "status": "active", "name": "Akismet Anti-Spam","version": "4.2.2"}]')
result = get_wordpress_installed_plugins(url, user, password)
assert result == expected_result
logger_mock.assert_called_with(f"Got response from {url} correctly.")
To be honest, I don't know if using pytest fixture mode of this library is the best way, but ok it is working for me. So the problem I have is when I have to test the function and raise the exception. Eventually, I did a workaround with #mock.patch, and worked for me.
#mock.patch("checkpluginsversion.requests.get")
#mock.patch("checkpluginsversion.logging.Logger.exception")
def test_api_should_return_an_exception(logger_mock,my_request_mock):
user = "user"
password = "password"
url = "https://www.example.com"
expected_result = b'[{"plugin": "akismet\\/akismet", "status": "active", "name": "Akismet Anti-Spam","version": "4.2.2"}]'
my_request_mock.side_effect = requests.exceptions.HTTPError
with pytest.raises(CouldNotConnectWithApi):
result = get_wordpress_installed_plugins(url, user, password)
#assert result == expected_result
logger_mock.assert_called_with(f"Got response from {url} correctly with error .")
But I would know and I will really appreciate it if someone could explain to me how to do a test to raise an exception using the pytest fixture of requests_mock library, thanks!

FastAPI pytest with arguments

I try to test fastAPI get route with pytest and the problem is how i can pass params to client.get
main.py
#app.get('/purpose'):
async def read_purpose(name, date):
"""some logic"""
return {'ok':'ok'}
test.py
client = TestClient(app)
def test_purpose():
response = client.get("/purpose", json={"name":"test_name", "date":"01.01.2020"})
assert response.status_code = 200
My test is failed. it can not find name, and date arguments.
How i can pass this arguments to my test.
Thank you
I have same problem when writing pytest for my first FastAPI demo.
#router.post('/item', tags=['items'], response_model=ShowItem)
async def create_item(item: ItemCreate,
user_id: int,
db: Session = Depends(get_db)):
date_posted = datetime.now().date()
# owner_id = 1
item = Items(**item.dict(),
date_posted=date_posted,
owner_id=user_id)
db.add(item)
db.commit()
db.refresh(item)
return item
You can try "params" instead of "json", because you are passing isolated query parameters
def test_create_item():
# wrong
data = {'title': 'Hot Boat', 'description': 'This is a boat', 'user_id': 1}
resp = client.post('/item', json.dumps(data))
# correct
data = {'title': 'Hot Boat', 'description': 'This is a boat'}
resp = client.post('/item', json.dumps(data), params={"user_id": 2})
assert resp.status_code == 200
Then i can by pass above error.
Try this fix:
client = TestClient(app)
def test_purpose():
response = client.get("/purpose", params={"name":"test_name", "date":"01.01.2020"})
assert response.status_code = 200
More detail refer Question 61383179

CL_HTPP_CLIENT CODE 400 BAD REQUEST - ABAP

i am trying to Post a Json to a Web Service.
The connection is good , but Unfortunately the payload arrives empty to the other side.
The Variable Jsondata is not empty and is a string.
I dont know what is missing. I have another Service to another api with a small json and works well.
Call Method cl_http_client=>create_by_url
Exporting
url = url
Importing
client = client
Exceptions
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
Others = 4.
If Sy-Subrc Ne 0.
Raise Error_conexion_token.
Else.
.
Data(Bearer) = 'Bearer' && | | && token.
client->request->set_header_field(
Exporting
name = 'Authorization'
value = Bearer ).
client->request->set_header_field(
Exporting
Name = 'Content-Type'
Value = 'application/json; charset=utf-8' ).
Call method client->request->set_cdata(
Exporting data = jsondata ).
client->request->set_method( if_http_request=>co_request_method_post).
Call Method client->send.
If sy-subrc Ne 0.
Raise Error_conexion_token.
Else.
Call Method client->receive
Exceptions
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
Others = 4.
If sy-subrc Ne 0.
Data(rc) = sy-subrc.
client->get_last_error(
Importing
code = zhcm_fdexperience=>codigo
message = zhcm_fdexperience=>mensaje ).
Case rc.
When 1.
Raise http_communication_failure.
When 2.
Raise http_invalid_state.
When 3.
Raise http_processing_failed.
Endcase.
Else.
client->get_last_error(
Importing
code = zhcm_fdexperience=>codigo
message = zhcm_fdexperience=>mensaje ).
Call method client->response->get_status( Importing code = zhcm_fdexperience=>codigo
reason = zhcm_fdexperience=>mensaje ).
If zhcm_fdexperience=>codigo Ne '200' Or zhcm_fdexperience=>codigo Ne '000' Or zhcm_fdexperience=>codigo Ne '0'.
Clear zhcm_fdexperience=>codigo.
Clear zhcm_fdexperience=>mensaje.
Data(Respuesta) = client->response->get_cdata( ).
Else.
Respuesta = client->response->get_cdata( ).
Endif.
Call method client->close.
An this is the json.
{
"data": [
{
"apiTipo": 1,
"fechaHoraAccion": "07/09/2021 21:20:03",
"nombreUsuarioSAP": "JUAN",
"numeroPersonal": "00001127",
"numeroPersonalREF": "sin información",
"tratamiento": "Señor",
"apellidoPaterno": "letelier",
"apellidoMaterno": "diaz",
"nombre": "rodrigo",
"sexo": "masculino",
"fechaNacimiento": "29/05/1985",
"estadoCivil": "Casado",
"nacionalidad": "Argentina",
"documentoIdentidad": "15902492-2",
"sociedad": "SBIO",
"divisionPersona": "CL01",
"centroCosto": "sin información",
"subdivisionPersona": "sin información",
"calleNumero": "ladies nIght 3221",
"ciudad": "san fernando",
"region": "Libertador Bernardo",
"pais": "Chile",
"telefono": "717846",
"claseContrato": "INDEFINIDO",
"plazoPreavEmpresa": "22.5 HORAS SEMANALES",
"reglaPlanJornadaColaborador": "BHADP201",
"statGestionTiempo": "9 - Evaluacion",
"indAdicTiempo": "NC",
"claseConvenio": "Sin Negociacion",
"areaConvenio": "No Sindicalizado",
"grupoProfesional": "General",
"subgrupoProfesional": "01",
"claseCorreoPersonal": "adiazs#funk.com",
"idSistema": "0016",
"fechaInicio": "22/08/2021",
"fechaFin": "31/12/9999"
}
]
}
Note : I tested in postman and works well.

Misunderstood, an example from the documentation Pytest authorization

I decided to look at Pytest and immediately misunderstood, an example from the documentation, but there is no authorization, the test crashes with a code of 301, can anyone know what is the reason?
def test_with_authenticated_client(client, django_user_model):
username = "TestUser"
password = "1234567"
user = django_user_model.objects.create_user(username=username,
password=password)
# Use this:
client.force_login(user)
response = client.get('/new')
assert response.status_code == 200
def test_with_authenticated_client2(client):
username = "user2"
password = "bar"
# Or this:
client.login(username=username, password=password)
response = client.get('/new')
assert response.status_code == 200
with an unauthorized client, expected code 301
def test_make_not_authorized_user(client):
response = client.get('/new')
assert response.status_code in (302, 301)