Unit Testing in Python Djnago - django

I am using
Django==3.0.3
djangorestframework==3.11.0
python ==3.6.8
I want to write unit testing for API and no need to use any database(no need of mock database)
that mean I want to mock the database call and write unit test cases
how can i write which property is used for this
Showing my api
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def employee_entry(request):
try:
login = User.objects.get(pk=request.user.id)
validationmsg = ''
emp_data = request.data
if not emp_data:
validationmsg = validation["FDP15"]
elif emp_data["EmployeeName"] is None or emp_data["EmployeeName"] == '':
validationmsg = validation["FDP1"]
elif emp_data["EmployeeCode"] is None or emp_data["EmployeeCode"] == '':
validationmsg = validation["FDP2"]
elif Employee.objects.filter(EmployeeCode=emp_data["EmployeeCode"]).count() > 0:
validationmsg = validation["FDP3"]
if validationmsg != '':
return Response({msg: validationmsg}, status=status.HTTP_400_BAD_REQUEST)
employee = Employee(
EmployeeName=emp_data["EmployeeName"],
EmployeeCode=emp_data["EmployeeCode"],
Security=emp_data["Security"],
CreatedDate=date.today(),
CreatedUser=login,
)
employee.save()
if emp_data["Security"] == 1:
device = Device.objects.filter(~Q(DeviceStatus=static_values["const0"]))
employee.Device.set(device)
elif emp_data["Security"] == 0:
device = Device.objects.filter(~Q(DeviceStatus=static_values["const0"]), DefaultAccess=True)
employee.Device.set(device)
return Response({"EmployeeId": employee.EmployeeId}, status=status.HTTP_200_OK)
except(KeyError, TypeError, ValueError) as ex:
logging.getLogger("error_logger").exception(repr(ex))
return Response({msg: validation["FDP21"]}, status=status.HTTP_400_BAD_REQUEST)
except Exception as ex:
logging.getLogger("error_logger").exception(repr(ex))
return Response({msg: validation["FDP23"]}, status=status.HTTP_400_BAD_REQUEST)

Related

Django - when 1 user accesses the same view with different url kwargs - why am I getting cross over of data?

