django test for upload image - django

i want to test user registration but i can't test image here is my test:
test.py
response = self.client.post('/api/v1/signup/',
content_type='application/json',
data=json.dumps({"username": "casino", "email": "casinoluxwin#gmail.com",
"password1": "android12", "password2": "android12", "photo": {
'real_filename': "u'banner3.jpg'",
'path': "u'C:/Users/Dima/Desktop'"}
}))
self.assertEqual(response.status_code, 200)
i get code 400(bad request), but without photo my test pass
service/users.py
#validate_input({
'username': {'min_length': 3, 'max_length': 50},
'email': {'validation_type': "email", 'max_length': 50},
'password1': {'min_length': 8, 'max_length': 50},
'password2': {'min_length': 8, 'equal_to': 'password1',
'messages': {'equal_to': _(u"Пароли не совпадают")}},
'photo': {'required': True}
})
#transaction.atomic
def signup(self, data):
user_data = {
'username': data['username'],
'email': data['email'],
'password': data['password1'],
'coins_amount': 0
}
user = self._create_user(user_data)
if data.get("photo"):
self._attach_photo(user, data["photo"])
obj, created = VerificationCode.objects.get_or_create(user=user, code_type="registration")
obj.create_expiration_date()
obj.create_code()
obj.save()
return user.id
So i want to test user photo anything else works fine. Thanks for any help

Problem probably resides in either Users._attach_photo() or your user model. Not enough information here to decipher it entirely. There are a couple of things to try.
I'd write a normal unittest that does not use the client. It'll give you a more helpful traceback than just the HTTP status code from the running server. Something like:
def test_user_add_method(self):
x = Users.signup(json.dumps({"username": "casino", "email": "casinoluxwin#gmail.com",
"password1": "android12", "password2": "android12", "photo": {
'real_filename': "u'banner3.jpg'",
'path': "u'C:/Users/Dima/Desktop'"})
Users.get(pk=x) #will fail if user was not created.
Second, try commenting out your validator. 400 bad request could easily be kicked off by that. It is possible that your validator isn't playing nice with the image and you'll have to mess around with that.

Related

Testing a PUT request in Django Rest Framework

When I run this test
def test_update_car(self):
new_car = Car.objects.create(make='Chevy', model='Equinox', year=2012, seats=4, color='green', VIN='12345671234567abc', current_mileage=19000, service_interval='3 months', next_service='april')
url = reverse('car-detail', kwargs={'pk': new_car.pk})
data = {
'make': 'test',
'model': 'test',
'year': 2014,
'seats': 5,
'color': 'blue',
'VIN': '12345671234567abc',
'current_mileage': 20000,
'service_interval': '6 months',
'next_service': 'July',
}
response = self.client.put(url, data=data)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(new_car.make, 'test')
I get an assertion error
AssertionError: 'Chevy' != 'test'
How should I structure this differently so that the PUT request actually changes the make and model of the new_car?
If your view indeed responds to a PUT request, the problem is located at the test itself. You need to refresh the data from the database with .refresh_from_db(…) [Django-doc]:
def test_update_car(self):
new_car = Car.objects.create(make='Chevy', model='Equinox', year=2012, seats=4, color='green', VIN='12345671234567abc', current_mileage=19000, service_interval='3 months', next_service='april')
url = reverse('car-detail', kwargs={'pk': new_car.pk})
data = {
'make': 'test',
'model': 'test',
'year': 2014,
'seats': 5,
'color': 'blue',
'VIN': '12345671234567abc',
'current_mileage': 20000,
'service_interval': '6 months',
'next_service': 'July',
}
response = self.client.put(url, data=data)
new_car.refresh_from_db()
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(new_car.make, 'test')

What's the structure of Telegram's updates to webhook Flask app?

I'm trying to program a Telegram bot using webhook in a Flask app with telepot, in PythonAnywhere. And so, I want to know what's the structure of the updates comming from Telegram, so as to know what's there and how is it called, and use it in the bot, essentially.
I've tried to log the message it receives to the console (though I'm not sure where the console should be on PythonAnywhere), and also to write in a file in the same server, through python, but that's not working either.
#This that seemed easy didn't work either in the Flask web app
with open('log.txt', 'a') as f:
f.write('Is this working?')
It feels like I'm missing some easy information everyone takes for granted, but I can't figure out what that is.
There was indeed something I didn't notice. Posting in case it helps anyone.
On the web app section of PythonAnywhere there are three Log Files links where you can see the kinds of things that would apear on the console in a regular Python app.
Those links look like this:
username.eu.pythonanywhere.com.access.log
username.eu.pythonanywhere.com.error.log
username.eu.pythonanywhere.com.server.log #no .eu on the american PythonAnywhere
And server.log is where console print statements end up.
Also, regular messages from Telegram users look like this when they arrive to Flask:
{
'update_id': 123456789,
'message': {
'message_id': 42,
'from': {
'id': 42424242,
'is_bot': False,
'first_name': 'Joaquim',
'last_name': 'Pernil Rinoceronts',
'username': 'Juqim',
'language_code': 'ca'
},
'chat': {
'id': 42424242,
'first_name': 'Joaquim',
'last_name': 'Pernil Rinoceronts',
'username': 'Juqim',
'type': 'private'
},
'date': 1562247903,
'text': 'Patata'
}
}
Stickers have their info where 'text' would be:
'sticker': {
'width': 512,
'height': 512,
'emoji': '😒',
'set_name': 'Ruscamems',
'thumb': {
'file_id': 'AAQEABNgnrsaAAQkkp4QRiVF1rokAAIC',
'file_size': 4840,
'width': 128,
'height': 128
},
'file_id': 'CAADBAADBQADkvulAumgmwOAjdfYAg',
'file_size': 36612
}
Images have 'photo' instead, and they come in a collection of different sizes:
'photo':[
{
'file_id': 'AgADBAADVrAxG2wj8FCs-f6v7AGFUQvo-RkABFGq4cIH4_MaHXIFAAEC',
'file_size': 2101,
'width': 66,
'height': 90
},
{
#same but bigger (different id too)
},
... #I got 4 sizes.
]
I guess I'll post the callback too and we'll have most of the interesting stuff:
{
'update_id': 123456793,
'callback_query': {
'id': '424242424242424242',
'from': { #Who pressed the Button
'id': 42424242,
'is_bot': False,
'first_name': 'Joaquim',
'last_name': 'Pernil Rinoceronts',
'username': 'Juqim',
'language_code': 'ca'
},
'message': { #What message was the button in
'message_id': 123,
'from': {
'id': 434343434,
'is_bot': True,
'first_name': 'The Bot Name',
'username': 'name_bot'
},
'chat': {
'id': 42424242,
'first_name': 'Joaquim',
'last_name': 'Pernil Rinoceronts',
'username': 'Juqim',
'type': 'private'
},
'date': 1562252792,
'text': 'A viam si funciona això',
'reply_markup': { #Keyboard pressed
'inline_keyboard': [[{'text': 'Cliccami', 'callback_data': 'clicat'}]]
}
},
'chat_instance': '1234123412341234242',
'data': 'clicat' #Callback data (button pressed)
}
}

How to POST data to a Django Form that contains checkboxes

I have a problem when I am testing my registration form in Django. I am trying to make a POST request but I cannot select a checkbox field.
self.response = self.client.post(url, {
'username': 'testuser',
'password': 'testuserpassword',
'first_name': 'testtt',
'last_name': 'userrr',
'image': '',
'email': 'testuser#gmail.com',
'gender': 'M',
'dob': '10/10/1996',
'hobby': 'Fishing'
})
This is my line of code. The problem is at Hobby. The registration page is made of two forms. A profile form and a hobby form. There is a many-to-many relationship between Profile and Hobby models.
When I make the above POST request, I get this (Select a valid choice):
Thank you in advance!
According to the screenshot you've posted, the value for each hobby checkbox corresponds to an integer - 1, 2, 3, 4, etc. That would imply that the backend is expecting the hobby ID to be transmitted in the form. However, the test is not sending the hobby ID, it's sending the name.
Change the name to the corresponding ID - e.g.
self.response = self.client.post(url, {
...
'hobby': 1 # Fishing
})

Django extract field form html

I have a html page that returns data in a form. The forms is a multiple choice checkbox field with "name=states1". When I run print(vars(self)) in my forms.py I see that the data is there ['MD', 'WV', 'WY'] (see below) however, when I try to extract it with print(self.data['states1']) I just get 'WY' and print(len(self.data['states1'])) returns 2.
{'instance': <AA: AAobject>, '_validate_unique': False, 'is_bound': True, 'data': <QueryDict: {'csrfmiddlewaretoken': ['AAAAA']: ['1'], 'states1': ['MD', 'WV', 'WY'], 'states': [''], 'price': ['2.00'], 'user': ['1', '1']}>, ...
However, when I run
import json
print(json.dumps(self.data, indent=2))
I get the following output
{
"csrfmiddlewaretoken": "AAAAA",
"roles": "1",
"states1": "WY",
"states": "",
"price": "2.00",
"user": "1"
}
The data is just gone. Why is my data being restricted to the last field, when I can clearly see it when looking at vars?
forms.py
class UserProfileChangeForm(forms.ModelForm):
states = forms.CharField(widget=USStateSelect(), initial='TX', required=False)
class Meta:
model = SkilledLaborer
fields = ['user','roles','travel_flag','price','states']
def clean_states(self):
print('states')
states = self.cleaned_data['states']
print(type(vars(self)))
print(vars(self).keys())
print(vars(self))
print(self.data.keys())
print(self.data['states1'])
print(len(self.data['states1']))
import json
print(json.dumps(self.data, indent=2))
try:
self.data['states1']
except:
pass
return states

django 2 custom jwt_get_username_from_payload_handler

To validate the jwt token of auth0 in django, I use the following code in settings.py
def jwt_get_username_from_payload_handler(payload):
return 'authuser'
JWT_AUTH = {
'JWT_PAYLOAD_GET_USERNAME_HANDLER': jwt_get_username_from_payload_handler,
'JWT_PUBLIC_KEY': PUBLIC_KEY,
'JWT_ALGORITHM': 'RS256',
'JWT_AUDIENCE': API_IDENTIFIER,
'JWT_ISSUER': JWT_ISSUER,
'JWT_AUTH_HEADER_PREFIX': 'Bearer',
}
where authuser is the username. So Instead of writing it directly I want to receive it in request header and pass it. Please help me in customising this function - jwt_get_username_from_payload_handler in such a way. TIA
def jwt_get_username_from_payload_handler(user):
return {
'username': user.username,
'email': user.email,
'is_superuser': user.is_superuser,
}
you can use this function