I have a django app that contains samples. On my home page, it displays a table with many samples, containing hyperlinks to the 'Sample page' - which is a view get request.
When I click on several of these samples in tandem, to open new tabs, each to a specific tab - I am getting cross over of data - I.e the url sample_id kwargs is different, but the page is displaying the same results which is incorrect. When i refresh the page, the correct sample data appears.
Is there any way around this happening is a user is to open several different sample tabs at the same time? This would impact on results and could cause errors in the workflow offered by the django app.
*is this because my view is processing too much, so the different view request=s ends up over lapping ?
Edit: adding view:
class FilterVariantSampleView(ReportView, ReportPDFGenerator, FileGenerator, limsQuery):
template_name = os.path.join(
'results',
'filter_templates',
'sample_page.html'
)
type = 'sample'
choice = False
group_required = ['filter']
def get(self, request, *args, **kwargs):
self.user = request.user
self.obtain_sample_information(kwargs)
self.obtain_patient_information()
self.obtain_header()
# create sample notes form
sample_notes_form = SampleNotesForm(
instance=self.sample_obj)
self.context['sample_notes_form'] = sample_notes_form
self.create_variant_filter_formset()
panel_list = [o.run_id.machine_panel_id.panel_id
for o in self.all_sr_obj]
if len(panel_list):
self.panel_obj = panel_list[0]
# self.generate_hotspot_form()
self.assess_fails()
crs_qs = ClinicallyReportedSample.objects.filter(
sample_id=self.sample_obj)
crs_qs = crs_qs.exclude(
reported_on_panel__parent_panel__isnull=False,
primary_technical_report=False,
final_technical_report=False
)
remove_report_form_list = []
lims_molecular_results = self.query_lims_clone_molecular(
qs=crs_qs)
mol_df = lims_molecular_results[0]
summary = lims_molecular_results[1]
self.context['summary'] = summary
if crs_qs.count() == 1:
crs_obj = crs_qs[0]
self.context['crs_qs'] = crs_qs
remove_report_form = RemoveDiagnosticReportForm(
instance=crs_obj)
remove_report_form_list.append(remove_report_form)
else:
messages.add_message(self.request, messages.WARNING,
'This sample has been sequenced on multiple panels.')
self.context['crs_qs'] = crs_qs
lims_molecular_results = self.query_molecular_lims(
sample_obj=self.sample_obj)
for crs_obj in crs_qs:
remove_report_form = RemoveDiagnosticReportForm(
instance=crs_obj)
remove_report_form_list.append(remove_report_form)
if crs_obj.diagnostic_report_required == False:
messages.add_message(self.request, messages.WARNING,
f'This sample does NOT require a diagnostic reoprt '
f'for the {crs_obj.reported_on_panel} panel.')
self.context['remove_report_form_list'] = remove_report_form_list
return render(request, self.template_name, self.context)
def post(self, request, *args, **kwargs):
"""
"""
self.define_variant_filter_formset()
submit = request.POST.get('submit', None)
if submit:
if submit == 'Modify sample':
logger.info('')
logger.info('Sample: {}'.format(self.sample_obj))
logger.info("Submit: '{}'".format(submit))
# pass POST dict to formset
modify_formset = self.CRVFormSet(request.POST, prefix='crv')
# validate
if modify_formset.is_valid():
logger.info('Modify Variant Formset valid')
logger.info('')
self.modify_variants(modify_formset)
self.modify_sample()
return HttpResponseRedirect(
reverse('results:filter_variant_sample',
kwargs={'sample_id': self.sample_obj.id}))
else:
msg = ('Modify ClinicallyReportedVariant '
f'Formset NOT valid: {modify_formset.errors}')
logger.error(msg)
messages.add_message(request, messages.ERROR, msg)
return HttpResponseRedirect(
reverse('results:filter_variant_sample',
kwargs={'sample_id': self.sample_obj.id}))
elif submit == 'Update':
form = RemoveDiagnosticReportForm(request.POST,
instance=ClinicallyReportedSample.objects.get(
sample_id=kwargs['sample_id'],
reported_on_panel=request.POST['reported_on_panel'])
)
if form.is_valid():
logger.info('RemoveDiagnosticReportForm is valid')
try:
form.save()
except Exception as e:
logger.error(e)
else:
msg = f'RemoveDiagnosticReportForm is NOT valid: {form.errors}'
logger.error(msg)
messages.add_message(self.request, messages.ERROR, msg)
return HttpResponseRedirect(request.path_info)
elif 'Download' in submit:
panel_name = submit.split(' ')[1]
self.panel_obj = Panel.objects.get(panel_name=panel_name)
self.crs_obj = ClinicallyReportedSample.objects.get(
sample_id=self.sample_obj, reported_on_panel=self.panel_obj)
if 'panel data' in submit:
logger.info(f'Downloading data for {self.sample_obj}')
if self.crs_obj.sample_id.external_dept.site in ['Newcastle', 'Sheffield']:
downloaded_data = self.download_yne_data()
if downloaded_data:
self.crs_obj.downloaded_data = True
self.crs_obj.downloaded_data_user = request.user
self.crs_obj.downloaded_data_date = timezone.now()
self.crs_obj.save()
return downloaded_data
else:
return HttpResponseRedirect(self.request.path_info)
elif 'report' in submit:
logger.info(f'Downloading report for {self.sample_obj}')
# update crs_obj
self.crs_obj.download_technical_report = True
self.crs_obj.download_technical_report_user = self.user
self.crs_obj.download_technical_report_date = timezone.now()
self.crs_obj.save()
# return HttpResponseRedirect(self.request.path_info)
lims_molecular_results = self.query_molecular_lims(
sample_obj=self.sample_obj)
mol_df = lims_molecular_results[0]
summary = lims_molecular_results[1]
if mol_df.empty:
logger.info('No molecular tests done')
self.latex_context['gene_status'] = False
else:
gene = mol_df[
(mol_df['test_name'] == 'gene') &
(mol_df['status'] == 'complete')
]
if gene.empty:
self.context['gene'] = False
else:
msg = ("gene Sanger in-fill test has been completed.{}")
result = gene['result'].to_string(index=False)
if result == 'normal or wild-type':
msg = msg.format(' No detectable variants.')
msg_info = messages.INFO
gene_df = pd.DataFrame()
elif result == 'failed':
msg = msg.format(' Unfortunately the test failed.')
msg_info = messages.WARNING
gene_df = pd.DataFrame()
elif result == 'mutated' or result == 'suspicious':
gene_df = self.get_gene_result(gene, technical_report=True)
if result == 'suspicious':
msg = msg.format(' There is suspicion of a variant '
'(see below for more information).')
else:
msg = msg.format(' A variant was detected '
'(see below for more information).')
msg_info = messages.INFO
else:
msg = msg.format(' Error - contact administrator.')
msg_info = messages.ERROR
result = 'error'
gene_df = pd.DataFrame()
self.latex_context['gene_status'] = result
self.latex_context['gene_df'] = gene_df
logger.info(msg)
messages.add_message(self.request, msg_info, msg)
print(self.latex_context)
# call method from TechnicalReportPDFGenerator
self.generateReport(report_type='technical')
response = self.download_technical_report()
return response
return render(request, self.template_name, self.context)
This may be due to the cache of your browser, are you sure the calls are going through the first time ?

TypeError: 'str' object is not callable python3

def SaveRoles(request):
if 'user_name' in request.session:
if request.method == "POST":
user_roles = request.POST['user_roles']
user_permission_level = request.POST['user_permission_level']
user_role_code = request.POST['user_role_code']
code = user_roles(user_roles=user_roles, user_permission_level=user_permission_level, user_role_code=user_role_code)
print("qqqqqq", code)
try:
model_status = code.save()
except Exception as e:
print("exception occured", e)
return render(request, 'administrator/add_role.html', {'message': 'Oops some error occured'})
if model_status == None:
role = user_roles.objects.all()
return HttpResponseRedirect('http://'+request.get_host()+'/admin/role-list/',{'message': 'Role added successfully','code': code})
else:
return HttpResponseRedirect('http://'+request.get_host()+'/admin/role-list/')
else:
return HttpResponseRedirect('/admin/')
When I am running this function I got the
TypeError: 'str' object is not callable
I searched all my code and I don't even use the word str anywhere in my project
But I cant figure out the error
user_roles is a string because you are assigning the value of request.POST['user_roles']. You probably need to change.
user_roles = request.POST['user_roles']
to
user_roles_val = request.POST['user_roles']
Ex:
def SaveRoles(request):
if 'user_name' in request.session:
if request.method == "POST":
user_roles_val = request.POST['user_roles'] #Update
user_permission_level = request.POST['user_permission_level']
user_role_code = request.POST['user_role_code']
code = user_roles(user_roles=user_roles_val, user_permission_level=user_permission_level, user_role_code=user_role_code) #Update
print("qqqqqq", code)
try:
model_status = code.save()
except Exception as e:
print("exception occured", e)
return render(request, 'administrator/add_role.html', {'message': 'Oops some error occured'})
if model_status == None:
role = user_roles.objects.all()
return HttpResponseRedirect('http://'+request.get_host()+'/admin/role-list/',{'message': 'Role added successfully','code': code})
else:
return HttpResponseRedirect('http://'+request.get_host()+'/admin/role-list/')
else:
return HttpResponseRedirect('/admin/')

elif condition in django view

I'm having view function which filters object according to the data I give and if that filtered object does not exist in the database it adds the object to DB(i didn't write add function yet). Shows error if it exists already. I'm getting data from a template using ajax post request.
#view.py
#csrf_exempt
def setUserInDB(request):
if request.method=="POST":
if request.POST.get('pname','u_id'):
pname = request.POST.get('pname')
u_id = request.POST.get('u_id')
user = userprofile.objects.get(pk=u_id)
pid = Project.objects.get(title=pname)
else:
u_id = None
pname = None
if request.POST.get('db_id','chkbox'):
db_id = request.POST.get('db_id')
db = Db_profile.objects.get(pk=db_id)
chkbox = request.POST.get('chkbox')
print chkbox
else:
db_id = None
chkbox = None
if Projectwiseusersetup.objects.filter(userid=user,project_id=pid,
db_profileid= db,setasdefaultproject=chkbox):
print "already exist"
elif (((Projectwiseusersetup.objects.filter(userid = user,project_id =
pid,db_profileid=db,setasdefaultproject=False)).exists()) and
(chkbox==True)):
print "FtoT"
elif Projectwiseusersetup.objects.filter(userid = user,project_id =
pid,db_profileid=db,setasdefaultproject=True) and chkbox==False:
print "TtoF"
else:
print "aaaa"
user,pid,db,chkbox }---- i'm getting these data from ajax post request,
userid, project_id, db_profileid, setasdefaultproject(boolean) }----- model fields
when I try to check my elif condition, i'm getting output in console "aaaa"(else part). what is wrong with elif?
Here the ex:
x = 4
if x == 1:
print ("1")
elif (x == 2):
print("2")
elif (x == 3):
print("3")
else:
print("4")

Save request.POST to database

in view.py:
#require_POST
#csrf_exempt
def ipn(request):
transactions_logger = logging.getLogger("django")
processor = Ipn(request.POST, logger=transactions_logger)
verification_success = processor.verify_ipn()
encoding = request.POST.get('ok_charset', None)
data = QueryDict(request.body, encoding=encoding)
if verification_success:
form = OkpayIpnForm(data)
if form.is_valid():
print("ALL FINE!!")
form.save()
return HttpResponse("")
In forms.py:
class OkpayIpnForm(forms.ModelForm):
class Meta:
model = OkpayIpn
exclude = []
Code for IPN Checkprocessor = Ipn(request.POST, logger=transactions_logger:
class Ipn(object):
OKPAY_VERIFICATION_URL = 'https://checkout.okpay.com/ipn-verify'
OKPAY_IPN_INVALID = b'INVALID'
OKPAY_IPN_VERIFIED = b'VERIFIED'
OKPAY_IPN_TEST = b'TEST'
OKPAY_STATUS_COMPLETED = 'completed'
__verification_result = False
def __init__(self, request_data, logger):
if 'ok_verify' in request_data:
raise Exception("ok_verify must not be present in initial request data for {}".format(
self.__class__.__name__
))
self._request_data = request_data
self.logger = logger
return
def verify_ipn(self):
self.__verification_result = False
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
verify_request_payload = {
'ok_verify': 'true',
}
verify_request_payload.update(self._request_data)
resp = requests.post(self.OKPAY_VERIFICATION_URL, data=verify_request_payload, headers=headers)
if resp.content == self.OKPAY_IPN_VERIFIED or resp.content == self.OKPAY_IPN_TEST:
self.__verification_result = True
# if resp.content == self.OKPAY_IPN_VERIFIED: # anyway disable test on production.
# self.__verification_result = True
return self.__verification_result
All is ok, I revice IPN and validate it, then I try to validate form and save it to Database.
But form doesn't pass validation and doesn't save to database.
Thank You for help
Problem was that 1 CharField of Model for saving IPN has maxlength=20, but recieved 40 symbols.
Thx jape he advised to add in form validation else statement and print form.errors
the error of of form validation was :
<li>ok_item_1_type<ul class="errorlist"><li>Ensure this value has at most 20 characters (it has 40).</li></ul></li>

Django form edit problem at intiliazation

I have a trouble with pre-population of the forms in Django. Because debuggin tool in Aptana doesn't work well, I couldn't detect the error.
I think when I try form = MemberSettings(default_data) form tries to validate the data and it gives errors for invalid fields even in first load.
Could you help me to find out the problem ?
Thanks
forms.py
class MemberSettings(forms.Form):
email = forms.EmailField(label=_("member_Email"),required = True)
currentPassword = forms.CharField(label=_("member_currentPassword"),widget=forms.PasswordInput,required=False)
newPassword = forms.CharField(label=_("member_newPassword"),widget=forms.PasswordInput,required=False)
newPasswordRe = forms.CharField(label=_("member_newPasswordRe"),widget=forms.PasswordInput,required=False)
emailPreference = forms.ChoiceField(label=_("member_email_preference"), widget=forms.RadioSelect(renderer=HorizRadioRenderer),choices = UserMailPreference.USER_MAIL_PREF,required = True)
gender = forms.ChoiceField(label=_("member_gender"), widget=forms.RadioSelect(renderer=HorizRadioRenderer),choices = UserGender.USER_GENDER ,required = False)
birthYear = forms.ChoiceField(label=_("member_birthyear"),required = False)
education = forms.ChoiceField(label=_("member_education"),choices = UserEducation.USER_EDU, required = False)
def __init__(self,*args, **kwargs):
super(MemberSettings,self).__init__(*args, **kwargs)
now = datetime.datetime.now()
birthYearList = []
for i in reversed(range (now.year-80,now.year-13)):
birthYearList.append((i,str(i)))
self.fields["birthYear"].choices = birthYearList
def clean_currentPassword(self):
field_data = self.cleaned_data['currentPassword']
if len(field_data) <= 0:
return field_data
if len(field_data.split(' ')) != 1:
raise forms.ValidationError(_('member_err_password_empty_char'))
if len(field_data) > 32:
raise forms.ValidationError(_('member_err_password_maxChar'))
if len(field_data) < 5:
raise forms.ValidationError(_('member_err_password_minChar'))
return field_data
def clean_newPassword(self):
field_data = self.cleaned_data['newPassword']
if len(field_data) <= 0:
return field_data
if len(field_data.split(' ')) != 1:
raise forms.ValidationError(_('member_err_password_empty_char'))
if len(field_data) > 32:
raise forms.ValidationError(_('member_err_password_maxChar'))
if len(field_data) < 5:
raise forms.ValidationError(_('member_err_password_minChar'))
return field_data
views.py
#login_required
def settings_edit(request):
u = request.user
if request.method == 'POST':
form = MemberSettings(request.POST)
if form.is_valid():
return redirect('/member/settings_edit/')
else:
return render_response(request, 'member/settings_edit.html', {'form': form})
else:
default_data = {
'email': u.email,
'gender': u.get_profile().gender,
'education': u.get_profile().education,
'birthYear': u.get_profile().birthyear,
'emailPreference': u.get_profile().mail_preference,
}
form = MemberSettings(default_data)
return render_response(request, 'user/settings_edit.html', {'form': form})
You need to use the initial argument when constructing your form instance in the view:
form = MemberSettings(initial=default_data)
See https://docs.djangoproject.com/en/1.3/ref/forms/api/ for more information. Hope that helps you out.